Backed out 2 changesets (bug 1446309) for build bustages at builds/worker/workspace/build/src/image/RasterImage.cpp on a CLOSED TREE
authorAndreea Pavel <apavel@mozilla.com>
Tue, 14 Aug 2018 19:03:18 +0300
changeset 431473 5589d9ec31aabd93c3b1b20f2517b96ec78ef752
parent 431472 da82ea6820eebf698d72c7273efe4b19cad4fda3
child 431474 78d5bc33afd08d7fa8acedcdf074de4ddc6f0bf0
push id67780
push usercsabou@mozilla.com
push dateWed, 15 Aug 2018 01:59:18 +0000
treeherderautoland@b725384bc0ce [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1446309
milestone63.0a1
backs out45e3f5d8e29402e8fda2fea772dc5d08d8866fd7
69a4c2a0aac6e8bfc041a82b634611e1432af36b
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
Backed out 2 changesets (bug 1446309) for build bustages at builds/worker/workspace/build/src/image/RasterImage.cpp on a CLOSED TREE Backed out changeset 45e3f5d8e294 (bug 1446309) Backed out changeset 69a4c2a0aac6 (bug 1446309)
image/ClippedImage.cpp
image/ClippedImage.h
image/DynamicImage.cpp
image/FrozenImage.cpp
image/FrozenImage.h
image/Image.cpp
image/Image.h
image/ImageWrapper.cpp
image/ImgDrawResult.h
image/OrientedImage.cpp
image/OrientedImage.h
image/RasterImage.cpp
image/RasterImage.h
image/VectorImage.cpp
image/VectorImage.h
image/imgIContainer.idl
image/test/gtest/TestContainers.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsImageFrame.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsImageRenderer.cpp
layout/xul/nsImageBoxFrame.cpp
widget/nsBaseDragService.cpp
--- a/image/ClippedImage.cpp
+++ b/image/ClippedImage.cpp
@@ -360,35 +360,34 @@ ClippedImage::IsImageContainerAvailableA
                                               uint32_t aFlags)
 {
   if (!ShouldClip()) {
     return InnerImage()->IsImageContainerAvailableAtSize(aManager, aSize, aFlags);
   }
   return false;
 }
 
-NS_IMETHODIMP_(ImgDrawResult)
-ClippedImage::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                      const gfx::IntSize& aSize,
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
+ClippedImage::GetImageContainerAtSize(LayerManager* aManager,
+                                      const IntSize& aSize,
                                       const Maybe<SVGImageContext>& aSVGContext,
-                                      uint32_t aFlags,
-                                      layers::ImageContainer** aOutContainer)
+                                      uint32_t aFlags)
 {
   // 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
   // actually benefit from GetImageContainer, it would be a good idea to fix
   // that method for performance reasons.
 
   if (!ShouldClip()) {
-    return InnerImage()->GetImageContainerAtSize(aManager, aSize, aSVGContext,
-                                                 aFlags, aOutContainer);
+    return InnerImage()->GetImageContainerAtSize(aManager, aSize,
+                                                 aSVGContext, aFlags);
   }
 
-  return ImgDrawResult::NOT_SUPPORTED;
+  return nullptr;
 }
 
 static bool
 MustCreateSurface(gfxContext* aContext,
                   const nsIntSize& aSize,
                   const ImageRegion& aRegion,
                   const uint32_t aFlags)
 {
--- a/image/ClippedImage.h
+++ b/image/ClippedImage.h
@@ -46,22 +46,21 @@ public:
                                               uint32_t aFlags) override;
   NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
     GetImageContainer(layers::LayerManager* aManager,
                       uint32_t aFlags) override;
   NS_IMETHOD_(bool)
     IsImageContainerAvailableAtSize(layers::LayerManager* aManager,
                                     const gfx::IntSize& aSize,
                                     uint32_t aFlags) override;
-  NS_IMETHOD_(ImgDrawResult)
+  NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
     GetImageContainerAtSize(layers::LayerManager* aManager,
                             const gfx::IntSize& aSize,
                             const Maybe<SVGImageContext>& aSVGContext,
-                            uint32_t aFlags,
-                            layers::ImageContainer** aOutContainer) override;
+                            uint32_t aFlags) override;
   NS_IMETHOD_(ImgDrawResult) Draw(gfxContext* aContext,
                                const nsIntSize& aSize,
                                const ImageRegion& aRegion,
                                uint32_t aWhichFrame,
                                gfx::SamplingFilter aSamplingFilter,
                                const Maybe<SVGImageContext>& aSVGContext,
                                uint32_t aFlags,
                                float aOpacity) override;
--- a/image/DynamicImage.cpp
+++ b/image/DynamicImage.cpp
@@ -229,24 +229,23 @@ DynamicImage::GetImageContainer(LayerMan
 NS_IMETHODIMP_(bool)
 DynamicImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
                                               const IntSize& aSize,
                                               uint32_t aFlags)
 {
   return false;
 }
 
