Bug 1317636 - Part 3. Implement ComposeExtraMask. draft
authorcku <cku@mozilla.com>
Thu, 17 Nov 2016 12:42:14 +0800
changeset 440750 8968efc44dc4dbc622e3f1bd96e32698800dccbb
parent 440749 4493cb470092e912c6ecf8caf08990ac86d3501c
child 440751 3a60f9ac27659dae662a647d5fe3b9d9dcd76fd6
push id36315
push userbmo:cku@mozilla.com
push dateFri, 18 Nov 2016 02:41:02 +0000
bugs1317636
milestone53.0a1
Bug 1317636 - Part 3. Implement ComposeExtraMask. CG is removed. By testing, D2D works fine with composing a mask by OP_IN mode. MozReview-Commit-ID: Gs5rB6JachJ
layout/svg/nsSVGClipPathFrame.cpp
--- a/layout/svg/nsSVGClipPathFrame.cpp
+++ b/layout/svg/nsSVGClipPathFrame.cpp
@@ -99,16 +99,31 @@ nsSVGClipPathFrame::CreateClipMask(gfxCo
   RefPtr<DrawTarget> maskDT =
     referenceDT->CreateSimilarDrawTarget(bounds.Size(), SurfaceFormat::A8);
 
   aOffset = bounds.TopLeft();
 
   return maskDT.forget();
 }
 
+static void
+ComposeExtraMask(DrawTarget* aTarget, const gfxMatrix& aMaskTransfrom,
+                 SourceSurface* aExtraMask, const Matrix& aExtraMasksTransform)
+{
+  MOZ_ASSERT(aExtraMask);
+
+  Matrix origin = aTarget->GetTransform();
+  aTarget->SetTransform(aExtraMasksTransform * aTarget->GetTransform());
+  aTarget->MaskSurface(ColorPattern(Color(0.0, 0.0, 0.0, 1.0)),
+                       aExtraMask,
+                       Point(0, 0),
+                       DrawOptions(1.0, CompositionOp::OP_IN));
+  aTarget->SetTransform(origin);
+}
+
 DrawResult
 nsSVGClipPathFrame::PaintClipMask(gfxContext& aMaskContext,
                                   nsIFrame* aClippedFrame,
                                   const gfxMatrix& aMatrix,
                                   Matrix* aMaskTransform,
                                   SourceSurface* aExtraMask,
                                   const Matrix& aExtraMasksTransform)
 {
@@ -177,29 +192,17 @@ nsSVGClipPathFrame::PaintClipMask(gfxCon
     }
   }
 
   // Moz2D transforms in the opposite direction to Thebes
   gfxMatrix maskTransfrom = aMaskContext.CurrentMatrix();
   maskTransfrom.Invert();
 
   if (aExtraMask) {
-    // We could potentially due this more efficiently with OPERATOR_IN
-    // but that operator does not work well on CG or D2D
-    RefPtr<SourceSurface> currentMask = maskDT->Snapshot();
-    IntSize targetSize = maskDT->GetSize();
-    Matrix transform = maskDT->GetTransform();
-    maskDT->SetTransform(Matrix());
-    maskDT->ClearRect(Rect(0, 0, targetSize.width, targetSize.height));
-    maskDT->SetTransform(aExtraMasksTransform * transform);
-    // draw currentMask with the inverse of the transform that we just so that
-    // it ends up in the same spot with aExtraMask transformed by aExtraMasksTransform
-    maskDT->MaskSurface(SurfacePattern(currentMask, ExtendMode::CLAMP, aExtraMasksTransform.Inverse() * ToMatrix(maskTransfrom)),
-                        aExtraMask,
-                        Point(0, 0));
+    ComposeExtraMask(maskDT, maskTransfrom, aExtraMask, aExtraMasksTransform);
   }
 
   *aMaskTransform = ToMatrix(maskTransfrom);
   return result;
 }
 
 DrawResult
 nsSVGClipPathFrame::PaintFrameIntoMask(nsIFrame *aFrame,