Bug 1317636 - Part 4. Use nsSVGUtils::DetermineMaskUsage. draft
authorcku <cku@mozilla.com>
Thu, 17 Nov 2016 15:11:34 +0800
changeset 440751 3a60f9ac27659dae662a647d5fe3b9d9dcd76fd6
parent 440750 8968efc44dc4dbc622e3f1bd96e32698800dccbb
child 440752 493b7280366767d83b1fa9f62efd146ea0c651ef
push id36315
push userbmo:cku@mozilla.com
push dateFri, 18 Nov 2016 02:41:02 +0000
bugs1317636
milestone53.0a1
Bug 1317636 - Part 4. Use nsSVGUtils::DetermineMaskUsage. MozReview-Commit-ID: JUAof5JvU4j
layout/svg/nsSVGClipPathFrame.cpp
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -153,47 +153,43 @@ nsSVGClipPathFrame::PaintClipMask(gfxCon
     // We need to set mMatrixForChildren here so that under the PaintSVG calls
     // on our children (below) our GetCanvasTM() method will return the correct
     // transform.
     mMatrixForChildren = GetClipPathTransform(aClippedFrame) * aMatrix;
 
     // Check if this clipPath is itself clipped by another clipPath:
     nsSVGClipPathFrame* clipPathThatClipsClipPath =
       nsSVGEffects::GetEffectProperties(this).GetClipPathFrame(nullptr);
-    bool clippingOfClipPathRequiredMasking;
-    if (clipPathThatClipsClipPath) {
-      aMaskContext.Save();
-      clippingOfClipPathRequiredMasking = !clipPathThatClipsClipPath->IsTrivial();
-      if (!clippingOfClipPathRequiredMasking) {
-        clipPathThatClipsClipPath->ApplyClipPath(aMaskContext, aClippedFrame,
-                                                 aMatrix);
-      } else {
-        Matrix maskTransform;
-        RefPtr<SourceSurface> mask =
-          clipPathThatClipsClipPath->GetClipMask(aMaskContext, aClippedFrame,
-                                                 aMatrix, &maskTransform);
-        aMaskContext.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
-                                   mask, maskTransform);
-        // The corresponding PopGroupAndBlend call below will mask the
-        // blend using |mask|.
-      }
+    nsSVGUtils::MaskUsage maskUsage;
+    nsSVGUtils::DetermineMaskUsage(this, true, maskUsage);
+
+    if (maskUsage.shouldApplyClipPath) {
+      clipPathThatClipsClipPath->ApplyClipPath(aMaskContext, aClippedFrame,
+                                               aMatrix);
+    } else if (maskUsage.shouldGenerateClipMaskLayer) {
+      Matrix maskTransform;
+      RefPtr<SourceSurface> mask =
+        clipPathThatClipsClipPath->GetClipMask(aMaskContext, aClippedFrame,
+                                               aMatrix, &maskTransform);
+      aMaskContext.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
+                                         mask, maskTransform);
+      // The corresponding PopGroupAndBlend call below will mask the
+      // blend using |mask|.
     }
 
     // Paint our children into the mask:
     for (nsIFrame* kid = mFrames.FirstChild(); kid;
          kid = kid->GetNextSibling()) {
       result &= PaintFrameIntoMask(kid, aClippedFrame, aMaskContext, aMatrix);
     }
 
-
-    if (clipPathThatClipsClipPath) {
-      if (clippingOfClipPathRequiredMasking) {
-        aMaskContext.PopGroupAndBlend();
-      }
-      aMaskContext.Restore();
+    if (maskUsage.shouldGenerateClipMaskLayer) {
+      aMaskContext.PopGroupAndBlend();
+    } else if (maskUsage.shouldApplyClipPath) {
+      aMaskContext.PopClip();
     }
   }
 
   // Moz2D transforms in the opposite direction to Thebes
   gfxMatrix maskTransfrom = aMaskContext.CurrentMatrix();
   maskTransfrom.Invert();
 
   if (aExtraMask) {
@@ -221,54 +217,49 @@ nsSVGClipPathFrame::PaintFrameIntoMask(n
   bool isOK = true;
   // Children of this clipPath may themselves be clipped.
   nsSVGClipPathFrame *clipPathThatClipsChild =
     nsSVGEffects::GetEffectProperties(aFrame).GetClipPathFrame(&isOK);
   if (!isOK) {
     return DrawResult::SUCCESS;
   }
 
-  bool childsClipPathRequiresMasking;
-
-  if (clipPathThatClipsChild) {
-    childsClipPathRequiresMasking = !clipPathThatClipsChild->IsTrivial();
-    aTarget.Save();
-    if (!childsClipPathRequiresMasking) {
-      clipPathThatClipsChild->ApplyClipPath(aTarget, aClippedFrame, aMatrix);
-    } else {
-      Matrix maskTransform;
-      RefPtr<SourceSurface> mask =
-        clipPathThatClipsChild->GetClipMask(aTarget, aClippedFrame,
-                                            aMatrix, &maskTransform);
-      aTarget.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
-                                 mask, maskTransform);
-      // The corresponding PopGroupAndBlend call below will mask the
-      // blend using |mask|.
-    }
+  nsSVGUtils::MaskUsage maskUsage;
+  nsSVGUtils::DetermineMaskUsage(aFrame, true, maskUsage);
+  if (maskUsage.shouldApplyClipPath) {
+    clipPathThatClipsChild->ApplyClipPath(aTarget, aClippedFrame, aMatrix);
+  } else if (maskUsage.shouldGenerateClipMaskLayer) {
+    Matrix maskTransform;
+    RefPtr<SourceSurface> mask =
+      clipPathThatClipsChild->GetClipMask(aTarget, aClippedFrame,
+                                          aMatrix, &maskTransform);
+    aTarget.PushGroupForBlendBack(gfxContentType::ALPHA, 1.0,
+                               mask, maskTransform);
+    // The corresponding PopGroupAndBlend call below will mask the
+    // blend using |mask|.
   }
 
   gfxMatrix toChildsUserSpace = mMatrixForChildren;
   nsIFrame* child = do_QueryFrame(frame);
   nsIContent* childContent = child->GetContent();
   if (childContent->IsSVGElement()) {
     toChildsUserSpace =
       static_cast<const nsSVGElement*>(childContent)->
         PrependLocalTransformsTo(mMatrixForChildren, eUserSpaceToParent);
   }
 
   // Our children have NS_STATE_SVG_CLIPPATH_CHILD set on them, and
   // nsSVGPathGeometryFrame::Render checks for that state bit and paints
   // only the geometry (opaque black) if set.
   DrawResult result = frame->PaintSVG(aTarget, toChildsUserSpace);
 
-  if (clipPathThatClipsChild) {
-    if (childsClipPathRequiresMasking) {
-      aTarget.PopGroupAndBlend();
-    }
-    aTarget.Restore();
+  if (maskUsage.shouldGenerateClipMaskLayer) {
+    aTarget.PopGroupAndBlend();
+  } else if (maskUsage.shouldApplyClipPath) {
+    aTarget.PopClip();
   }
 
   return result;
 }
 
 already_AddRefed<SourceSurface>
 nsSVGClipPathFrame::GetClipMask(gfxContext& aReferenceContext,
                                 nsIFrame* aClippedFrame,