-NS_IMETHODIMP_(ImgDrawResult)
-DynamicImage::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                     const gfx::IntSize& aSize,
-                                     const Maybe<SVGImageContext>& aSVGContext,
-                                     uint32_t aFlags,
-                                     layers::ImageContainer** aContainer)
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
+DynamicImage::GetImageContainerAtSize(LayerManager* aManager,
+                                      const IntSize& aSize,
+                                      const Maybe<SVGImageContext>& aSVGContext,
+                                      uint32_t aFlags)
 {
-  return ImgDrawResult::NOT_SUPPORTED;
+  return nullptr;
 }
 
 NS_IMETHODIMP_(ImgDrawResult)
 DynamicImage::Draw(gfxContext* aContext,
                    const nsIntSize& aSize,
                    const ImageRegion& aRegion,
                    uint32_t aWhichFrame,
                    SamplingFilter aSamplingFilter,
--- a/image/FrozenImage.cpp
+++ b/image/FrozenImage.cpp
@@ -72,29 +72,28 @@ FrozenImage::GetImageContainer(layers::L
 NS_IMETHODIMP_(bool)
 FrozenImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
                                              const IntSize& aSize,
                                              uint32_t aFlags)
 {
   return false;
 }
 
-NS_IMETHODIMP_(ImgDrawResult)
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
 FrozenImage::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                     const gfx::IntSize& aSize,
+                                     const IntSize& aSize,
                                      const Maybe<SVGImageContext>& aSVGContext,
-                                     uint32_t aFlags,
-                                     layers::ImageContainer** aOutContainer)
+                                     uint32_t aFlags)
 {
   // XXX(seth): GetImageContainer does not currently support anything but the
   // current frame. We work around this by always returning null, but if it ever
   // turns out that FrozenImage is widely used on codepaths that can actually
   // benefit from GetImageContainer, it would be a good idea to fix that method
   // for performance reasons.
-  return ImgDrawResult::NOT_SUPPORTED;
+  return nullptr;
 }
 
 NS_IMETHODIMP_(ImgDrawResult)
 FrozenImage::Draw(gfxContext* aContext,
                   const nsIntSize& aSize,
                   const ImageRegion& aRegion,
                   uint32_t /* aWhichFrame - ignored */,
                   SamplingFilter aSamplingFilter,
--- a/image/FrozenImage.h
+++ b/image/FrozenImage.h
@@ -45,22 +45,21 @@ public:
                                               uint32_t aFlags) override;
   NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
     GetImageContainer(layers::LayerManager* aManager,
                       uint32_t aFlags) override;
   NS_IMETHOD_(bool)
     IsImageContainerAvailableAtSize(layers::LayerManager* aManager,
                                     const gfx::IntSize& aSize,
                                     uint32_t aFlags) override;
-  NS_IMETHOD_(ImgDrawResult)
+  NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
     GetImageContainerAtSize(layers::LayerManager* aManager,
                             const gfx::IntSize& aSize,
                             const Maybe<SVGImageContext>& aSVGContext,
-                            uint32_t aFlags,
-                            layers::ImageContainer** aOutContainer) override;
+                            uint32_t aFlags) override;
   NS_IMETHOD_(ImgDrawResult) Draw(gfxContext* aContext,
                                const nsIntSize& aSize,
                                const ImageRegion& aRegion,
                                uint32_t aWhichFrame,
                                gfx::SamplingFilter aSamplingFilter,
                                const Maybe<SVGImageContext>& aSVGContext,
                                uint32_t aFlags,
                                float aOpacity) override;
--- a/image/Image.cpp
+++ b/image/Image.cpp
@@ -99,41 +99,36 @@ ImageResource::SetCurrentImage(ImageCont
 
   if (aInTransaction) {
     aContainer->SetCurrentImagesInTransaction(imageList);
   } else {
     aContainer->SetCurrentImages(imageList);
   }
 }
 
-ImgDrawResult
+already_AddRefed<ImageContainer>
 ImageResource::GetImageContainerImpl(LayerManager* aManager,
                                      const IntSize& aSize,
                                      const Maybe<SVGImageContext>& aSVGContext,
-                                     uint32_t aFlags,
-                                     ImageContainer** aOutContainer)
+                                     uint32_t aFlags)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aManager);
   MOZ_ASSERT((aFlags & ~(FLAG_SYNC_DECODE |
                          FLAG_SYNC_DECODE_IF_FAST |
                          FLAG_ASYNC_NOTIFY |
                          FLAG_HIGH_QUALITY_SCALING))
                == FLAG_NONE,
              "Unsupported flag passed to GetImageContainer");
 
-  ImgDrawResult drawResult;
-  IntSize size;
-  Tie(drawResult, size) = GetImageContainerSize(aManager, aSize, aFlags);
-  if (drawResult != ImgDrawResult::SUCCESS) {
-    return drawResult;
+  IntSize size = GetImageContainerSize(aManager, aSize, aFlags);
+  if (size.IsEmpty()) {
+    return nullptr;
   }
 
-  MOZ_ASSERT(!size.IsEmpty());
-
   if (mAnimationConsumers == 0) {
     SendOnUnlockedDraw(aFlags);
   }
 
   uint32_t flags = (aFlags & ~(FLAG_SYNC_DECODE |
                                FLAG_SYNC_DECODE_IF_FAST)) | FLAG_ASYNC_NOTIFY;
   RefPtr<layers::ImageContainer> container;
   ImageContainerEntry* entry = nullptr;
@@ -155,36 +150,35 @@ ImageResource::GetImageContainerImpl(Lay
     }
   }
 
   if (container) {
     switch (entry->mLastDrawResult) {
       case ImgDrawResult::SUCCESS:
       case ImgDrawResult::BAD_IMAGE:
       case ImgDrawResult::BAD_ARGS:
-        container.forget(aOutContainer);
-        return entry->mLastDrawResult;
+        return container.forget();
       case ImgDrawResult::NOT_READY:
       case ImgDrawResult::INCOMPLETE:
       case ImgDrawResult::TEMPORARY_ERROR:
         // Temporary conditions where we need to rerequest the frame to recover.
         break;
       case ImgDrawResult::WRONG_SIZE:
         // Unused by GetFrameInternal
       default:
         MOZ_ASSERT_UNREACHABLE("Unhandled ImgDrawResult type!");
-        container.forget(aOutContainer);
-        return entry->mLastDrawResult;
+        return container.forget();
     }
   }
 
 #ifdef DEBUG
   NotifyDrawingObservers();
 #endif
 
+  ImgDrawResult drawResult;
   IntSize bestSize;
   RefPtr<SourceSurface> surface;
   Tie(drawResult, bestSize, surface) =
     GetFrameInternal(size, aSVGContext, FRAME_CURRENT,
                      aFlags | FLAG_ASYNC_NOTIFY);
 
   // The requested size might be refused by the surface cache (i.e. due to
   // factor-of-2 mode). In that case we don't want to create an entry for this
