Bug 1274236 - Part 1. Simplify function parameters of nsSVGMaskFrame::GetMaskForMaskedFrame. draft
authorcku <cku@mozilla.com>
Tue, 04 Oct 2016 10:47:20 +0800
changeset 420528 213738b1f3983089befaae79f83c5d5f3701d887
parent 420017 955840bfd3c20eb24dd5a01be27bdc55c489a285
child 420529 eacced6b1baa45559cf06f7e3b85fe1e219838cc
push id31224
push userbmo:cku@mozilla.com
push dateTue, 04 Oct 2016 09:01:22 +0000
bugs1274236
milestone52.0a1
Bug 1274236 - Part 1. Simplify function parameters of nsSVGMaskFrame::GetMaskForMaskedFrame. MozReview-Commit-ID: ANRxSAScfLj
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGMaskFrame.cpp
layout/svg/nsSVGMaskFrame.h
layout/svg/nsSVGUtils.cpp
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -505,21 +505,21 @@ GenerateMaskSurface(const PaintFramesPar
   gfxMatrix cssPxToDevPxMatrix =
     nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(aParams.frame);
 
   gfxContext& ctx = aParams.ctx;
 
   // There is only one SVG mask.
   if (((aMaskFrames.Length() == 1) && aMaskFrames[0])) {
     aOpacityApplied = true;
-    aOutMaskSurface =
-      aMaskFrames[0]->GetMaskForMaskedFrame(&ctx, aParams.frame,
-                                            cssPxToDevPxMatrix, aOpacity,
-                                            &aOutMaskTransform,
-                                            svgReset->mMask.mLayers[0].mMaskMode);
+    nsSVGMaskFrame::MaskFrameParams params(&ctx, aParams.frame,
+                                           cssPxToDevPxMatrix, aOpacity,
+                                           &aOutMaskTransform,
+                                           svgReset->mMask.mLayers[0].mMaskMode);
+    aOutMaskSurface = aMaskFrames[0]->GetMaskForMaskedFrame(params);
     return DrawResult::SUCCESS;
   }
 
   IntRect maskSurfaceRect = ComputeMaskGeometry(aParams, svgReset,
                                                 aOffsetToUserSpace,
                                                 aMaskFrames);
   if (maskSurfaceRect.IsEmpty()) {
     return DrawResult::SUCCESS;
@@ -572,22 +572,23 @@ GenerateMaskSurface(const PaintFramesPar
     CompositionOp compositionOp = (i == int(aMaskFrames.Length() - 1))
       ? CompositionOp::OP_OVER
       : nsCSSRendering::GetGFXCompositeMode(svgReset->mMask.mLayers[i].mComposite);
 
     // maskFrame != nullptr means we get a SVG mask.
     // maskFrame == nullptr means we get an image mask.
     if (maskFrame) {
       Matrix svgMaskMatrix;
+      nsSVGMaskFrame::MaskFrameParams params(maskContext, aParams.frame,
+                                           cssPxToDevPxMatrix,
+                                           aOpacityApplied ? aOpacity : 1.0,
+                                           &svgMaskMatrix,
+                                           svgReset->mMask.mLayers[i].mMaskMode);
       RefPtr<SourceSurface> svgMask =
-        maskFrame->GetMaskForMaskedFrame(maskContext, aParams.frame,
-                                         cssPxToDevPxMatrix,
-                                         aOpacityApplied ? aOpacity : 1.0,
-                                         &svgMaskMatrix,
-                                         svgReset->mMask.mLayers[i].mMaskMode);
+        maskFrame->GetMaskForMaskedFrame(params);
       if (svgMask) {
         gfxContextMatrixAutoSaveRestore matRestore(maskContext);
 
         maskContext->Multiply(ThebesMatrix(svgMaskMatrix));
         Rect drawRect = IntRectToRect(IntRect(IntPoint(0, 0), svgMask->GetSize()));
         maskDT->MaskSurface(ColorPattern(Color(0.0, 0.0, 0.0, 1.0)), svgMask,
                             drawRect.TopLeft(),
                             DrawOptions(1.0, compositionOp));
--- a/layout/svg/nsSVGMaskFrame.cpp
+++ b/layout/svg/nsSVGMaskFrame.cpp
@@ -196,68 +196,67 @@ nsIFrame*
 NS_NewSVGMaskFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsSVGMaskFrame(aContext);
 }
 
 NS_IMPL_FRAMEARENA_HELPERS(nsSVGMaskFrame)
 
 already_AddRefed<SourceSurface>
-nsSVGMaskFrame::GetMaskForMaskedFrame(gfxContext* aContext,
-                                      nsIFrame* aMaskedFrame,
-                                      const gfxMatrix &aMatrix,
-                                      float aOpacity,
-                                      Matrix* aMaskTransform,
-                                      uint8_t aMaskOp)
+nsSVGMaskFrame::GetMaskForMaskedFrame(const MaskFrameParams& aParams)
 {
   // If the flag is set when we get here, it means this mask frame
   // has already been used painting the current mask, and the document
   // has a mask reference loop.
   if (mInUse) {
     NS_WARNING("Mask loop detected!");
     return nullptr;
   }
   AutoMaskReferencer maskRef(this);
 
-  gfxRect maskArea = GetMaskArea(aMaskedFrame);
+  gfxRect maskArea = GetMaskArea(aParams.maskedFrame);
+
+  gfxContext* context = aParams.context;
 
   // Get the clip extents in device space:
   // Minimizing the mask surface extents (using both the current clip extents
   // and maskArea) is important for performance.
-  aContext->Save();
-  nsSVGUtils::SetClipRect(aContext, aMatrix, maskArea);
-  aContext->SetMatrix(gfxMatrix());
-  gfxRect maskSurfaceRect = aContext->GetClipExtents();
+  context->Save();
+  nsSVGUtils::SetClipRect(context, aParams.cssPxToDevPxMatrix, maskArea);
+  context->SetMatrix(gfxMatrix());
+  gfxRect maskSurfaceRect = context->GetClipExtents();
   maskSurfaceRect.RoundOut();
-  aContext->Restore();
+  context->Restore();
 
   bool resultOverflows;
   IntSize maskSurfaceSize =
     nsSVGUtils::ConvertToSurfaceSize(maskSurfaceRect.Size(), &resultOverflows);
 
   if (resultOverflows || maskSurfaceSize.IsEmpty()) {
-    // XXXjwatt we should return an empty surface so we don't paint aMaskedFrame!
+    // XXXjwatt we should return an empty surface so we don't paint
+    // aParams.maskedFrame!
     return nullptr;
   }
 
   RefPtr<DrawTarget> maskDT =
     Factory::CreateDrawTarget(BackendType::CAIRO, maskSurfaceSize,
                               SurfaceFormat::B8G8R8A8);
   if (!maskDT || !maskDT->IsValid()) {
     return nullptr;
   }
 
   gfxMatrix maskSurfaceMatrix =
-    aContext->CurrentMatrix() * gfxMatrix::Translation(-maskSurfaceRect.TopLeft());
+    context->CurrentMatrix() * gfxMatrix::Translation(-maskSurfaceRect.TopLeft());
 
   RefPtr<gfxContext> tmpCtx = gfxContext::CreateOrNull(maskDT);
   MOZ_ASSERT(tmpCtx); // already checked the draw target above
   tmpCtx->SetMatrix(maskSurfaceMatrix);
 
-  mMatrixForChildren = GetMaskTransform(aMaskedFrame) * aMatrix;
+  mMatrixForChildren = GetMaskTransform(aParams.maskedFrame) *
+                       aParams.cssPxToDevPxMatrix;
 
   for (nsIFrame* kid = mFrames.FirstChild(); kid;
        kid = kid->GetNextSibling()) {
     // The CTM of each frame referencing us can be different
     nsISVGChildFrame* SVGFrame = do_QueryFrame(kid);
     if (SVGFrame) {
       SVGFrame->NotifySVGChanged(nsISVGChildFrame::TRANSFORM_CHANGED);
     }
@@ -295,49 +294,49 @@ nsSVGMaskFrame::GetMaskForMaskedFrame(gf
   }
   RefPtr<DataSourceSurface> destMaskSurface = destMaskSnapshot->GetDataSurface();
   DataSourceSurface::MappedSurface destMap;
   if (!destMaskSurface->Map(DataSourceSurface::MapType::WRITE, &destMap)) {
     return nullptr;
   }
 
   uint8_t maskType;
-  if (aMaskOp == NS_STYLE_MASK_MODE_MATCH_SOURCE) {
+  if (aParams.maskOp == NS_STYLE_MASK_MODE_MATCH_SOURCE) {
     maskType = StyleSVGReset()->mMaskType;
   } else {
-    maskType = aMaskOp == NS_STYLE_MASK_MODE_LUMINANCE ?
+    maskType = aParams.maskOp == NS_STYLE_MASK_MODE_LUMINANCE ?
                  NS_STYLE_MASK_TYPE_LUMINANCE : NS_STYLE_MASK_TYPE_ALPHA;
   }
 
   if (maskType == NS_STYLE_MASK_TYPE_LUMINANCE) {
     if (StyleSVG()->mColorInterpolation ==
         NS_STYLE_COLOR_INTERPOLATION_LINEARRGB) {
       ComputeLinearRGBLuminanceMask(map.mData, map.mStride,
                                     destMap.mData, destMap.mStride,
-                                    maskSurfaceSize, aOpacity);
+                                    maskSurfaceSize, aParams.opacity);
     } else {
       ComputesRGBLuminanceMask(map.mData, map.mStride,
                                destMap.mData, destMap.mStride,
-                               maskSurfaceSize, aOpacity);
+                               maskSurfaceSize, aParams.opacity);
     }
   } else {
       ComputeAlphaMask(map.mData, map.mStride,
                        destMap.mData, destMap.mStride,
-                       maskSurfaceSize, aOpacity);
+                       maskSurfaceSize, aParams.opacity);
   }
 
   maskSurface->Unmap();
   destMaskSurface->Unmap();
 
   // Moz2D transforms in the opposite direction to Thebes
   if (!maskSurfaceMatrix.Invert()) {
     return nullptr;
   }
 
-  *aMaskTransform = ToMatrix(maskSurfaceMatrix);
+  *(aParams.maskTransform) = ToMatrix(maskSurfaceMatrix);
   return destMaskSurface.forget();
 }
 
 gfxRect
 nsSVGMaskFrame::GetMaskArea(nsIFrame* aMaskedFrame)
 {
   SVGMaskElement *maskElem = static_cast<SVGMaskElement*>(mContent);
 
--- a/layout/svg/nsSVGMaskFrame.h
+++ b/layout/svg/nsSVGMaskFrame.h
@@ -45,24 +45,36 @@ protected:
     , mInUse(false)
   {
     AddStateBits(NS_FRAME_IS_NONDISPLAY);
   }
 
 public:
   NS_DECL_FRAMEARENA_HELPERS
 
+  struct MaskFrameParams {
+    gfxContext* context;
+    nsIFrame* maskedFrame;
+    const gfxMatrix& cssPxToDevPxMatrix;
+    float opacity;
+    Matrix* maskTransform;
+    uint8_t maskOp;
+    MaskFrameParams(gfxContext* aContext, nsIFrame* aMaskedFrame,
+                    const gfxMatrix& aCssPxToDevPxMatrix, float aOpacity,
+                    Matrix* aMaskTransform,
+                    uint8_t aMaskOp= NS_STYLE_MASK_MODE_MATCH_SOURCE)
+      : context(aContext), maskedFrame(aMaskedFrame),
+        cssPxToDevPxMatrix(aCssPxToDevPxMatrix),
+        opacity(opacity), maskTransform(aMaskTransform), maskOp(aMaskOp)
+    {}
+  };
+
   // nsSVGMaskFrame method:
   already_AddRefed<SourceSurface>
-  GetMaskForMaskedFrame(gfxContext* aContext,
-                        nsIFrame* aMaskedFrame,
-                        const gfxMatrix &aMatrix,
-                        float aOpacity,
-                        Matrix* aMaskTransform,
-                        uint8_t aMaskOp = NS_STYLE_MASK_MODE_MATCH_SOURCE);
+  GetMaskForMaskedFrame(const MaskFrameParams& aParams);
 
   gfxRect
   GetMaskArea(nsIFrame* aMaskedFrame);
 
   virtual nsresult AttributeChanged(int32_t         aNameSpaceID,
                                     nsIAtom*        aAttribute,
                                     int32_t         aModType) override;
 
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -592,20 +592,20 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
 
   /* Check if we need to do additional operations on this child's
    * rendering, which necessitates rendering into another surface. */
   if (opacity != 1.0f || maskFrame || (clipPathFrame && !isTrivialClip)
       || aFrame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
     complexEffects = true;
 
     Matrix maskTransform;
+    nsSVGMaskFrame::MaskFrameParams params(&aContext, aFrame, aTransform,
+                                           opacity, &maskTransform);
     RefPtr<SourceSurface> maskSurface =
-      maskFrame ? maskFrame->GetMaskForMaskedFrame(&aContext,
-                                                    aFrame, aTransform, opacity, &maskTransform)
-                : nullptr;
+      maskFrame ? maskFrame->GetMaskForMaskedFrame(params) : nullptr;
 
     if (maskFrame && !maskSurface) {
       // Entire surface is clipped out.
       return DrawResult::SUCCESS;
     }
 
     aContext.Save();
     if (!(aFrame->GetStateBits() & NS_FRAME_IS_NONDISPLAY)) {