Bug 1447880. Allow PaintMaskAndClipPath to support different ways of painting its children. r=mstange
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Wed, 12 Sep 2018 15:14:20 -0400
changeset 493517 78784961fe2c0af5ee4501bd4296edb9eb60b6a6
parent 493516 4f0db2886781fc12b645cd7ae415fe8e094edf2b
child 493518 e3136af29c895b613def401aa30525735aff48ae
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1447880
milestone64.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 1447880. Allow PaintMaskAndClipPath to support different ways of painting its children. r=mstange Differential Revision: https://phabricator.services.mozilla.com/D6223
gfx/layers/wr/WebRenderCommandBuilder.cpp
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGIntegrationUtils.h
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -851,18 +851,18 @@ Grouper::PaintContainerItem(DIGroup* aGr
       } else {
         matrix = aContext->CurrentMatrix();
       }
 
       auto transformItem = static_cast<nsDisplayTransform*>(aItem);
       Matrix4x4Flagged trans = transformItem->GetTransform();
       Matrix trans2d;
       if (!trans.Is2D(&trans2d)) {
-        // We don't currently support doing invalidation inside 3d transforms
-        // for now just paint it as a single item
+        // We don't currently support doing invalidation inside 3d transforms.
+        // For now just paint it as a single item.
         BlobItemData* data = GetBlobItemDataForGroup(aItem, aGroup);
         if (data->mLayerManager->GetRoot()) {
           data->mLayerManager->BeginTransaction();
           data->mLayerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer, mDisplayListBuilder);
           aContext->GetDrawTarget()->FlushItem(aItemBounds);
         }
       } else {
         aContext->Multiply(ThebesMatrix(trans2d));
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -857,20 +857,20 @@ nsSVGIntegrationUtils::PaintMask(const P
     clipPathFrame->PaintClipMask(ctx, frame, cssPxToDevPxMatrix,
                                    &clipMaskTransform, maskSurface,
                                    ctx.CurrentMatrix());
   }
 
   return true;
 }
 
-void
-nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
+template<class T>
+void PaintMaskAndClipPathInternal(const PaintFramesParams& aParams, const T& aPaintChild)
 {
-  MOZ_ASSERT(UsingMaskOrClipPathForFrame(aParams.frame),
+  MOZ_ASSERT(nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(aParams.frame),
              "Should not use this method when no mask or clipPath effect"
              "on this frame");
 
   /* SVG defines the following rendering model:
    *
    *  1. Render geometry
    *  2. Apply filter
    *  3. Apply clipping, masking, group opacity
@@ -1011,22 +1011,17 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
       clipPathFrame->ApplyClipPath(context, frame, cssPxToDevPxMatrix);
     } else {
       nsCSSClipPathInstance::ApplyBasicShapeOrPathClip(context, frame);
     }
   }
 
   /* Paint the child */
   context.SetMatrix(matrixAutoSaveRestore.Matrix());
-  BasicLayerManager* basic = aParams.layerManager->AsBasicLayerManager();
-  RefPtr<gfxContext> oldCtx = basic->GetTarget();
-  basic->SetTarget(&context);
-  aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
-                                       aParams.builder);
-  basic->SetTarget(oldCtx);
+  aPaintChild();
 
   if (gfxPrefs::DrawMaskLayer()) {
     gfxContextAutoSaveRestore saver(&context);
 
     context.NewPath();
     gfxRect drawingRect =
       nsLayoutUtils::RectToGfxRect(aParams.borderArea,
                                    frame->PresContext()->AppUnitsPerDevPixel());
@@ -1053,16 +1048,37 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
   }
 
   if (shouldPushMask) {
     context.PopGroupAndBlend();
   }
 
 }
 
+
+void
+nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
+{
+  PaintMaskAndClipPathInternal(aParams, [&] {
+    gfxContext& context = aParams.ctx;
+    BasicLayerManager* basic = aParams.layerManager->AsBasicLayerManager();
+    RefPtr<gfxContext> oldCtx = basic->GetTarget();
+    basic->SetTarget(&context);
+    aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
+                                         aParams.builder);
+    basic->SetTarget(oldCtx);
+  });
+}
+
+void
+nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams, const std::function<void()>& aPaintChild)
+{
+  PaintMaskAndClipPathInternal(aParams, aPaintChild);
+}
+
 void
 nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
 {
   MOZ_ASSERT(!aParams.builder->IsForGenerateGlyphMask(),
              "Filter effect is discarded while generating glyph mask.");
   MOZ_ASSERT(aParams.frame->StyleEffects()->HasFilters(),
              "Should not use this method when no filter effect on this frame");
 
--- a/layout/svg/nsSVGIntegrationUtils.h
+++ b/layout/svg/nsSVGIntegrationUtils.h
@@ -161,16 +161,21 @@ public:
   };
 
   /**
    * Paint non-SVG frame with mask, clipPath and opacity effect.
    */
   static void
   PaintMaskAndClipPath(const PaintFramesParams& aParams);
 
+  // This should use FunctionRef instead of std::function because we don't need
+  // to take ownership of the function. See bug 1490781.
+  static void
+  PaintMaskAndClipPath(const PaintFramesParams& aParams, const std::function<void()>& aPaintChild);
+
   /**
    * Paint mask of non-SVG frame onto a given context, aParams.ctx.
    * aParams.ctx must contain an A8 surface. Returns false if the mask
    * didn't get painted and should be ignored at the call site.
    */
   static bool
   PaintMask(const PaintFramesParams& aParams);