Bug 944442 - DeCOMify imgIContainer::GetFrame. r=seth
authorJonathan Watt <jwatt@jwatt.org>
Fri, 13 Dec 2013 08:34:24 +0000
changeset 160387 826415ddd250964cbef76e9ea5a554c89cb9744d
parent 160386 54c6e55f60af2d86295b6a893c21db72b8f0bf22
child 160388 bd5c5a325b15c186c16a1ed049e16f39747e2673
push id25831
push userryanvm@gmail.com
push dateFri, 13 Dec 2013 21:16:01 +0000
treeherdermozilla-central@9d593727eb94 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth
bugs944442
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 944442 - DeCOMify imgIContainer::GetFrame. r=seth
browser/components/shell/src/nsWindowsShellService.cpp
content/svg/content/src/SVGFEImageElement.cpp
image/public/imgIContainer.idl
image/src/ClippedImage.cpp
image/src/ClippedImage.h
image/src/FrozenImage.cpp
image/src/FrozenImage.h
image/src/ImageWrapper.cpp
image/src/OrientedImage.cpp
image/src/OrientedImage.h
image/src/RasterImage.cpp
image/src/VectorImage.cpp
image/src/imgTools.cpp
layout/base/nsLayoutUtils.cpp
widget/cocoa/nsClipboard.mm
widget/cocoa/nsCocoaUtils.mm
widget/cocoa/nsMenuItemIconX.mm
widget/gtk/nsImageToPixbuf.cpp
widget/os2/nsWindow.cpp
widget/qt/nsClipboard.cpp
widget/windows/WinUtils.cpp
widget/windows/nsImageClipboard.cpp
widget/windows/nsWindowGfx.cpp
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -747,20 +747,19 @@ nsWindowsShellService::SetShouldCheckDef
   return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
 }
 
 static nsresult
 WriteBitmap(nsIFile* aFile, imgIContainer* aImage)
 {
   nsresult rv;
 
-  nsRefPtr<gfxASurface> surface;
-  aImage->GetFrame(imgIContainer::FRAME_FIRST,
-                   imgIContainer::FLAG_SYNC_DECODE,
-                   getter_AddRefs(surface));
+  nsRefPtr<gfxASurface> surface =
+    aImage->GetFrame(imgIContainer::FRAME_FIRST,
+                     imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
   nsRefPtr<gfxImageSurface> image(surface->GetAsReadableARGB32ImageSurface());
   NS_ENSURE_TRUE(image, NS_ERROR_FAILURE);
 
   int32_t width = image->Width();
   int32_t height = image->Height();
 
--- a/content/svg/content/src/SVGFEImageElement.cpp
+++ b/content/svg/content/src/SVGFEImageElement.cpp
@@ -206,19 +206,19 @@ SVGFEImageElement::GetPrimitiveDescripti
 
   nsCOMPtr<imgIContainer> imageContainer;
   if (currentRequest) {
     currentRequest->GetImage(getter_AddRefs(imageContainer));
   }
 
   nsRefPtr<gfxASurface> currentFrame;
   if (imageContainer) {
-    imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
-                             imgIContainer::FLAG_SYNC_DECODE,
-                             getter_AddRefs(currentFrame));
+    currentFrame =
+      imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
+                               imgIContainer::FLAG_SYNC_DECODE);
   }
 
   if (!currentFrame) {
     return FilterPrimitiveDescription(FilterPrimitiveDescription::eNone);
   }
 
   gfxPlatform* platform = gfxPlatform::GetPlatform();
   DrawTarget* dt = platform->ScreenReferenceDrawTarget();
--- a/image/public/imgIContainer.idl
+++ b/image/public/imgIContainer.idl
@@ -50,26 +50,27 @@ native gfxGraphicsFilter(GraphicsFilter)
 [ref] native nsIntSize(nsIntSize);
 native nsSize(nsSize);
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native ImageContainer(mozilla::layers::ImageContainer);
 [ptr] native LayerManager(mozilla::layers::LayerManager);
 native Orientation(mozilla::image::Orientation);
 [ref] native TimeStamp(mozilla::TimeStamp);
 [ptr] native SVGImageContext(mozilla::SVGImageContext);
+native already_AddRefed_gfxASurface(already_AddRefed<gfxASurface>);
 
 
 /**
  * imgIContainer is the interface that represents an image. It allows
  * access to frames as Thebes surfaces. It also allows drawing of images
  * onto Thebes contexts.
  *
  * Internally, imgIContainer also manages animation of images.
  */
