Bug 1385239 - Part 1. Pass gfxContext, instead of DrawTarget, into nsFilterInstance::PaintFilteredFrame. draft
authorcku <cku@mozilla.com>
Fri, 25 Aug 2017 16:33:33 +0800
changeset 662746 a9a5f3f5b9e5d84f1e35ab99fb6e68b3aeb9b011
parent 662738 bda524beac249b64aa36016800502a34073bf35a
child 662747 063987f16a399ca2489f52969ca5f7a96ade76c7
push id79187
push userbmo:cku@mozilla.com
push dateTue, 12 Sep 2017 03:20:38 +0000
bugs1385239
milestone57.0a1
Bug 1385239 - Part 1. Pass gfxContext, instead of DrawTarget, into nsFilterInstance::PaintFilteredFrame. This change makes the next patch free of doing Matrix to gfxMatrix conversion. MozReview-Commit-ID: 8K9RNgjZPTw
layout/svg/nsFilterInstance.cpp
layout/svg/nsFilterInstance.h
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGUtils.cpp
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -56,32 +56,32 @@ UserSpaceMetricsForFrame(nsIFrame* aFram
     nsSVGElement* element = static_cast<nsSVGElement*>(aFrame->GetContent());
     return MakeUnique<SVGElementMetrics>(element);
   }
   return MakeUnique<NonSVGFrameUserSpaceMetrics>(aFrame);
 }
 
 void
 nsFilterInstance::PaintFilteredFrame(nsIFrame *aFilteredFrame,
-                                     DrawTarget* aDrawTarget,
+                                     gfxContext* aCtx,
                                      const gfxMatrix& aTransform,
                                      nsSVGFilterPaintCallback *aPaintCallback,
                                      const nsRegion *aDirtyArea,
                                      imgDrawingParams& aImgParams)
 {
   auto& filterChain = aFilteredFrame->StyleEffects()->mFilters;
   UniquePtr<UserSpaceMetrics> metrics = UserSpaceMetricsForFrame(aFilteredFrame);
   // Hardcode InputIsTainted to true because we don't want JS to be able to
   // read the rendered contents of aFilteredFrame.
   nsFilterInstance instance(aFilteredFrame, aFilteredFrame->GetContent(),
                             *metrics, filterChain, /* InputIsTainted */ true,
                             aPaintCallback, aTransform, aDirtyArea, nullptr,
                             nullptr, nullptr);
   if (instance.IsInitialized()) {
-    instance.Render(aDrawTarget, aImgParams);
+    instance.Render(aCtx, aImgParams);
   }
 }
 
 nsRegion
 nsFilterInstance::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame,
                                          const nsRegion& aPreFilterDirtyRegion)
 {
   if (aPreFilterDirtyRegion.IsEmpty()) {
@@ -468,43 +468,41 @@ nsFilterInstance::BuildSourceImage(imgDr
 
   mPaintCallback->Paint(*ctx, mTargetFrame, mPaintTransform, &dirty, aImgParams);
 
   mSourceGraphic.mSourceSurface = offscreenDT->Snapshot();
   mSourceGraphic.mSurfaceRect = neededRect;
 }
 
 void
-nsFilterInstance::Render(DrawTarget* aDrawTarget, imgDrawingParams& aImgParams)
+nsFilterInstance::Render(gfxContext* aCtx, imgDrawingParams& aImgParams)
 {
   MOZ_ASSERT(mTargetFrame, "Need a frame for rendering");
 
   if (mPrimitiveDescriptions.IsEmpty()) {
     // An filter without any primitive. Treat it as success and paint nothing.
     return;
   }
 
   nsIntRect filterRect =
     mPostFilterDirtyRegion.GetBounds().Intersect(OutputFilterSpaceBounds());
   if (filterRect.IsEmpty() || mPaintTransform.IsSingular()) {
     return;
   }
 
-  AutoRestoreTransform autoRestoreTransform(aDrawTarget);
-  Matrix newTM =
-    aDrawTarget->GetTransform().PreTranslate(filterRect.x, filterRect.y);
-  aDrawTarget->SetTransform(newTM);
+  gfxContextMatrixAutoSaveRestore autoSR(aCtx);
+  aCtx->SetMatrix(aCtx->CurrentMatrix().PreTranslate(filterRect.x, filterRect.y));
 
   ComputeNeededBoxes();
 
   BuildSourceImage(aImgParams);
   BuildSourcePaints(aImgParams);
 
   FilterSupport::RenderFilterDescription(
-    aDrawTarget, mFilterDescription, IntRectToRect(filterRect),
+    aCtx->GetDrawTarget(), mFilterDescription, IntRectToRect(filterRect),
     mSourceGraphic.mSourceSurface, mSourceGraphic.mSurfaceRect,
     mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect,
     mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect,
     mInputImages, Point(0, 0));
 }
 
 nsRegion
 nsFilterInstance::ComputePostFilterDirtyRegion()
--- a/layout/svg/nsFilterInstance.h
+++ b/layout/svg/nsFilterInstance.h
@@ -79,17 +79,17 @@ public:
 
   /**
    * Paint the given filtered frame.
    * @param aDirtyArea The area than needs to be painted, in aFilteredFrame's
    *   frame space (i.e. relative to its origin, the top-left corner of its
    *   border box).
    */
   static void PaintFilteredFrame(nsIFrame *aFilteredFrame,
-                                 DrawTarget* aDrawTarget,
+                                 gfxContext* aCtx,
                                  const gfxMatrix& aTransform,
                                  nsSVGFilterPaintCallback *aPaintCallback,
                                  const nsRegion* aDirtyArea,
                                  imgDrawingParams& aImgParams);
 
   /**
    * Returns the post-filter area that could be dirtied when the given
    * pre-filter area of aFilteredFrame changes.
@@ -163,17 +163,17 @@ private:
   bool IsInitialized() const { return mInitialized; }
 
   /**
    * Draws the filter output into aDrawTarget. The area that
    * needs to be painted must have been specified before calling this method
    * by passing it as the aPostFilterDirtyRegion argument to the
    * nsFilterInstance constructor.
    */
-  void Render(DrawTarget* aDrawTarget, imgDrawingParams& aImgParams);
+  void Render(gfxContext* aCtx, imgDrawingParams& aImgParams);
 
   const FilterDescription& ExtractDescriptionAndAdditionalImages(nsTArray<RefPtr<SourceSurface>>& aOutAdditionalImages)
   {
     mInputImages.SwapElements(aOutAdditionalImages);
     return mFilterDescription;
   }
 
   /**
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -1100,17 +1100,17 @@ nsSVGIntegrationUtils::PaintFilter(const
                         0.0f, 0.0f);
   gfxMatrix reverseScaleMatrix = scaleMatrix;
   DebugOnly<bool> invertible = reverseScaleMatrix.Invert();
   MOZ_ASSERT(invertible);
   context.SetMatrix(reverseScaleMatrix * context.CurrentMatrix());
 
   gfxMatrix tm =
     scaleMatrix * nsSVGUtils::GetCSSPxToDevPxMatrix(frame);
-  nsFilterInstance::PaintFilteredFrame(frame, context.GetDrawTarget(),
+  nsFilterInstance::PaintFilteredFrame(frame, &context,
                                        tm, &callback, &dirtyRegion,
                                        aParams.imgParams);
 
   if (opacity != 1.0f) {
     context.PopGroupAndBlend();
   }
 }
 
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -849,17 +849,17 @@ nsSVGUtils::PaintFrameWithEffects(nsIFra
       tmpDirtyRegion =
         nsLayoutUtils::RoundGfxRectToAppRect(
           dirtyBounds, aFrame->PresContext()->AppUnitsPerCSSPixel()) -
         aFrame->GetPosition();
       dirtyRegion = &tmpDirtyRegion;
     }
 
     SVGPaintCallback paintCallback;
-    nsFilterInstance::PaintFilteredFrame(aFrame, target->GetDrawTarget(),
+    nsFilterInstance::PaintFilteredFrame(aFrame, target,
                                          aTransform, &paintCallback,
                                          dirtyRegion, aImgParams);
   } else {
      svgFrame->PaintSVG(*target, aTransform, aImgParams, aDirtyRect);
   }
 
   if (maskUsage.shouldApplyClipPath || maskUsage.shouldApplyBasicShape) {
     aContext.PopClip();