@@ -213,30 +207,28 @@ ImageResource::GetImageContainerImpl(Lay
       if (bestSize == entry->mSize && flags == entry->mFlags &&
           aSVGContext == entry->mSVGContext) {
         container = entry->mContainer.get();
         if (container) {
           switch (entry->mLastDrawResult) {
             case ImgDrawResult::SUCCESS:
             case ImgDrawResult::BAD_IMAGE:
             case ImgDrawResult::BAD_ARGS:
-              container.forget(aOutContainer);
-              return entry->mLastDrawResult;
+              return container.forget();
             case ImgDrawResult::NOT_READY:
             case ImgDrawResult::INCOMPLETE:
             case ImgDrawResult::TEMPORARY_ERROR:
               // Temporary conditions where we need to rerequest the frame to
               // recover. We have already done so!
               break;
            case ImgDrawResult::WRONG_SIZE:
               // Unused by GetFrameInternal
             default:
               MOZ_ASSERT_UNREACHABLE("Unhandled DrawResult type!");
-              container.forget(aOutContainer);
-              return entry->mLastDrawResult;
+              return container.forget();
           }
         }
         break;
       }
     }
   }
 
   if (!container) {
@@ -248,18 +240,17 @@ ImageResource::GetImageContainerImpl(Lay
     } else {
       entry = mImageContainers.AppendElement(
         ImageContainerEntry(bestSize, aSVGContext, container.get(), flags));
     }
   }
 
   SetCurrentImage(container, surface, true);
   entry->mLastDrawResult = drawResult;
-  container.forget(aOutContainer);
-  return drawResult;
+  return container.forget();
 }
 
 void
 ImageResource::UpdateImageContainer()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   for (int i = mImageContainers.Length() - 1; i >= 0; --i) {
--- a/image/Image.h
+++ b/image/Image.h
@@ -348,29 +348,28 @@ protected:
   }
 
   /**
    * Calculate the estimated size to use for an image container with the given
    * parameters. It may not be the same as the given size, and it may not be
    * the same as the size of the surface in the image container, but it is the
    * best effort estimate.
    */
-  virtual Tuple<ImgDrawResult, gfx::IntSize>
-    GetImageContainerSize(layers::LayerManager* aManager,
-                          const gfx::IntSize& aSize,
-                          uint32_t aFlags)
+  virtual gfx::IntSize GetImageContainerSize(layers::LayerManager* aManager,
+                                             const gfx::IntSize& aSize,
+                                             uint32_t aFlags)
   {
-    return MakeTuple(ImgDrawResult::NOT_SUPPORTED, gfx::IntSize(0, 0));
+    return gfx::IntSize(0, 0);
   }
 
