Bug 1366097 - Part 2. Implement VectorImage::GetFrameInternal as required by ImageResource for image containers. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 17 Nov 2017 14:08:52 -0500
changeset 392501 12fc7f8b8930fac9b91e1d4232e404b7ac6db3d5
parent 392500 eb77f75f95d945e1a9f95d035f83337c4e10b0c6
child 392502 a4b811e0b860206b0aa4a66a14b8ebaf8655940b
push id32921
push usernerli@mozilla.com
push dateFri, 17 Nov 2017 22:02:18 +0000
treeherdermozilla-central@daa0dcd1616c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1366097
milestone59.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 1366097 - Part 2. Implement VectorImage::GetFrameInternal as required by ImageResource for image containers. r=tnikkel No functional change aside from the implementation from VectorImage::GetFrameAtSize being repurposed for GetFrameInternal and returning an additional error code with the surface.
image/VectorImage.cpp
image/VectorImage.h
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -11,16 +11,17 @@
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "imgFrame.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/RefPtr.h"
+#include "mozilla/Tuple.h"
 #include "nsIDOMEvent.h"
 #include "nsIPresShell.h"
 #include "nsIStreamListener.h"
 #include "nsMimeTypes.h"
 #include "nsPresContext.h"
 #include "nsRect.h"
 #include "nsString.h"
 #include "nsStubDocumentObserver.h"
@@ -732,61 +733,76 @@ VectorImage::GetFrame(uint32_t aWhichFra
   return GetFrameAtSize(imageIntSize, aWhichFrame, aFlags);
 }
 
 NS_IMETHODIMP_(already_AddRefed<SourceSurface>)
 VectorImage::GetFrameAtSize(const IntSize& aSize,
                             uint32_t aWhichFrame,
                             uint32_t aFlags)
 {
+  auto result = GetFrameInternal(aSize, aWhichFrame, aFlags);
+  return Get<2>(result).forget();
+}
+
+Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
+VectorImage::GetFrameInternal(const IntSize& aSize,
+                              uint32_t aWhichFrame,
+                              uint32_t aFlags)
+{
   MOZ_ASSERT(aWhichFrame <= FRAME_MAX_VALUE);
 
-  if (aSize.IsEmpty()) {
-    return nullptr;
+  if (aSize.IsEmpty() || aWhichFrame > FRAME_MAX_VALUE) {
+    return MakeTuple(DrawResult::BAD_ARGS, aSize,
+                     RefPtr<SourceSurface>());
   }
 
-  if (aWhichFrame > FRAME_MAX_VALUE) {
-    return nullptr;
+  if (mError) {
+    return MakeTuple(DrawResult::BAD_IMAGE, aSize,
+                     RefPtr<SourceSurface>());
   }
 
-  if (mError || !mIsFullyLoaded) {
-    return nullptr;
+  if (!mIsFullyLoaded) {
+    return MakeTuple(DrawResult::NOT_READY, aSize,
+                     RefPtr<SourceSurface>());
   }
 
   RefPtr<SourceSurface> sourceSurface =
     LookupCachedSurface(aSize, Nothing(), aFlags);
   if (sourceSurface) {
-    return sourceSurface.forget();
+    return MakeTuple(DrawResult::SUCCESS, aSize, Move(sourceSurface));
   }
 
   if (mIsDrawing) {
     NS_WARNING("Refusing to make re-entrant call to VectorImage::Draw");
-    return nullptr;
+    return MakeTuple(DrawResult::TEMPORARY_ERROR, aSize,
+                     RefPtr<SourceSurface>());
   }
 
   // Make our surface the size of what will ultimately be drawn to it.
   // (either the full image size, or the restricted region)
   RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->
     CreateOffscreenContentDrawTarget(aSize, SurfaceFormat::B8G8R8A8);
   if (!dt || !dt->IsValid()) {
     NS_ERROR("Could not create a DrawTarget");
-    return nullptr;
+    return MakeTuple(DrawResult::TEMPORARY_ERROR, aSize,
+                     RefPtr<SourceSurface>());
   }
 
   RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
   MOZ_ASSERT(context); // already checked the draw target above
 
   Maybe<SVGImageContext> svgContext;
   SVGDrawingParameters params(context, aSize, ImageRegion::Create(aSize),
                               SamplingFilter::POINT, svgContext,
                               mSVGDocumentWrapper->GetCurrentTime(),
                               aFlags, 1.0);
 
   DrawInternal(params, false);
-  return dt->Snapshot();
+  RefPtr<SourceSurface> sourceSurface = dt->Snapshot();
+  return MakeTuple(DrawResult::SUCCESS, aSize, Move(sourceSurface));
 }
 
 //******************************************************************************
 NS_IMETHODIMP_(bool)
 VectorImage::IsImageContainerAvailable(LayerManager* aManager, uint32_t aFlags)
 {
   return false;
 }
@@ -894,17 +910,16 @@ VectorImage::Draw(gfxContext* aContext,
   SVGDrawingParameters params(aContext, aSize, aRegion, aSamplingFilter,
                               newSVGContext ? newSVGContext : aSVGContext,
                               animTime, aFlags, aOpacity);
 
   // If we have an prerasterized version of this image that matches the
   // drawing parameters, use that.
   RefPtr<SourceSurface> sourceSurface =
     LookupCachedSurface(aSize, params.svgContext, aFlags);
-
   if (sourceSurface) {
     RefPtr<gfxDrawable> svgDrawable =
       new gfxSurfaceDrawable(sourceSurface, sourceSurface->GetSize());
     Show(svgDrawable, params);
     return DrawResult::SUCCESS;
   }
 
   // else, we need to paint the image:
@@ -962,16 +977,18 @@ VectorImage::LookupCachedSurface(const I
   // in this case either.
   if (mHaveAnimations) {
     return nullptr;
   }
 
   LookupResult result =
     SurfaceCache::Lookup(ImageKey(this),
                          VectorSurfaceKey(aSize, aSVGContext));
+
+  MOZ_ASSERT(result.SuggestedSize().IsEmpty(), "SVG should not substitute!");
   if (!result) {
     return nullptr;  // No matching surface, or the OS freed the volatile buffer.
   }
 
   RefPtr<SourceSurface> sourceSurface = result.Surface()->GetSourceSurface();
   if (!sourceSurface) {
     // Something went wrong. (Probably a GPU driver crash or device reset.)
     // Attempt to recover.
--- a/image/VectorImage.h
+++ b/image/VectorImage.h
@@ -76,16 +76,21 @@ protected:
   explicit VectorImage(ImageURL* aURI = nullptr);
   virtual ~VectorImage();
 
   virtual nsresult StartAnimation() override;
   virtual nsresult StopAnimation() override;
   virtual bool     ShouldAnimate() override;
 
 private:
+  Tuple<DrawResult, IntSize, RefPtr<SourceSurface>>
+    GetFrameInternal(const IntSize& aSize,
+                     uint32_t aWhichFrame,
+                     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);
 
   void DrawInternal(const SVGDrawingParameters& aParams, bool aContextPaint);
   void CreateSurfaceAndShow(const SVGDrawingParameters& aParams,