Bug 1521027: Use the correct targets in ImageLib, allowing optimal behavior with OMTP. r=aosmond
authorBas Schouten <bschouten@mozilla.com>
Fri, 18 Jan 2019 07:56:43 +0100
changeset 514606 965622da5962b6cfd9e9e8b5332896e1634070e1
parent 514605 bd3e08ada630ea0051c778a5cbdb4af33e8471ae
child 514607 70857e6af679bed8ffcf7f4c9ae248bc26424c15
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaosmond
bugs1521027
milestone66.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 1521027: Use the correct targets in ImageLib, allowing optimal behavior with OMTP. r=aosmond Differential Revision: https://phabricator.services.mozilla.com/D16945
image/VectorImage.cpp
image/imgFrame.cpp
image/imgFrame.h
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -1112,17 +1112,18 @@ already_AddRefed<SourceSurface> VectorIm
       aParams.context ? aParams.context->GetDrawTarget()->GetBackendType()
                       : gfxPlatform::GetPlatform()->GetDefaultContentBackend();
 
   // Try to create an imgFrame, initializing the surface it contains by drawing
   // our gfxDrawable into it. (We use FILTER_NEAREST since we never scale here.)
   auto frame = MakeNotNull<RefPtr<imgFrame>>();
   nsresult rv = frame->InitWithDrawable(
       aSVGDrawable, aParams.size, SurfaceFormat::B8G8R8A8,
-      SamplingFilter::POINT, aParams.flags, backend);
+      SamplingFilter::POINT, aParams.flags, backend,
+      aParams.context ? aParams.context->GetDrawTarget() : nullptr);
 
   // If we couldn't create the frame, it was probably because it would end
   // up way too big. Generally it also wouldn't fit in the cache, but the prefs
   // could be set such that the cache isn't the limiting factor.
   if (NS_FAILED(rv)) {
     aWillCache = false;
     return nullptr;
   }
--- a/image/imgFrame.cpp
+++ b/image/imgFrame.cpp
@@ -358,22 +358,20 @@ nsresult imgFrame::InitForDecoderRecycle
   mTimeout = aAnimParams.mTimeout;
   mBlendMethod = aAnimParams.mBlendMethod;
   mDisposalMethod = aAnimParams.mDisposalMethod;
   mDirtyRect = mFrameRect;
 
   return NS_OK;
 }
 
-nsresult imgFrame::InitWithDrawable(gfxDrawable* aDrawable,
-                                    const nsIntSize& aSize,
-                                    const SurfaceFormat aFormat,
-                                    SamplingFilter aSamplingFilter,
-                                    uint32_t aImageFlags,
-                                    gfx::BackendType aBackend) {
+nsresult imgFrame::InitWithDrawable(
+    gfxDrawable* aDrawable, const nsIntSize& aSize, const SurfaceFormat aFormat,
+    SamplingFilter aSamplingFilter, uint32_t aImageFlags,
+    gfx::BackendType aBackend, DrawTarget* aTargetDT) {
   // Assert for properties that should be verified by decoders,
   // warn for properties related to bad content.
   if (!SurfaceCache::IsLegalSize(aSize)) {
     NS_WARNING("Should have legal image size");
     mAborted = true;
     return NS_ERROR_FAILURE;
   }
 
@@ -416,22 +414,26 @@ nsresult imgFrame::InitWithDrawable(gfxD
         mFormat);
   } else {
     // We can't use data surfaces for content, so we'll create an offscreen
     // surface instead.  This means if someone later calls RawAccessRef(), we
     // may have to do an expensive readback, but we warned callers about that in
     // the documentation for this method.
     MOZ_ASSERT(!mOptSurface, "Called imgFrame::InitWithDrawable() twice?");
 
-    if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(aBackend)) {
-      target = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(
-          aBackend, mFrameRect.Size(), mFormat);
+    if (aTargetDT && !gfxVars::UseWebRender()) {
+      target = aTargetDT->CreateSimilarDrawTarget(mFrameRect.Size(), mFormat);
     } else {
-      target = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
-          mFrameRect.Size(), mFormat);
+      if (gfxPlatform::GetPlatform()->SupportsAzureContentForType(aBackend)) {
+        target = gfxPlatform::GetPlatform()->CreateDrawTargetForBackend(
+            aBackend, mFrameRect.Size(), mFormat);
+      } else {
+        target = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+            mFrameRect.Size(), mFormat);
+      }
     }
   }
 
   if (!target || !target->IsValid()) {
     mAborted = true;
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
@@ -500,20 +502,21 @@ nsresult imgFrame::Optimize(DrawTarget* 
     return NS_OK;
   }
 
   // XXX(seth): It's currently unclear if there's any reason why we can't
   // optimize non-premult surfaces. We should look into removing this.
   if (mNonPremult) {
     return NS_OK;
   }
-
-  mOptSurface = gfxPlatform::GetPlatform()
-                    ->ScreenReferenceDrawTarget()
-                    ->OptimizeSourceSurface(mLockedSurface);
+  if (!gfxVars::UseWebRender()) {
+    mOptSurface = aTarget->OptimizeSourceSurface(mLockedSurface);
+  } else {
+    mOptSurface = gfxPlatform::GetPlatform()->ScreenReferenceDrawTarget()->OptimizeSourceSurface(mLockedSurface);
+  }
   if (mOptSurface == mLockedSurface) {
     mOptSurface = nullptr;
   }
 
   if (mOptSurface) {
     // There's no reason to keep our original surface around if we have an
     // optimized surface. Release our reference to it. This will leave
     // |mLockedSurface| as the only thing keeping it alive, so it'll get freed
--- a/image/imgFrame.h
+++ b/image/imgFrame.h
@@ -90,17 +90,18 @@ class imgFrame {
    * more expensive than in the InitForDecoder() case.
    *
    * aBackend specifies the DrawTarget backend type this imgFrame is supposed
    *          to be drawn to.
    */
   nsresult InitWithDrawable(gfxDrawable* aDrawable, const nsIntSize& aSize,
                             const SurfaceFormat aFormat,
                             SamplingFilter aSamplingFilter,
-                            uint32_t aImageFlags, gfx::BackendType aBackend);
+                            uint32_t aImageFlags, gfx::BackendType aBackend,
+                            DrawTarget* aTarget);
 
   DrawableFrameRef DrawableRef();
 
   /**
    * Create a RawAccessFrameRef for the frame.
    *
    * @param aOnlyFinished If true, only return a valid RawAccessFrameRef if
    *                      imgFrame::Finish has been called.