-  ImgDrawResult GetImageContainerImpl(layers::LayerManager* aManager,
-                                      const gfx::IntSize& aSize,
-                                      const Maybe<SVGImageContext>& aSVGContext,
-                                      uint32_t aFlags,
-                                      layers::ImageContainer** aContainer);
+  already_AddRefed<layers::ImageContainer>
+    GetImageContainerImpl(layers::LayerManager* aManager,
+                          const gfx::IntSize& aSize,
+                          const Maybe<SVGImageContext>& aSVGContext,
+                          uint32_t aFlags);
 
   void UpdateImageContainer();
 
   void ReleaseImageContainer();
 
 private:
   void SetCurrentImage(layers::ImageContainer* aContainer,
                        gfx::SourceSurface* aSurface,
--- a/image/ImageWrapper.cpp
+++ b/image/ImageWrapper.cpp
@@ -217,25 +217,24 @@ ImageWrapper::GetImageContainer(LayerMan
 NS_IMETHODIMP_(bool)
 ImageWrapper::IsImageContainerAvailableAtSize(LayerManager* aManager,
                                               const IntSize& aSize,
                                               uint32_t aFlags)
 {
   return mInnerImage->IsImageContainerAvailableAtSize(aManager, aSize, aFlags);
 }
 
-NS_IMETHODIMP_(ImgDrawResult)
-ImageWrapper::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                      const gfx::IntSize& aSize,
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
+ImageWrapper::GetImageContainerAtSize(LayerManager* aManager,
+                                      const IntSize& aSize,
                                       const Maybe<SVGImageContext>& aSVGContext,
-                                      uint32_t aFlags,
-                                      layers::ImageContainer** aOutContainer)
+                                      uint32_t aFlags)
 {
-  return mInnerImage->GetImageContainerAtSize(aManager, aSize, aSVGContext,
-                                              aFlags, aOutContainer);
+  return mInnerImage->GetImageContainerAtSize(aManager, aSize,
+                                              aSVGContext, aFlags);
 }
 
 NS_IMETHODIMP_(ImgDrawResult)
 ImageWrapper::Draw(gfxContext* aContext,
                    const nsIntSize& aSize,
                    const ImageRegion& aRegion,
                    uint32_t aWhichFrame,
                    SamplingFilter aSamplingFilter,
--- a/image/ImgDrawResult.h
+++ b/image/ImgDrawResult.h
@@ -40,30 +40,26 @@ namespace image {
  *
  * TEMPORARY_ERROR: We failed to draw due to a temporary error. Drawing may
  * succeed at a later time.
  *
  * BAD_IMAGE: We failed to draw because the image has an error. This is a
  * permanent condition.
  *
  * BAD_ARGS: We failed to draw because bad arguments were passed to draw().
- *
- * NOT_SUPPORTED: The requested operation is not supported, but the image is
- *                otherwise valid.
  */
 enum class MOZ_MUST_USE_TYPE ImgDrawResult : uint8_t
 {
   SUCCESS,
   INCOMPLETE,
   WRONG_SIZE,
   NOT_READY,
   TEMPORARY_ERROR,
   BAD_IMAGE,
-  BAD_ARGS,
-  NOT_SUPPORTED
+  BAD_ARGS
 };
 
 /**
  * You can combine ImgDrawResults with &. By analogy to bitwise-&, the result is
  * ImgDrawResult::SUCCESS only if both operands are ImgDrawResult::SUCCESS. Otherwise,
  * a failing ImgDrawResult is returned; we favor the left operand's failure when
  * deciding which failure to return, with the exception that we always prefer
  * any other kind of failure over ImgDrawResult::BAD_IMAGE, since other failures
--- a/image/OrientedImage.cpp
+++ b/image/OrientedImage.cpp
@@ -177,35 +177,34 @@ OrientedImage::IsImageContainerAvailable
                                                uint32_t aFlags)
 {
   if (mOrientation.IsIdentity()) {
     return InnerImage()->IsImageContainerAvailableAtSize(aManager, aSize, aFlags);
   }
   return false;
 }
 
-NS_IMETHODIMP_(ImgDrawResult)
-OrientedImage::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                       const gfx::IntSize& aSize,
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
+OrientedImage::GetImageContainerAtSize(LayerManager* aManager,
+                                       const IntSize& aSize,
                                        const Maybe<SVGImageContext>& aSVGContext,
-                                       uint32_t aFlags,
-                                       layers::ImageContainer** aOutContainer)
+                                       uint32_t aFlags)
 {
   // 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
   // actually benefit from GetImageContainer, it would be a good idea to fix
   // that method for performance reasons.
 
   if (mOrientation.IsIdentity()) {
-    return InnerImage()->GetImageContainerAtSize(aManager, aSize, aSVGContext,
-                                                 aFlags, aOutContainer);
+    return InnerImage()->GetImageContainerAtSize(aManager, aSize,
+                                                 aSVGContext, aFlags);
   }
 
-  return ImgDrawResult::NOT_SUPPORTED;
+  return nullptr;
 }
 
 struct MatrixBuilder
 {
   explicit MatrixBuilder(bool aInvert) : mInvert(aInvert) { }
 
   gfxMatrix Build() { return mMatrix; }
 
--- a/image/OrientedImage.h
+++ b/image/OrientedImage.h
@@ -43,22 +43,21 @@ public:
                                               uint32_t aFlags) override;
   NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
     GetImageContainer(layers::LayerManager* aManager,
                       uint32_t aFlags) override;
   NS_IMETHOD_(bool)
     IsImageContainerAvailableAtSize(layers::LayerManager* aManager,
                                     const gfx::IntSize& aSize,
                                     uint32_t aFlags) override;
-  NS_IMETHOD_(ImgDrawResult)
+  NS_IMETHOD_(already_AddRefed<layers::ImageContainer>)
     GetImageContainerAtSize(layers::LayerManager* aManager,
                             const gfx::IntSize& aSize,
                             const Maybe<SVGImageContext>& aSVGContext,
-                            uint32_t aFlags,
-                            layers::ImageContainer** aOutContainer) override;
+                            uint32_t aFlags) override;
   NS_IMETHOD_(ImgDrawResult) Draw(gfxContext* aContext,
                                const nsIntSize& aSize,
                                const ImageRegion& aRegion,
                                uint32_t aWhichFrame,
                                gfx::SamplingFilter aSamplingFilter,
                                const Maybe<SVGImageContext>& aSVGContext,
                                uint32_t aFlags,
                                float aOpacity) override;
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -622,59 +622,42 @@ RasterImage::GetFrameInternal(const IntS
   RefPtr<SourceSurface> surface = result.Surface()->GetSourceSurface();
   if (!result.Surface()->IsFinished()) {
     return MakeTuple(ImgDrawResult::INCOMPLETE, suggestedSize, std::move(surface));
   }
 
   return MakeTuple(ImgDrawResult::SUCCESS, suggestedSize, std::move(surface));
 }
 
-Tuple<ImgDrawResult, IntSize>
+IntSize
 RasterImage::GetImageContainerSize(LayerManager* aManager,
                                    const IntSize& aSize,
                                    uint32_t aFlags)
 {
-  if (!mHasSize) {
-    return MakeTuple(ImgDrawResult::NOT_READY, IntSize(0, 0));
-  }
-
-  if (aSize.IsEmpty()) {
-    return MakeTuple(ImgDrawResult::BAD_ARGS, IntSize(0, 0));
-  }
-
-  // We check the minimum size because while we support downscaling, we do not
-  // support upscaling. If aSize > mSize, we will never give a larger surface
-  // than mSize. If mSize > aSize, and mSize > maxTextureSize, we still want to
-  // use image containers if aSize <= maxTextureSize.
-  int32_t maxTextureSize = aManager->GetMaxTextureSize();
-  if (min(mSize.width, aSize.width) > maxTextureSize ||
-      min(mSize.height, aSize.height) > maxTextureSize) {
-    return MakeTuple(ImgDrawResult::NOT_SUPPORTED, IntSize(0, 0));
+  if (!IsImageContainerAvailableAtSize(aManager, aSize, aFlags)) {
+    return IntSize(0, 0);
   }
 
   if (!CanDownscaleDuringDecode(aSize, aFlags)) {
-    return MakeTuple(ImgDrawResult::SUCCESS, mSize);
+    return mSize;
   }
 
-  return MakeTuple(ImgDrawResult::SUCCESS, aSize);
+  return aSize;
 }
 
 NS_IMETHODIMP_(bool)
 RasterImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
 {
   return IsImageContainerAvailableAtSize(aManager, mSize, aFlags);
 }
 
 NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
 RasterImage::GetImageContainer(LayerManager* aManager, uint32_t aFlags)
 {
-  RefPtr<ImageContainer> container;
-  GetImageContainerImpl(aManager, mSize, Nothing(), aFlags,
-                        getter_AddRefs(container));
-  return container.forget();
+  return GetImageContainerImpl(aManager, mSize, Nothing(), aFlags);
 }
 
 NS_IMETHODIMP_(bool)
 RasterImage::IsImageContainerAvailableAtSize(LayerManager* aManager,
                                              const IntSize& aSize,
                                              uint32_t aFlags)
 {
   // We check the minimum size because while we support downscaling, we do not
@@ -686,28 +669,26 @@ RasterImage::IsImageContainerAvailableAt
       min(mSize.width, aSize.width) > maxTextureSize ||
       min(mSize.height, aSize.height) > maxTextureSize) {
     return false;
   }
 
   return true;
 }
 
-NS_IMETHODIMP_(ImgDrawResult)
-RasterImage::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                     const gfx::IntSize& aSize,
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
+RasterImage::GetImageContainerAtSize(LayerManager* aManager,
+                                     const IntSize& aSize,
                                      const Maybe<SVGImageContext>& aSVGContext,
-                                     uint32_t aFlags,
-                                     layers::ImageContainer** aOutContainer)
+                                     uint32_t aFlags)
 {
   // We do not pass in the given SVG context because in theory it could differ
   // between calls, but actually have no impact on the actual contents of the
   // image container.
-  return GetImageContainerImpl(aManager, aSize, Nothing(),
-                               aFlags, aOutContainer);
+  return GetImageContainerImpl(aManager, aSize, Nothing(), aFlags);
 }
 
 size_t
 RasterImage::SizeOfSourceWithComputedFallback(SizeOfState& aState) const
 {
   return mSourceBuffer->SizeOfIncludingThisWithComputedFallback(
     aState.mMallocSizeOf);
 }
--- a/image/RasterImage.h
+++ b/image/RasterImage.h
@@ -307,20 +307,19 @@ private:
                           float aOpacity);
 
   Tuple<ImgDrawResult, gfx::IntSize, RefPtr<gfx::SourceSurface>>
     GetFrameInternal(const gfx::IntSize& aSize,
                      const Maybe<SVGImageContext>& aSVGContext,
                      uint32_t aWhichFrame,
                      uint32_t aFlags) override;
 
-  Tuple<ImgDrawResult, gfx::IntSize>
-    GetImageContainerSize(layers::LayerManager* aManager,
-                          const gfx::IntSize& aSize,
-                          uint32_t aFlags) override;
+  gfx::IntSize GetImageContainerSize(layers::LayerManager* aManager,
+                                     const gfx::IntSize& aSize,
+                                     uint32_t aFlags) override;
 
   //////////////////////////////////////////////////////////////////////////////
   // Decoding.
   //////////////////////////////////////////////////////////////////////////////
 
   /**
    * Creates and runs a decoder, either synchronously or asynchronously
    * according to @aFlags. Decodes at the provided target size @aSize, using
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -844,41 +844,26 @@ VectorImage::GetFrameInternal(const IntS
                      RefPtr<SourceSurface>());
   }
 
   SendFrameComplete(didCache, params.flags);
   return MakeTuple(ImgDrawResult::SUCCESS, aSize, std::move(surface));
 }
 
 //******************************************************************************
-Tuple<ImgDrawResult, IntSize>
+IntSize
 VectorImage::GetImageContainerSize(LayerManager* aManager,
                                    const IntSize& aSize,
                                    uint32_t aFlags)
 {
-  if (mError) {
-    return MakeTuple(ImgDrawResult::BAD_IMAGE, IntSize(0, 0));
-  }
-
-  if (!mIsFullyLoaded) {
-    return MakeTuple(ImgDrawResult::NOT_READY, IntSize(0, 0));
+  if (!IsImageContainerAvailableAtSize(aManager, aSize, aFlags)) {
+    return IntSize(0, 0);
   }
 
-  if (mHaveAnimations ||
-      aManager->GetBackendType() != LayersBackend::LAYERS_WR) {
-    return MakeTuple(ImgDrawResult::NOT_SUPPORTED, IntSize(0, 0));
-  }
-
-  // We don't need to check if the size is too big since we only support
-  // WebRender backends.
-  if (aSize.IsEmpty()) {
-    return MakeTuple(ImgDrawResult::BAD_ARGS, IntSize(0, 0));
-  }
-
-  return MakeTuple(ImgDrawResult::SUCCESS, aSize);
+  return aSize;
 }
 
 NS_IMETHODIMP_(bool)
 VectorImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
 {
   if (mError || !mIsFullyLoaded || mHaveAnimations ||
       aManager->GetBackendType() != LayersBackend::LAYERS_WR) {
     return false;
@@ -903,35 +888,34 @@ VectorImage::IsImageContainerAvailableAt
                                              uint32_t aFlags)
 {
   // Since we only support image containers with WebRender, and it can handle
   // textures larger than the hw max texture size, we don't need to check aSize.
   return !aSize.IsEmpty() && IsImageContainerAvailable(aManager, aFlags);
 }
 
 //******************************************************************************
-NS_IMETHODIMP_(ImgDrawResult)
-VectorImage::GetImageContainerAtSize(layers::LayerManager* aManager,
-                                     const gfx::IntSize& aSize,
+NS_IMETHODIMP_(already_AddRefed<ImageContainer>)
+VectorImage::GetImageContainerAtSize(LayerManager* aManager,
+                                     const IntSize& aSize,
                                      const Maybe<SVGImageContext>& aSVGContext,
-                                     uint32_t aFlags,
-                                     layers::ImageContainer** aOutContainer)
+                                     uint32_t aFlags)
 {
   Maybe<SVGImageContext> newSVGContext;
   MaybeRestrictSVGContext(newSVGContext, aSVGContext, aFlags);
 
   // Since we do not support high quality scaling with SVG, we mask it off so
   // that container requests with and without it map to the same container.
   // Similarly the aspect ratio flag was already handled as part of the SVG
   // context restriction above.
   uint32_t flags = aFlags & ~(FLAG_HIGH_QUALITY_SCALING |
                               FLAG_FORCE_PRESERVEASPECTRATIO_NONE);
   return GetImageContainerImpl(aManager, aSize,
                                newSVGContext ? newSVGContext : aSVGContext,
-                               flags, aOutContainer);
+                               flags);
 }
 
 bool
 VectorImage::MaybeRestrictSVGContext(Maybe<SVGImageContext>& aNewSVGContext,
                                      const Maybe<SVGImageContext>& aSVGContext,
                                      uint32_t aFlags)
 {
   bool overridePAR = (aFlags & FLAG_FORCE_PRESERVEASPECTRATIO_NONE) && aSVGContext;
--- a/image/VectorImage.h
+++ b/image/VectorImage.h
@@ -82,20 +82,19 @@ protected:
 
 private:
   Tuple<ImgDrawResult, IntSize, RefPtr<SourceSurface>>
     GetFrameInternal(const IntSize& aSize,
                      const Maybe<SVGImageContext>& aSVGContext,
                      uint32_t aWhichFrame,
                      uint32_t aFlags) override;
 
-  Tuple<ImgDrawResult, IntSize>
-    GetImageContainerSize(layers::LayerManager* aManager,
-                          const IntSize& aSize,
-                          uint32_t aFlags) override;
+  IntSize GetImageContainerSize(layers::LayerManager* aManager,
+                                const IntSize& aSize,
+                                uint32_t aFlags) override;
 
   /// Attempt to find a matching cached surface in the SurfaceCache.
   already_AddRefed<SourceSurface>
     LookupCachedSurface(const IntSize& aSize,
                         const Maybe<SVGImageContext>& aSVGContext,
                         uint32_t aFlags);
 
   bool MaybeRestrictSVGContext(Maybe<SVGImageContext>& aNewSVGContext,
--- a/image/imgIContainer.idl
+++ b/image/imgIContainer.idl
@@ -52,17 +52,16 @@ native ImgDrawResult(mozilla::image::Img
 [ref] native gfxSize(gfxSize);
 native SamplingFilter(mozilla::gfx::SamplingFilter);
 [ref] native nsIntRect(nsIntRect);
 native nsIntRectByVal(nsIntRect);
 [ref] native nsIntSize(nsIntSize);
 native nsSize(nsSize);
 [ptr] native nsIFrame(nsIFrame);
 native TempRefImageContainer(already_AddRefed<mozilla::layers::ImageContainer>);
-[ptr] native ImageContainer(mozilla::layers::ImageContainer);
 [ref] native ImageRegion(mozilla::image::ImageRegion);
 [ptr] native LayerManager(mozilla::layers::LayerManager);
 native Orientation(mozilla::image::Orientation);
 [ref] native TimeStamp(mozilla::TimeStamp);
 [ref] native MaybeSVGImageContext(mozilla::Maybe<mozilla::SVGImageContext>);
 native TempRefSourceSurface(already_AddRefed<mozilla::gfx::SourceSurface>);
 native TempRefImgIContainer(already_AddRefed<imgIContainer>);
 native nsIntSizeByVal(nsIntSize);
@@ -292,16 +291,25 @@ interface imgIContainer : nsISupports
    *               are supported.
    * @return An ImageContainer for the current frame, or nullptr if one could
    *         not be created.
    */
   [noscript, notxpcom] TempRefImageContainer getImageContainer(in LayerManager aManager,
                                                                in uint32_t aFlags);
 
   /**
+   * @return true if getImageContainer() is expected to return a valid
+   *         ImageContainer when passed the given @Manager, @Size and @Flags
+   *         parameters.
+   */
+  [noscript, notxpcom] boolean isImageContainerAvailableAtSize(in LayerManager aManager,
+                                                               [const] in nsIntSize aSize,
+                                                               in uint32_t aFlags);
+
+  /**
    * Attempts to create an ImageContainer (and Image) containing the current
    * frame at the given size. Match the requested size is best effort; it's
    * not guaranteed that the surface you get will be a perfect match. (Some
    * reasons you may get a surface of a different size include: if you
    * requested upscaling, or if downscale-during-decode is disabled.)
    *
    * Avoid calling this unless you're actually going to layerize this image.
    *
@@ -309,34 +317,23 @@ interface imgIContainer : nsISupports
    *                 ImageContainer.
    * @param aSVGContext If specified, SVG-related rendering context, such as
    *                    overridden attributes on the image document's root <svg>
    *                    node, and the size of the viewport that the full image
    *                    would occupy. Ignored for raster images.
    * @param aFlags Decoding / drawing flags (in other words, FLAG_* flags).
    *               Currently only FLAG_SYNC_DECODE and FLAG_SYNC_DECODE_IF_FAST
    *               are supported.
-   * @param aContainer Return value for ImageContainer for the current frame.
-   *                   May be null depending on the draw result.
-   * @return The draw result for the current frame.
+   * @return An ImageContainer for the current frame, or nullptr if one could
+   *         not be created.
    */
-  [noscript, notxpcom] ImgDrawResult getImageContainerAtSize(in LayerManager aManager,
-                                                             [const] in nsIntSize aSize,
-                                                             [const] in MaybeSVGImageContext aSVGContext,
-                                                             in uint32_t aFlags,
-                                                             out ImageContainer aOutContainer);
-
-  /**
-   * @return true if getImageContainer() is expected to return a valid
-   *         ImageContainer when passed the given @Manager, @Size and @Flags
-   *         parameters.
-   */
-  [noscript, notxpcom] boolean isImageContainerAvailableAtSize(in LayerManager aManager,
-                                                               [const] in nsIntSize aSize,
-                                                               in uint32_t aFlags);
+  [noscript, notxpcom] TempRefImageContainer getImageContainerAtSize(in LayerManager aManager,
+                                                                     [const] in nsIntSize aSize,
+                                                                     [const] in MaybeSVGImageContext aSVGContext,
+                                                                     in uint32_t aFlags);
 
   /**
    * Draw the requested frame of this image onto the context specified.
    *
    * Drawing an image involves scaling it to a certain size (which may be
    * implemented as a "smart" scale by substituting an HQ-scaled frame or
    * rendering at a high DPI), and then selecting a region of that image to
    * draw. That region is drawn onto the graphics context and in the process
--- a/image/test/gtest/TestContainers.cpp
+++ b/image/test/gtest/TestContainers.cpp
@@ -65,44 +65,41 @@ TEST_F(ImageContainers, RasterImageConta
   ASSERT_TRUE(nativeContainer != nullptr);
   IntSize containerSize = nativeContainer->GetCurrentSize();
   EXPECT_EQ(testCase.mSize.width, containerSize.width);
   EXPECT_EQ(testCase.mSize.height, containerSize.height);
 
   // Upscaling should give the native size.
   IntSize requestedSize = testCase.mSize;
   requestedSize.Scale(2, 2);
-  RefPtr<layers::ImageContainer> upscaleContainer;
-  image->GetImageContainerAtSize(layerManager,
-                                 requestedSize,
-                                 Nothing(),
-                                 imgIContainer::FLAG_SYNC_DECODE |
-                                 imgIContainer::FLAG_HIGH_QUALITY_SCALING,
-                                 getter_AddRefs(upscaleContainer));
+  RefPtr<layers::ImageContainer> upscaleContainer =
+    image->GetImageContainerAtSize(layerManager,
+                                   requestedSize,
+                                   Nothing(),
+                                   imgIContainer::FLAG_SYNC_DECODE |
+                                   imgIContainer::FLAG_HIGH_QUALITY_SCALING);
   ASSERT_TRUE(upscaleContainer != nullptr);
   containerSize = upscaleContainer->GetCurrentSize();
   EXPECT_EQ(testCase.mSize.width, containerSize.width);
   EXPECT_EQ(testCase.mSize.height, containerSize.height);
 
   // Downscaling should give the downscaled size.
   requestedSize = testCase.mSize;
   requestedSize.width /= 2;
   requestedSize.height /= 2;
-  RefPtr<layers::ImageContainer> downscaleContainer;
-  image->GetImageContainerAtSize(layerManager,
-                                 requestedSize,
-                                 Nothing(),
-                                 imgIContainer::FLAG_SYNC_DECODE |
-                                 imgIContainer::FLAG_HIGH_QUALITY_SCALING,
-                                 getter_AddRefs(downscaleContainer));
+  RefPtr<layers::ImageContainer> downscaleContainer =
+    image->GetImageContainerAtSize(layerManager,
+                                   requestedSize,
+                                   Nothing(),
+                                   imgIContainer::FLAG_SYNC_DECODE |
+                                   imgIContainer::FLAG_HIGH_QUALITY_SCALING);
   containerSize = downscaleContainer->GetCurrentSize();
   EXPECT_EQ(requestedSize.width, containerSize.width);
   EXPECT_EQ(requestedSize.height, containerSize.height);
 
   // Get at native size again. Should give same container.
-  RefPtr<layers::ImageContainer> againContainer;
-  image->GetImageContainerAtSize(layerManager,
-                                 testCase.mSize,
-                                 Nothing(),
-                                 imgIContainer::FLAG_SYNC_DECODE,
-                                 getter_AddRefs(againContainer));
+  RefPtr<layers::ImageContainer> againContainer =
+    image->GetImageContainerAtSize(layerManager,
+                                   testCase.mSize,
+                                   Nothing(),
+                                   imgIContainer::FLAG_SYNC_DECODE);
   ASSERT_EQ(nativeContainer.get(), againContainer.get());
 }
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -474,20 +474,18 @@ BulletRenderer::CreateWebRenderCommandsF
   }
 
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
   LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(mDest, appUnitsPerDevPixel);
   Maybe<SVGImageContext> svgContext;
   gfx::IntSize decodeSize =
     nsLayoutUtils::ComputeImageContainerDrawingParameters(mImage, aItem->Frame(), destRect,
                                                           aSc, flags, svgContext);
-
-  RefPtr<layers::ImageContainer> container;
-  mImage->GetImageContainerAtSize(aManager, decodeSize, svgContext,
-                                  flags, getter_AddRefs(container));
+  RefPtr<layers::ImageContainer> container =
+    mImage->GetImageContainerAtSize(aManager, decodeSize, svgContext, flags);
   if (!container) {
     return false;
   }
 
   gfx::IntSize size;
   Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container, aBuilder, aResources,
                                                                       aSc, size, Nothing());
   if (key.isNothing()) {
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1806,60 +1806,18 @@ nsDisplayImage::CreateWebRenderCommands(
 
   const int32_t factor = mFrame->PresContext()->AppUnitsPerDevPixel();
   const LayoutDeviceRect destRect(
     LayoutDeviceRect::FromAppUnits(GetDestRect(), factor));
   Maybe<SVGImageContext> svgContext;
   IntSize decodeSize =
     nsLayoutUtils::ComputeImageContainerDrawingParameters(mImage, mFrame, destRect,
                                                           aSc, flags, svgContext);
-
-  RefPtr<layers::ImageContainer> container;
-  ImgDrawResult drawResult =
-    mImage->GetImageContainerAtSize(aManager, decodeSize, svgContext,
-                                    flags, getter_AddRefs(container));
-
-  // While we got a container, it may not contain a fully decoded surface. If
-  // that is the case, and we have an image we were previously displaying which
-  // has a fully decoded surface, then we should prefer the previous image.
-  bool updatePrevImage = false;
-  switch (drawResult) {
-    case ImgDrawResult::NOT_READY:
-    case ImgDrawResult::INCOMPLETE:
-    case ImgDrawResult::TEMPORARY_ERROR:
-      if (mPrevImage && mPrevImage != mImage) {
-        RefPtr<ImageContainer> prevContainer;
-        drawResult = mPrevImage->GetImageContainerAtSize(aManager, decodeSize,
-                                                         svgContext, flags,
-                                                         getter_AddRefs(prevContainer));
-        if (prevContainer && drawResult == ImgDrawResult::SUCCESS) {
-          container = std::move(prevContainer);
-          break;
-        }
-
-        // Previous image was unusable; we can forget about it.
-        updatePrevImage = true;
-      }
-      break;
-    default:
-      updatePrevImage = mPrevImage != mImage;
-      break;
-  }
-
-  // The previous image was not used, and is different from the current image.
-  // We should forget about it. We need to update the frame as well because the
-  // display item may get recreated.
-  if (updatePrevImage) {
-    mPrevImage = mImage;
-    if (mFrame->IsImageFrame()) {
-      nsImageFrame* f = static_cast<nsImageFrame*>(mFrame);
-      f->mPrevImage = f->mImage;
-    }
-  }
-
+  RefPtr<ImageContainer> container =
+    mImage->GetImageContainerAtSize(aManager, decodeSize, svgContext, flags);
   if (!container) {
     return false;
   }
 
   // If the image container is empty, we don't want to fallback. Any other
   // failure will be due to resource constraints and fallback is unlikely to
   // help us. Hence we can ignore the return value from PushImage.
   aManager->CommandBuilder().PushImage(this, container, aBuilder, aResources, aSc, destRect);
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3716,20 +3716,18 @@ nsCSSBorderImageRenderer::CreateWebRende
         flags |= imgIContainer::FLAG_SYNC_DECODE;
       }
 
       RefPtr<imgIContainer> img = mImageRenderer.GetImage();
       Maybe<SVGImageContext> svgContext;
       gfx::IntSize decodeSize =
         nsLayoutUtils::ComputeImageContainerDrawingParameters(img, aForFrame, destRect,
                                                               aSc, flags, svgContext);
-
-      RefPtr<layers::ImageContainer> container;
-      img->GetImageContainerAtSize(aManager, decodeSize, svgContext,
-                                   flags, getter_AddRefs(container));
+      RefPtr<layers::ImageContainer> container =
+        img->GetImageContainerAtSize(aManager, decodeSize, svgContext, flags);
       if (!container) {
         return;
       }
 
       gfx::IntSize size;
       Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container, aBuilder,
                                                                           aResources, aSc, size, Nothing());
       if (key.isNothing()) {
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -613,20 +613,18 @@ nsImageRenderer::BuildWebRenderDisplayIt
       Maybe<SVGImageContext> svgContext(Some(SVGImageContext(Some(imageSize))));
 
       const int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
       LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
           aDest, appUnitsPerDevPixel);
       gfx::IntSize decodeSize =
         nsLayoutUtils::ComputeImageContainerDrawingParameters(mImageContainer, mForFrame, destRect,
                                                               aSc, containerFlags, svgContext);
-
-      RefPtr<layers::ImageContainer> container;
-      mImageContainer->GetImageContainerAtSize(aManager, decodeSize, svgContext,
-                                               containerFlags, getter_AddRefs(container));
+      RefPtr<layers::ImageContainer> container =
+        mImageContainer->GetImageContainerAtSize(aManager, decodeSize, svgContext, containerFlags);
       if (!container) {
         NS_WARNING("Failed to get image container");
         return ImgDrawResult::NOT_READY;
       }
 
       gfx::IntSize size;
       Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container, aBuilder,
                                                                           aResources, aSc, size, Nothing());
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -447,20 +447,18 @@ nsImageBoxFrame::CreateWebRenderCommands
 
   const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
   LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits(dest,
                                                              appUnitsPerDevPixel);
   Maybe<SVGImageContext> svgContext;
   gfx::IntSize decodeSize =
     nsLayoutUtils::ComputeImageContainerDrawingParameters(imgCon, aItem->Frame(), fillRect,
                                                           aSc, containerFlags, svgContext);
-
-  RefPtr<layers::ImageContainer> container;
-  imgCon->GetImageContainerAtSize(aManager, decodeSize, svgContext,
-                                  containerFlags, getter_AddRefs(container));
+  RefPtr<layers::ImageContainer> container =
+    imgCon->GetImageContainerAtSize(aManager, decodeSize, svgContext, containerFlags);
   if (!container) {
     NS_WARNING("Failed to get image container");
     return Nothing();
   }
 
   gfx::IntSize size;
   Maybe<wr::ImageKey> key = aManager->CommandBuilder().CreateImageKey(aItem, container,
                                                                       aBuilder, aResources,
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -784,18 +784,17 @@ nsBaseDragService::DrawDragForImage(nsPr
     if (!ctx)
       return NS_ERROR_FAILURE;
 
     ImgDrawResult res =
       imgContainer->Draw(ctx, destSize, ImageRegion::Create(destSize),
                          imgIContainer::FRAME_CURRENT,
                          SamplingFilter::GOOD, /* no SVGImageContext */ Nothing(),
                          imgIContainer::FLAG_SYNC_DECODE, 1.0);
-    if (res == ImgDrawResult::BAD_IMAGE || res == ImgDrawResult::BAD_ARGS ||
-        res == ImgDrawResult::NOT_SUPPORTED) {
+    if (res == ImgDrawResult::BAD_IMAGE || res == ImgDrawResult::BAD_ARGS) {
       return NS_ERROR_FAILURE;
     }
     *aSurface = dt->Snapshot();
   } else {
     *aSurface = aCanvas->GetSurfaceSnapshot();
   }
 
   return result;