-[scriptable, builtinclass, uuid(73340b79-e3ae-4f02-97d0-822db78017e5)]
+[scriptable, builtinclass, uuid(8b7db7dd-bfe9-40d3-9114-3a79c0658afd)]
 interface imgIContainer : nsISupports
 {
   /**
    * The width of the container rectangle.  In the case of any error,
    * zero is returned, and an exception will be thrown.
    */
   readonly attribute int32_t width;
 
@@ -167,17 +168,18 @@ interface imgIContainer : nsISupports
    * Get a surface for the given frame. This may be a platform-native,
    * optimized surface, so you cannot inspect its pixel data. If you
    * need that, use gfxASurface::GetAsReadableARGB32ImageSurface or
    * gfxASurface::CopyToARGB32ImageSurface.
    *
    * @param aWhichFrame Frame specifier of the FRAME_* variety.
    * @param aFlags Flags of the FLAG_* variety
    */
-  [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
+  [noscript, notxpcom] already_AddRefed_gfxASurface
+                         getFrame(in uint32_t aWhichFrame,
                                   in uint32_t aFlags);
 
   /**
    * Whether the given frame is opaque; that is, needs the background painted
    * behind it.
    *
    * @param aWhichFrame Frame specifier of the FRAME_* variety.
    */
--- a/image/src/ClippedImage.cpp
+++ b/image/src/ClippedImage.cpp
@@ -204,33 +204,31 @@ ClippedImage::GetIntrinsicRatio(nsSize* 
   if (!ShouldClip()) {
     return InnerImage()->GetIntrinsicRatio(aRatio);
   }
 
   *aRatio = nsSize(mClip.width, mClip.height);
   return NS_OK;
 }
 
-NS_IMETHODIMP
+NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
 ClippedImage::GetFrame(uint32_t aWhichFrame,
-                       uint32_t aFlags,
-                       gfxASurface** _retval)
+                       uint32_t aFlags)
 {
-  return GetFrameInternal(mClip.Size(), nullptr, aWhichFrame, aFlags, _retval);
+  return GetFrameInternal(mClip.Size(), nullptr, aWhichFrame, aFlags);
 }
 
-nsresult
+already_AddRefed<gfxASurface>
 ClippedImage::GetFrameInternal(const nsIntSize& aViewportSize,
                                const SVGImageContext* aSVGContext,
                                uint32_t aWhichFrame,
-                               uint32_t aFlags,
-                               gfxASurface** _retval)
+                               uint32_t aFlags)
 {
   if (!ShouldClip()) {
-    return InnerImage()->GetFrame(aWhichFrame, aFlags, _retval);
+    return InnerImage()->GetFrame(aWhichFrame, aFlags);
   }
 
   float frameToDraw = InnerImage()->GetFrameIndex(aWhichFrame);
   if (!mCachedSurface || !mCachedSurface->Matches(aViewportSize,
                                                   aSVGContext,
                                                   frameToDraw,
                                                   aFlags)) {
     // Create a surface to draw into.
@@ -268,19 +266,17 @@ ClippedImage::GetFrameInternal(const nsI
     mCachedSurface = new ClippedImageCachedSurface(target,
                                                    aViewportSize,
                                                    aSVGContext,
                                                    frameToDraw,
                                                    aFlags);
   }
 
   MOZ_ASSERT(mCachedSurface, "Should have a cached surface now");
-  nsRefPtr<gfxASurface> surf = mCachedSurface->Surface();
-  surf.forget(_retval);
-  return NS_OK;
+  return mCachedSurface->Surface();
 }
 
 NS_IMETHODIMP
 ClippedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
 {
   // XXX(seth): We currently don't have a way of clipping the result of
   // GetImageContainer. We work around this by always returning null, but if it
   // ever turns out that ClippedImage is widely used on codepaths that can
@@ -330,18 +326,18 @@ ClippedImage::Draw(gfxContext* aContext,
   }
 
   // Check for tiling. If we need to tile then we need to create a
   // gfxCallbackDrawable to handle drawing for us.
   gfxRect sourceRect = aUserSpaceToImageSpace.Transform(aFill);
   if (MustCreateSurface(aContext, aUserSpaceToImageSpace, sourceRect, aSubimage, aFlags)) {
     // Create a temporary surface containing a single tile of this image.
     // GetFrame will call DrawSingleTile internally.
-    nsRefPtr<gfxASurface> surface;
-    GetFrameInternal(aViewportSize, aSVGContext, aWhichFrame, aFlags, getter_AddRefs(surface));
+    nsRefPtr<gfxASurface> surface =
+      GetFrameInternal(aViewportSize, aSVGContext, aWhichFrame, aFlags);
     NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
     // Create a drawable from that surface.
     nsRefPtr<gfxSurfaceDrawable> drawable =
       new gfxSurfaceDrawable(surface, gfxIntSize(mClip.width, mClip.height));
 
     // Draw.
     gfxRect imageRect(0, 0, mClip.width, mClip.height);
--- a/image/src/ClippedImage.h
+++ b/image/src/ClippedImage.h
@@ -30,19 +30,18 @@ public:
   virtual ~ClippedImage();
 
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
-  NS_IMETHOD GetFrame(uint32_t aWhichFrame,
-                      uint32_t aFlags,
-                      gfxASurface** _retval) MOZ_OVERRIDE;
+  NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
+                                                      uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager,
                                mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   GraphicsFilter aFilter,
                   const gfxMatrix& aUserSpaceToImageSpace,
                   const gfxRect& aFill,
                   const nsIntRect& aSubimage,
                   const nsIntSize& aViewportSize,
@@ -51,21 +50,20 @@ public:
                   uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD RequestDiscard() MOZ_OVERRIDE;
   NS_IMETHOD_(Orientation) GetOrientation() MOZ_OVERRIDE;
 
 protected:
   ClippedImage(Image* aImage, nsIntRect aClip);
 
 private:
-  nsresult GetFrameInternal(const nsIntSize& aViewportSize,
-                            const SVGImageContext* aSVGContext,
-                            uint32_t aWhichFrame,
-                            uint32_t aFlags,
-                            gfxASurface** _retval);
+  already_AddRefed<gfxASurface> GetFrameInternal(const nsIntSize& aViewportSize,
+                                                 const SVGImageContext* aSVGContext,
+                                                 uint32_t aWhichFrame,
+                                                 uint32_t aFlags);
   bool ShouldClip();
   bool MustCreateSurface(gfxContext* aContext,
                          const gfxMatrix& aTransform,
                          const gfxRect& aSourceRect,
                          const nsIntRect& aSubimage,
                          const uint32_t aFlags) const;
   gfxFloat ClampFactor(const gfxFloat aToClamp, const int aReference) const;
   nsresult DrawSingleTile(gfxContext* aContext,
--- a/image/src/FrozenImage.cpp
+++ b/image/src/FrozenImage.cpp
@@ -35,22 +35,21 @@ FrozenImage::GetAnimated(bool* aAnimated
   bool dummy;
   nsresult rv = InnerImage()->GetAnimated(&dummy);
   if (NS_SUCCEEDED(rv)) {
     *aAnimated = false;
   }
   return rv;
 }
 
-NS_IMETHODIMP
+NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
 FrozenImage::GetFrame(uint32_t aWhichFrame,
-                      uint32_t aFlags,
-                      gfxASurface** _retval)
+                      uint32_t aFlags)
 {
-  return InnerImage()->GetFrame(FRAME_FIRST, aFlags, _retval);
+  return InnerImage()->GetFrame(FRAME_FIRST, aFlags);
 }
 
 NS_IMETHODIMP_(bool)
 FrozenImage::FrameIsOpaque(uint32_t aWhichFrame)
 {
   return InnerImage()->FrameIsOpaque(FRAME_FIRST);
 }
 
--- a/image/src/FrozenImage.h
+++ b/image/src/FrozenImage.h
@@ -29,19 +29,18 @@ public:
 
   virtual ~FrozenImage() { }
 
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
   virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
   virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
 
   NS_IMETHOD GetAnimated(bool* aAnimated) MOZ_OVERRIDE;
-  NS_IMETHOD GetFrame(uint32_t aWhichFrame,
-                      uint32_t aFlags,
-                      gfxASurface** _retval) MOZ_OVERRIDE;
+  NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
+                                                      uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD_(bool) FrameIsOpaque(uint32_t aWhichFrame) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(layers::LayerManager* aManager,
                                layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   GraphicsFilter aFilter,
                   const gfxMatrix& aUserSpaceToImageSpace,
                   const gfxRect& aFill,
                   const nsIntRect& aSubimage,
--- a/image/src/ImageWrapper.cpp
+++ b/image/src/ImageWrapper.cpp
@@ -191,22 +191,21 @@ ImageWrapper::GetType()
 }
 
 NS_IMETHODIMP
 ImageWrapper::GetAnimated(bool* aAnimated)
 {
   return mInnerImage->GetAnimated(aAnimated);
 }
 
-NS_IMETHODIMP
+NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
 ImageWrapper::GetFrame(uint32_t aWhichFrame,
-                       uint32_t aFlags,
-                       gfxASurface** _retval)
+                       uint32_t aFlags)
 {
-  return mInnerImage->GetFrame(aWhichFrame, aFlags, _retval);
+  return mInnerImage->GetFrame(aWhichFrame, aFlags);
 }
 
 NS_IMETHODIMP_(bool)
 ImageWrapper::FrameIsOpaque(uint32_t aWhichFrame)
 {
   return mInnerImage->FrameIsOpaque(aWhichFrame);
 }
 
--- a/image/src/OrientedImage.cpp
+++ b/image/src/OrientedImage.cpp
@@ -70,37 +70,36 @@ OrientedImage::GetIntrinsicRatio(nsSize*
 
   if (mOrientation.SwapsWidthAndHeight()) {
     swap(aRatio->width, aRatio->height);
   }
 
   return rv;
 }
 
-NS_IMETHODIMP
+NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
 OrientedImage::GetFrame(uint32_t aWhichFrame,
-                        uint32_t aFlags,
-                        gfxASurface** _retval)
+                        uint32_t aFlags)
 {
   nsresult rv;
 
   if (mOrientation.IsIdentity()) {
-    return InnerImage()->GetFrame(aWhichFrame, aFlags, _retval);
+    return InnerImage()->GetFrame(aWhichFrame, aFlags);
   }
 
   // Get the underlying dimensions.
   int32_t width, height;
   if (mOrientation.SwapsWidthAndHeight()) {
     rv = InnerImage()->GetWidth(&height);
     rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&width);
   } else {
     rv = InnerImage()->GetWidth(&width);
     rv = NS_FAILED(rv) ? rv : InnerImage()->GetHeight(&height);
   }
-  NS_ENSURE_SUCCESS(rv, rv);
+  NS_ENSURE_SUCCESS(rv, nullptr);
 
   // Determine an appropriate format for the surface.
   gfx::SurfaceFormat surfaceFormat;
   gfxImageFormat imageFormat;
   if (InnerImage()->FrameIsOpaque(aWhichFrame)) {
     surfaceFormat = gfx::FORMAT_B8G8R8X8;
     imageFormat = gfxImageFormatARGB32;
   } else {
@@ -111,31 +110,30 @@ OrientedImage::GetFrame(uint32_t aWhichF
   // Create a surface to draw into.
   mozilla::RefPtr<mozilla::gfx::DrawTarget> target;
   target = gfxPlatform::GetPlatform()->
     CreateOffscreenCanvasDrawTarget(gfx::IntSize(width, height), surfaceFormat);
   nsRefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->
     GetThebesSurfaceForDrawTarget(target);
 
   // Create our drawable.
-  nsRefPtr<gfxASurface> innerSurface;
-  rv = InnerImage()->GetFrame(aWhichFrame, aFlags, getter_AddRefs(innerSurface));
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsRefPtr<gfxASurface> innerSurface =
+    InnerImage()->GetFrame(aWhichFrame, aFlags);
+  NS_ENSURE_TRUE(innerSurface, nullptr);
   nsRefPtr<gfxDrawable> drawable =
     new gfxSurfaceDrawable(innerSurface, gfxIntSize(width, height));
 
   // Draw.
   nsRefPtr<gfxContext> ctx = new gfxContext(surface);
   gfxRect imageRect(0, 0, width, height);
   gfxUtils::DrawPixelSnapped(ctx, drawable, OrientationMatrix(nsIntSize(width, height)),
                              imageRect, imageRect, imageRect, imageRect,
                              imageFormat, GraphicsFilter::FILTER_FAST);
 
-  surface.forget(_retval);
-  return NS_OK;
+  return surface.forget();
 }
 
 NS_IMETHODIMP
 OrientedImage::GetImageContainer(LayerManager* aManager, ImageContainer** _retval)
 {
   // XXX(seth): We currently don't have a way of orienting the result of
   // GetImageContainer. We work around this by always returning null, but if it
   // ever turns out that OrientedImage is widely used on codepaths that can
--- a/image/src/OrientedImage.h
+++ b/image/src/OrientedImage.h
@@ -27,19 +27,18 @@ public:
   virtual ~OrientedImage() { }
 
   virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
 
   NS_IMETHOD GetWidth(int32_t* aWidth) MOZ_OVERRIDE;
   NS_IMETHOD GetHeight(int32_t* aHeight) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicSize(nsSize* aSize) MOZ_OVERRIDE;
   NS_IMETHOD GetIntrinsicRatio(nsSize* aRatio) MOZ_OVERRIDE;
-  NS_IMETHOD GetFrame(uint32_t aWhichFrame,
-                      uint32_t aFlags,
-                      gfxASurface** _retval) MOZ_OVERRIDE;
+  NS_IMETHOD_(already_AddRefed<gfxASurface>) GetFrame(uint32_t aWhichFrame,
+                                                      uint32_t aFlags) MOZ_OVERRIDE;
   NS_IMETHOD GetImageContainer(mozilla::layers::LayerManager* aManager,
                                mozilla::layers::ImageContainer** _retval) MOZ_OVERRIDE;
   NS_IMETHOD Draw(gfxContext* aContext,
                   GraphicsFilter aFilter,
                   const gfxMatrix& aUserSpaceToImageSpace,
                   const gfxRect& aFill,
                   const nsIntRect& aSubimage,
                   const nsIntSize& aViewportSize,
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -874,93 +874,84 @@ RasterImage::CopyFrame(uint32_t aWhichFr
 
   *_retval = imgsurface.forget().get();
   return NS_OK;
 }
 
 //******************************************************************************
 /* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
  *                                 in uint32_t aFlags); */
-NS_IMETHODIMP
+NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
 RasterImage::GetFrame(uint32_t aWhichFrame,
-                      uint32_t aFlags,
-                      gfxASurface **_retval)
+                      uint32_t aFlags)
 {
+  MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
+
   if (aWhichFrame > FRAME_MAX_VALUE)
-    return NS_ERROR_INVALID_ARG;
+    return nullptr;
 
   if (mError)
-    return NS_ERROR_FAILURE;
+    return nullptr;
 
   // Disallowed in the API
   if (mInDecoder && (aFlags & imgIContainer::FLAG_SYNC_DECODE))
-    return NS_ERROR_FAILURE;
-
-  nsresult rv = NS_OK;
+    return nullptr;
 
   if (!ApplyDecodeFlags(aFlags))
-    return NS_ERROR_NOT_AVAILABLE;
+    return nullptr;
 
   // If the caller requested a synchronous decode, do it
   if (aFlags & FLAG_SYNC_DECODE) {
-    rv = SyncDecode();
-    CONTAINER_ENSURE_SUCCESS(rv);
+    nsresult rv = SyncDecode();
+    CONTAINER_ENSURE_TRUE(NS_SUCCEEDED(rv), nullptr);
   }
 
   // Get the frame. If it's not there, it's probably the caller's fault for
   // not waiting for the data to be loaded from the network or not passing
   // FLAG_SYNC_DECODE
   uint32_t frameIndex = (aWhichFrame == FRAME_FIRST) ?
                           0 : GetCurrentImgFrameIndex();
   imgFrame *frame = GetDrawableImgFrame(frameIndex);
   if (!frame) {
-    *_retval = nullptr;
-    return NS_ERROR_FAILURE;
+    return nullptr;
   }
 
   nsRefPtr<gfxASurface> framesurf;
 
   // If this frame covers the entire image, we can just reuse its existing
   // surface.
   nsIntRect framerect = frame->GetRect();
   if (framerect.x == 0 && framerect.y == 0 &&
       framerect.width == mSize.width &&
       framerect.height == mSize.height)
-    rv = frame->GetSurface(getter_AddRefs(framesurf));
+    frame->GetSurface(getter_AddRefs(framesurf));
 
   // The image doesn't have a surface because it's been optimized away. Create
   // one.
   if (!framesurf) {
     nsRefPtr<gfxImageSurface> imgsurf;
-    rv = CopyFrame(aWhichFrame, aFlags, getter_AddRefs(imgsurf));
+    CopyFrame(aWhichFrame, aFlags, getter_AddRefs(imgsurf));
     framesurf = imgsurf;
   }
 
-  *_retval = framesurf.forget().get();
-
-  return rv;
+  return framesurf.forget();
 }
 
 already_AddRefed<layers::Image>
 RasterImage::GetCurrentImage()
 {
   if (!mDecoded) {
     // We can't call StartDecoding because that can synchronously notify
     // which can cause DOM modification
     RequestDecodeCore(ASYNCHRONOUS);
     return nullptr;
   }
 
-  nsRefPtr<gfxASurface> imageSurface;
-  nsresult rv = GetFrame(FRAME_CURRENT, FLAG_NONE, getter_AddRefs(imageSurface));
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  if (!imageSurface) {
-    return nullptr;
-  }
+  nsRefPtr<gfxASurface> imageSurface = GetFrame(FRAME_CURRENT, FLAG_NONE);
+  NS_ENSURE_TRUE(imageSurface, nullptr);
 
   if (!mImageContainer) {
     mImageContainer = LayerManager::CreateImageContainer();
   }
 
   CairoImage::Data cairoData;
   cairoData.mSurface = imageSurface;
   GetWidth(&cairoData.mSize.width);
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -642,38 +642,37 @@ VectorImage::FrameIsOpaque(uint32_t aWhi
     NS_WARNING("aWhichFrame outside valid range!");
 
   return false; // In general, SVG content is not opaque.
 }
 
 //******************************************************************************
 /* [noscript] gfxASurface getFrame(in uint32_t aWhichFrame,
  *                                 in uint32_t aFlags; */
-NS_IMETHODIMP
+NS_IMETHODIMP_(already_AddRefed<gfxASurface>)
 VectorImage::GetFrame(uint32_t aWhichFrame,
-                      uint32_t aFlags,
-                      gfxASurface** _retval)
+                      uint32_t aFlags)
 {
-  NS_ENSURE_ARG_POINTER(_retval);
+  MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
 
   if (aWhichFrame > FRAME_MAX_VALUE)
-    return NS_ERROR_INVALID_ARG;
+    return nullptr;
 
   if (mError)
-    return NS_ERROR_FAILURE;
+    return nullptr;
 
   // Look up height & width
   // ----------------------
   nsIntSize imageIntSize;
   if (!mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eWidth,
                                              imageIntSize.width) ||
       !mSVGDocumentWrapper->GetWidthOrHeight(SVGDocumentWrapper::eHeight,
                                              imageIntSize.height)) {
     // We'll get here if our SVG doc has a percent-valued width or height.
-    return NS_ERROR_FAILURE;
+    return nullptr;
   }
 
   // Create a surface that we'll ultimately return
   // ---------------------------------------------
   // Make our surface the size of what will ultimately be drawn to it.
   // (either the full image size, or the restricted region)
   gfxIntSize surfaceSize(imageIntSize.width, imageIntSize.height);
 
@@ -684,19 +683,18 @@ VectorImage::GetFrame(uint32_t aWhichFra
   // Draw to our surface!
   // --------------------
   nsresult rv = Draw(context, GraphicsFilter::FILTER_NEAREST, gfxMatrix(),
                      gfxRect(gfxPoint(0,0), gfxIntSize(imageIntSize.width,
                                                        imageIntSize.height)),
                      nsIntRect(nsIntPoint(0,0), imageIntSize),
                      imageIntSize, nullptr, aWhichFrame, aFlags);
 
-  NS_ENSURE_SUCCESS(rv, rv);
-  *_retval = surface.forget().get();
-  return rv;
+  NS_ENSURE_SUCCESS(rv, nullptr);
+  return surface.forget();
 }
 
 //******************************************************************************
 /* [noscript] ImageContainer getImageContainer(); */
 NS_IMETHODIMP
 VectorImage::GetImageContainer(LayerManager* aManager,
                                mozilla::layers::ImageContainer** _retval)
 {
--- a/image/src/imgTools.cpp
+++ b/image/src/imgTools.cpp
@@ -271,20 +271,19 @@ NS_IMETHODIMP imgTools::EncodeImageData(
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CallQueryInterface(encoder, aStream);
 }
 
 NS_IMETHODIMP imgTools::GetFirstImageFrame(imgIContainer *aContainer,
                                            gfxImageSurface **aSurface)
 {
-  nsRefPtr<gfxASurface> surface;
-  aContainer->GetFrame(imgIContainer::FRAME_FIRST,
-                       imgIContainer::FLAG_SYNC_DECODE,
-                       getter_AddRefs(surface));
+  nsRefPtr<gfxASurface> surface =
+    aContainer->GetFrame(imgIContainer::FRAME_FIRST,
+                         imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(surface, NS_ERROR_NOT_AVAILABLE);
 
   nsRefPtr<gfxImageSurface> frame(surface->CopyToARGB32ImageSurface());
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
   NS_ENSURE_TRUE(frame->Width() && frame->Height(), NS_ERROR_FAILURE);
 
   frame.forget(aSurface);
   return NS_OK;
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -4811,21 +4811,19 @@ nsLayoutUtils::SurfaceFromElement(nsIIma
   uint32_t whichFrame = (aSurfaceFlags & SFE_WANT_FIRST_FRAME)
                         ? (uint32_t) imgIContainer::FRAME_FIRST
                         : (uint32_t) imgIContainer::FRAME_CURRENT;
   uint32_t frameFlags = imgIContainer::FLAG_SYNC_DECODE;
   if (aSurfaceFlags & SFE_NO_COLORSPACE_CONVERSION)
     frameFlags |= imgIContainer::FLAG_DECODE_NO_COLORSPACE_CONVERSION;
   if (aSurfaceFlags & SFE_NO_PREMULTIPLY_ALPHA)
     frameFlags |= imgIContainer::FLAG_DECODE_NO_PREMULTIPLY_ALPHA;
-  nsRefPtr<gfxASurface> framesurf;
-  rv = imgContainer->GetFrame(whichFrame,
-                              frameFlags,
-                              getter_AddRefs(framesurf));
-  if (NS_FAILED(rv))
+  nsRefPtr<gfxASurface> framesurf =
+    imgContainer->GetFrame(whichFrame, frameFlags);
+  if (!framesurf)
     return result;
 
   int32_t imgWidth, imgHeight;
   rv = imgContainer->GetWidth(&imgWidth);
   nsresult rv2 = imgContainer->GetHeight(&imgHeight);
   if (NS_FAILED(rv) || NS_FAILED(rv2))
     return result;
 
--- a/widget/cocoa/nsClipboard.mm
+++ b/widget/cocoa/nsClipboard.mm
@@ -426,20 +426,19 @@ nsClipboard::PasteboardDictFromTransfera
       ptrPrimitive->GetData(getter_AddRefs(primitiveData));
 
       nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
       if (!image) {
         NS_WARNING("Image isn't an imgIContainer in transferable");
         continue;
       }
 
-      nsRefPtr<gfxASurface> surface;
-      image->GetFrame(imgIContainer::FRAME_CURRENT,
-                      imgIContainer::FLAG_SYNC_DECODE,
-                      getter_AddRefs(surface));
+      nsRefPtr<gfxASurface> surface =
+        image->GetFrame(imgIContainer::FRAME_CURRENT,
+                        imgIContainer::FLAG_SYNC_DECODE);
       if (!surface) {
         continue;
       }
       nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
       if (!frame) {
         continue;
       }
       CGImageRef imageRef = NULL;
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -367,20 +367,18 @@ nsresult nsCocoaUtils::CreateNSImageFrom
     aImage->Draw(context, GraphicsFilter::FILTER_NEAREST, gfxMatrix(),
       gfxRect(0.0f, 0.0f, scaledWidth, scaledHeight),
       nsIntRect(0, 0, width, height),
       nsIntSize(scaledWidth, scaledHeight),
       nullptr, aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
   }
 
   else {
-    nsRefPtr<gfxASurface> surface;
-    aImage->GetFrame(aWhichFrame,
-                     imgIContainer::FLAG_SYNC_DECODE,
-                     getter_AddRefs(surface));
+    nsRefPtr<gfxASurface> surface =
+      aImage->GetFrame(aWhichFrame, imgIContainer::FLAG_SYNC_DECODE);
     NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
     frame = surface->GetAsReadableARGB32ImageSurface();
     NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
   }
 
   CGImageRef imageRef = NULL;
   nsresult rv = nsCocoaUtils::CreateCGImageFromSurface(frame, &imageRef);
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -379,20 +379,19 @@ nsMenuItemIconX::OnStopFrame(imgIRequest
     [mNativeMenuItem setImage:nil];
     return NS_ERROR_FAILURE;
   }
 
   if (mImageRegionRect.IsEmpty()) {
     mImageRegionRect.SetRect(0, 0, origWidth, origHeight);
   }
   
-  nsRefPtr<gfxASurface> surface;
-  imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
-                           imgIContainer::FLAG_NONE,
-                           getter_AddRefs(surface));
+  nsRefPtr<gfxASurface> surface =
+    imageContainer->GetFrame(imgIContainer::FRAME_CURRENT,
+                             imgIContainer::FLAG_NONE);
   if (!surface) {
     [mNativeMenuItem setImage:nil];
     return NS_ERROR_FAILURE;
   }
   nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   CGImageRef origImage = NULL;
--- a/widget/gtk/nsImageToPixbuf.cpp
+++ b/widget/gtk/nsImageToPixbuf.cpp
@@ -31,29 +31,27 @@ NS_IMETHODIMP_(GdkPixbuf*)
 nsImageToPixbuf::ConvertImageToPixbuf(imgIContainer* aImage)
 {
     return ImageToPixbuf(aImage);
 }
 
 GdkPixbuf*
 nsImageToPixbuf::ImageToPixbuf(imgIContainer* aImage)
 {
-    nsRefPtr<gfxASurface> surface;
-    aImage->GetFrame(imgIContainer::FRAME_CURRENT,
-                     imgIContainer::FLAG_SYNC_DECODE,
-                     getter_AddRefs(surface));
+    nsRefPtr<gfxASurface> surface =
+      aImage->GetFrame(imgIContainer::FRAME_CURRENT,
+                       imgIContainer::FLAG_SYNC_DECODE);
 
     // If the last call failed, it was probably because our call stack originates
     // in an imgINotificationObserver event, meaning that we're not allowed request
     // a sync decode. Presumably the originating event is something sensible like
     // OnStopFrame(), so we can just retry the call without a sync decode.
     if (!surface)
-        aImage->GetFrame(imgIContainer::FRAME_CURRENT,
-                         imgIContainer::FLAG_NONE,
-                         getter_AddRefs(surface));
+        surface = aImage->GetFrame(imgIContainer::FRAME_CURRENT,
+                                   imgIContainer::FLAG_NONE);
 
     NS_ENSURE_TRUE(surface, nullptr);
 
     nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
     NS_ENSURE_TRUE(frame, nullptr);
 
     return ImgSurfaceToPixbuf(frame, frame->Width(), frame->Height());
 }
--- a/widget/os2/nsWindow.cpp
+++ b/widget/os2/nsWindow.cpp
@@ -1329,20 +1329,19 @@ NS_IMETHODIMP nsWindow::SetCursor(imgICo
   // if this is the same image as last time, reuse the saved hptr;
   // it will be destroyed when we create a new one or when the
   // current window is destroyed
   if (mCssCursorImg == aCursor && mCssCursorHPtr) {
     WinSetPointer(HWND_DESKTOP, mCssCursorHPtr);
     return NS_OK;
   }
 
-  nsRefPtr<gfxASurface> surface;
-  aCursor->GetFrame(imgIContainer::FRAME_CURRENT,
-                    imgIContainer::FLAG_SYNC_DECODE,
-                    getter_AddRefs(surface));
+  nsRefPtr<gfxASurface> surface =
+    aCursor->GetFrame(imgIContainer::FRAME_CURRENT,
+                      imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(surface, NS_ERROR_NOT_AVAILABLE);
 
   nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
   NS_ENSURE_TRUE(frame, NS_ERROR_NOT_AVAILABLE);
 
   // if the image is ridiculously large, exit because
   // it will be unrecognizable when shrunk to 32x32
   int32_t width = frame->Width();
--- a/widget/qt/nsClipboard.cpp
+++ b/widget/qt/nsClipboard.cpp
@@ -171,20 +171,19 @@ nsClipboard::SetNativeClipboardData( nsI
                     continue;
 
                 nsCOMPtr<nsISupports> primitiveData;
                 ptrPrimitive->GetData(getter_AddRefs(primitiveData));
                 nsCOMPtr<imgIContainer> image(do_QueryInterface(primitiveData));
                 if (!image)  // Not getting an image for an image mime type!?
                    continue;
 
-                nsRefPtr<gfxASurface> surface;
-                image->GetFrame(imgIContainer::FRAME_CURRENT,
-                                imgIContainer::FLAG_SYNC_DECODE,
-                                getter_AddRefs(surface));
+                nsRefPtr<gfxASurface> surface =
+                  image->GetFrame(imgIContainer::FRAME_CURRENT,
+                                  imgIContainer::FLAG_SYNC_DECODE);
                 if (!surface)
                   continue;
 
                 nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
                 if (!frame)
                   continue;
 
                 QImage qImage(frame->Data(),
--- a/widget/windows/WinUtils.cpp
+++ b/widget/windows/WinUtils.cpp
@@ -689,18 +689,18 @@ AsyncFaviconDataReady::OnComplete(nsIURI
   nsAutoCString mimeTypeOfInputData;
   mimeTypeOfInputData.AssignLiteral("image/vnd.microsoft.icon");
   nsCOMPtr<imgIContainer> container;
   nsCOMPtr<imgITools> imgtool = do_CreateInstance("@mozilla.org/image/tools;1");
   rv = imgtool->DecodeImageData(stream, aMimeType,
                                 getter_AddRefs(container));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  nsRefPtr<gfxASurface> imgFrame;
-  rv = container->GetFrame(imgIContainer::FRAME_FIRST, 0, getter_AddRefs(imgFrame));
+  nsRefPtr<gfxASurface> imgFrame =
+    container->GetFrame(imgIContainer::FRAME_FIRST, 0);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<gfxImageSurface> imageSurface;
   gfxIntSize size;
   if (mURLShortcut) {
     imageSurface =
       new gfxImageSurface(gfxIntSize(48, 48),
                           gfxImageFormatARGB32);
--- a/widget/windows/nsImageClipboard.cpp
+++ b/widget/windows/nsImageClipboard.cpp
@@ -111,20 +111,19 @@ nsImageToClipboard::CalcSpanLength(uint3
 // image. 
 //
 nsresult
 nsImageToClipboard::CreateFromImage ( imgIContainer* inImage, HANDLE* outBitmap )
 {
     nsresult rv;
     *outBitmap = nullptr;
 
-    nsRefPtr<gfxASurface> surface;
-    inImage->GetFrame(imgIContainer::FRAME_CURRENT,
-                      imgIContainer::FLAG_SYNC_DECODE,
-                      getter_AddRefs(surface));
+    nsRefPtr<gfxASurface> surface =
+      inImage->GetFrame(imgIContainer::FRAME_CURRENT,
+                        imgIContainer::FLAG_SYNC_DECODE);
     NS_ENSURE_TRUE(surface, NS_ERROR_FAILURE);
 
     nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
     NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
     nsCOMPtr<imgIEncoder> encoder = do_CreateInstance("@mozilla.org/image/encoder;2?type=image/bmp", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -642,20 +642,19 @@ gfxIntSize nsWindowGfx::GetIconMetrics(I
 nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer,
                                   bool aIsCursor,
                                   uint32_t aHotspotX,
                                   uint32_t aHotspotY,
                                   gfxIntSize aScaledSize,
                                   HICON *aIcon) {
 
   // Get the image data
-  nsRefPtr<gfxASurface> surface;
-  aContainer->GetFrame(imgIContainer::FRAME_CURRENT,
-                       imgIContainer::FLAG_SYNC_DECODE,
-                       getter_AddRefs(surface));
+  nsRefPtr<gfxASurface> surface =
+    aContainer->GetFrame(imgIContainer::FRAME_CURRENT,
+                         imgIContainer::FLAG_SYNC_DECODE);
   NS_ENSURE_TRUE(surface, NS_ERROR_NOT_AVAILABLE);
 
   nsRefPtr<gfxImageSurface> frame(surface->GetAsReadableARGB32ImageSurface());
   NS_ENSURE_TRUE(frame, NS_ERROR_NOT_AVAILABLE);
 
   int32_t width = frame->Width();
   int32_t height = frame->Height();
   if (!width || !height)