Bug 1234485 - Part 4. Implement nsDisplayMask::ShouldPaintOnMaskLayer. draft
authorcku <cku@mozilla.com>
Wed, 19 Oct 2016 11:44:15 +0800
changeset 435835 4dfec6e8d42ce46095d82d688984a8ef5d436119
parent 435834 496a0b706d5408fb86b669ea4d3e61146d95264d
child 435836 f43c7365245b637e554b02d0445a30c895d5b0cd
push id35137
push userbmo:cku@mozilla.com
push dateWed, 09 Nov 2016 09:16:18 +0000
bugs1234485
milestone52.0a1
Bug 1234485 - Part 4. Implement nsDisplayMask::ShouldPaintOnMaskLayer. MozReview-Commit-ID: CChi1vbLLh8
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -7052,19 +7052,47 @@ nsDisplayMask::BuildLayer(nsDisplayListB
   return container.forget();
 }
 
 LayerState
 nsDisplayMask::GetLayerState(nsDisplayListBuilder* aBuilder,
                              LayerManager* aManager,
                              const ContainerLayerParameters& aParameters)
 {
+  if (ShouldPaintOnMaskLayer(aManager)) {
+    return RequiredLayerStateForChildren(aBuilder, aManager, aParameters,
+                                         mList, GetAnimatedGeometryRoot());
+  }
+
   return LAYER_SVG_EFFECTS;
 }
 
+bool nsDisplayMask::ShouldPaintOnMaskLayer(LayerManager* aManager)
+{
+  if (!aManager->IsCompositingCheap()) {
+    return false;
+  }
+
+  nsSVGIntegrationUtils::MaskUsage maskUsage;
+  nsSVGIntegrationUtils::DetermineMaskUsage(mFrame, mHandleOpacity, maskUsage);
+
+  if (!maskUsage.shouldGenerateMaskLayer ||
+      maskUsage.opacity != 1.0 || maskUsage.shouldApplyClipPath ||
+      maskUsage.shouldApplyBasicShape ||
+      maskUsage.shouldGenerateClipMaskLayer) {
+    return false;
+  }
+
+  if (!nsSVGIntegrationUtils::IsMaskResourceReady(mFrame)) {
+    return false;
+  }
+
+  return true;
+}
+
 bool nsDisplayMask::ComputeVisibility(nsDisplayListBuilder* aBuilder,
                                       nsRegion* aVisibleRegion)
 {
   // Our children may be made translucent or arbitrarily deformed so we should
   // not allow them to subtract area from aVisibleRegion.
   nsRegion childrenVisible(mVisibleRect);
   nsRect r = mVisibleRect.Intersect(mList.GetBounds(aBuilder));
   mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -3913,16 +3913,20 @@ public:
                     nsRenderingContext* aCtx,
                     LayerManager* aManager);
 
   const nsTArray<nsRect>& GetDestRects()
   {
     return mDestRects;
   }
 private:
+  // According to mask property and the capability of aManager, determine
+  // whether paint mask onto a dedicate mask layer.
+  bool ShouldPaintOnMaskLayer(LayerManager* aManager);
+
   nsTArray<nsRect> mDestRects;
 };
 
 /**
  * A display item to paint a stacking context with filter effects set by the
  * stacking context root frame's style.
  */
 class nsDisplayFilter : public nsDisplaySVGEffects {