Bug 1361593 - Simplify nsSVGMarkerFrame by storing the transform matrix rather than all the parameters necessary to calculate it. r=jwatt
authorRobert Longson <longsonr@gmail.com>
Thu, 08 Jun 2017 06:17:07 +0100
changeset 411056 fd72dc86c01db8ef2035c7aaeccd9758ec9bc8ae
parent 411055 4f29bdedb50c5f60d58e88030cb37c0bec6cfab0
child 411057 82ffae610a03a314544f54d6d79edafb3f0daa7f
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt
bugs1361593
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1361593 - Simplify nsSVGMarkerFrame by storing the transform matrix rather than all the parameters necessary to calculate it. r=jwatt
dom/svg/SVGMarkerElement.cpp
dom/svg/SVGMarkerElement.h
layout/svg/SVGGeometryFrame.cpp
layout/svg/nsSVGMarkerFrame.cpp
layout/svg/nsSVGMarkerFrame.h
--- a/dom/svg/SVGMarkerElement.cpp
+++ b/dom/svg/SVGMarkerElement.cpp
@@ -298,38 +298,37 @@ SVGMarkerElement::GetPreserveAspectRatio
   return &mPreserveAspectRatio;
 }
 
 //----------------------------------------------------------------------
 // public helpers
 
 gfx::Matrix
 SVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
-                                     float aX, float aY, float aAutoAngle,
-                                     bool aIsStart)
+                                     const nsSVGMark& aMark)
 {
   float scale = mEnumAttributes[MARKERUNITS].GetAnimValue() ==
                      SVG_MARKERUNITS_STROKEWIDTH ? aStrokeWidth : 1.0f;
 
   float angle;
   switch (mOrientType.GetAnimValueInternal()) {
     case SVG_MARKER_ORIENT_AUTO:
-      angle = aAutoAngle;
+      angle = aMark.angle;
       break;
     case SVG_MARKER_ORIENT_AUTO_START_REVERSE:
-      angle = aAutoAngle + (aIsStart ? M_PI : 0.0f);
+      angle = aMark.angle + (aMark.type == nsSVGMark::eStart ? M_PI : 0.0f);
       break;
     default: // SVG_MARKER_ORIENT_ANGLE
       angle = mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0f;
       break;
   }
 
   return gfx::Matrix(cos(angle) * scale,   sin(angle) * scale,
                      -sin(angle) * scale,  cos(angle) * scale,
-                     aX,                    aY);
+                     aMark.x,              aMark.y);
 }
 
 nsSVGViewBoxRect
 SVGMarkerElement::GetViewBoxRect()
 {
   if (mViewBox.HasRect()) {
     return mViewBox.GetAnimValue();
   }
--- a/dom/svg/SVGMarkerElement.h
+++ b/dom/svg/SVGMarkerElement.h
@@ -13,16 +13,17 @@
 #include "nsSVGLength2.h"
 #include "nsSVGViewBox.h"
 #include "SVGAnimatedPreserveAspectRatio.h"
 #include "nsSVGElement.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/SVGAnimatedEnumeration.h"
 
 class nsSVGMarkerFrame;
+struct nsSVGMark;
 
 nsresult NS_NewSVGMarkerElement(nsIContent **aResult,
                                 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
 
 namespace mozilla {
 namespace dom {
 
 // Marker Unit Types
@@ -116,19 +117,17 @@ public:
 
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
                              bool aNotify) override;
 
   // nsSVGSVGElement methods:
   virtual bool HasValidDimensions() const override;
 
   // public helpers
-  gfx::Matrix GetMarkerTransform(float aStrokeWidth,
-                                 float aX, float aY, float aAutoAngle,
-                                 bool aIsStart);
+  gfx::Matrix GetMarkerTransform(float aStrokeWidth, const nsSVGMark& aMark);
   nsSVGViewBoxRect GetViewBoxRect();
   gfx::Matrix GetViewBoxTransform();
 
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
                          bool aPreallocateChildren) const override;
 
   nsSVGOrientType* GetOrientType() { return &mOrientType; }
 
--- a/layout/svg/SVGGeometryFrame.cpp
+++ b/layout/svg/SVGGeometryFrame.cpp
@@ -663,22 +663,22 @@ SVGGeometryFrame::GetBBoxContribution(co
         properties.GetMarkerStartFrame(),
         properties.GetMarkerMidFrame(),
         properties.GetMarkerEndFrame(),
       };
       static_assert(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount,
                     "Number of Marker frames should be equal to eTypeCount");
 
       for (uint32_t i = 0; i < num; i++) {
-        nsSVGMark& mark = marks[i];
+        const nsSVGMark& mark = marks[i];
         nsSVGMarkerFrame* frame = markerFrames[mark.type];
         if (frame) {
           SVGBBox mbbox =
             frame->GetMarkBBoxContribution(aToBBoxUserspace, aFlags, this,
-                                           &marks[i], strokeWidth);
+                                           mark, strokeWidth);
           MOZ_ASSERT(mbbox.IsFinite(), "bbox is about to go bad");
           bbox.UnionEdges(mbbox);
         }
       }
     }
   }
 
   return bbox;
@@ -891,20 +891,20 @@ SVGGeometryFrame::PaintMarkers(gfxContex
           properties.GetMarkerStartFrame(),
           properties.GetMarkerMidFrame(),
           properties.GetMarkerEndFrame(),
         };
         static_assert(MOZ_ARRAY_LENGTH(markerFrames) == nsSVGMark::eTypeCount,
                       "Number of Marker frames should be equal to eTypeCount");
 
         for (uint32_t i = 0; i < num; i++) {
-          nsSVGMark& mark = marks[i];
+          const nsSVGMark& mark = marks[i];
           nsSVGMarkerFrame* frame = markerFrames[mark.type];
           if (frame) {
-            frame->PaintMark(aContext, aTransform, this, &mark, strokeWidth,
+            frame->PaintMark(aContext, aTransform, this, mark, strokeWidth,
                              aImgParams);
           }
         }
       }
     }
   }
 }
 
--- a/layout/svg/nsSVGMarkerFrame.cpp
+++ b/layout/svg/nsSVGMarkerFrame.cpp
@@ -75,37 +75,35 @@ nsSVGMarkerFrame::GetCanvasTM()
   }
 
   SVGMarkerElement *content = static_cast<SVGMarkerElement*>(mContent);
   
   mInUse2 = true;
   gfxMatrix markedTM = mMarkedFrame->GetCanvasTM();
   mInUse2 = false;
 
-  Matrix markerTM = content->GetMarkerTransform(mStrokeWidth, mX, mY,
-                                                mAutoAngle, mIsStart);
   Matrix viewBoxTM = content->GetViewBoxTransform();
 
-  return ThebesMatrix(viewBoxTM * markerTM) * markedTM;
+  return ThebesMatrix(viewBoxTM * mMarkerTM) * markedTM;
 }
 
 static nsIFrame*
 GetAnonymousChildFrame(nsIFrame* aFrame)
 {
   nsIFrame* kid = aFrame->PrincipalChildList().FirstChild();
   MOZ_ASSERT(kid && kid->IsSVGMarkerAnonChildFrame(),
              "expected to find anonymous child of marker frame");
   return kid;
 }
 
 void
 nsSVGMarkerFrame::PaintMark(gfxContext& aContext,
                             const gfxMatrix& aToMarkedFrameUserSpace,
-                            SVGGeometryFrame *aMarkedFrame,
-                            nsSVGMark *aMark, float aStrokeWidth,
+                            SVGGeometryFrame* aMarkedFrame,
+                            const nsSVGMark& aMark, float aStrokeWidth,
                             imgDrawingParams& aImgParams)
 {
   // If the flag is set when we get here, it means this marker frame
   // has already been used painting the current mark, and the document
   // has a marker reference loop.
   if (mInUse) {
     return;
   }
@@ -119,28 +117,21 @@ nsSVGMarkerFrame::PaintMark(gfxContext& 
 
   const nsSVGViewBoxRect viewBox = marker->GetViewBoxRect();
 
   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
     // We must disable rendering if the viewBox width or height are zero.
     return;
   }
 
-  mStrokeWidth = aStrokeWidth;
-  mX = aMark->x;
-  mY = aMark->y;
-  mAutoAngle = aMark->angle;
-  mIsStart = aMark->type == nsSVGMark::eStart;
-
   Matrix viewBoxTM = marker->GetViewBoxTransform();
 
-  Matrix markerTM = marker->GetMarkerTransform(mStrokeWidth, mX, mY,
-                                               mAutoAngle, mIsStart);
+  mMarkerTM = marker->GetMarkerTransform(aStrokeWidth, aMark);
 
-  gfxMatrix markTM = ThebesMatrix(viewBoxTM) * ThebesMatrix(markerTM) *
+  gfxMatrix markTM = ThebesMatrix(viewBoxTM) * ThebesMatrix(mMarkerTM) *
                      aToMarkedFrameUserSpace;
 
   if (StyleDisplay()->IsScrollableOverflow()) {
     aContext.Save();
     gfxRect clipRect =
       nsSVGUtils::GetClipRectForFrame(this, viewBox.x, viewBox.y,
                                       viewBox.width, viewBox.height);
     nsSVGUtils::SetClipRect(&aContext, markTM, clipRect);
@@ -153,20 +144,20 @@ nsSVGMarkerFrame::PaintMark(gfxContext& 
   SVGFrame->NotifySVGChanged(nsSVGDisplayableFrame::TRANSFORM_CHANGED);
   nsSVGUtils::PaintFrameWithEffects(kid, aContext, markTM, aImgParams);
 
   if (StyleDisplay()->IsScrollableOverflow())
     aContext.Restore();
 }
 
 SVGBBox
-nsSVGMarkerFrame::GetMarkBBoxContribution(const Matrix &aToBBoxUserspace,
+nsSVGMarkerFrame::GetMarkBBoxContribution(const Matrix& aToBBoxUserspace,
                                           uint32_t aFlags,
-                                          SVGGeometryFrame *aMarkedFrame,
-                                          const nsSVGMark *aMark,
+                                          SVGGeometryFrame* aMarkedFrame,
+                                          const nsSVGMark& aMark,
                                           float aStrokeWidth)
 {
   SVGBBox bbox;
 
   // If the flag is set when we get here, it means this marker frame
   // has already been used in calculating the current mark bbox, and
   // the document has a marker reference loop.
   if (mInUse)
@@ -180,27 +171,20 @@ nsSVGMarkerFrame::GetMarkBBoxContributio
   }
 
   const nsSVGViewBoxRect viewBox = content->GetViewBoxRect();
 
   if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
     return bbox;
   }
 
-  mStrokeWidth = aStrokeWidth;
-  mX = aMark->x;
-  mY = aMark->y;
-  mAutoAngle = aMark->angle;
-  mIsStart = aMark->type == nsSVGMark::eStart;
-
-  Matrix markerTM =
-    content->GetMarkerTransform(mStrokeWidth, mX, mY, mAutoAngle, mIsStart);
+  mMarkerTM = content->GetMarkerTransform(aStrokeWidth, aMark);
   Matrix viewBoxTM = content->GetViewBoxTransform();
 
-  Matrix tm = viewBoxTM * markerTM * aToBBoxUserspace;
+  Matrix tm = viewBoxTM * mMarkerTM * aToBBoxUserspace;
 
   nsSVGDisplayableFrame* child = do_QueryFrame(GetAnonymousChildFrame(this));
   // When we're being called to obtain the invalidation area, we need to
   // pass down all the flags so that stroke is included. However, once DOM
   // getBBox() accepts flags, maybe we should strip some of those here?
 
   // We need to include zero width/height vertical/horizontal lines, so we have
   // to use UnionEdges.
--- a/layout/svg/nsSVGMarkerFrame.h
+++ b/layout/svg/nsSVGMarkerFrame.h
@@ -74,37 +74,36 @@ public:
                PrincipalChildList().FirstChild()->IsSVGMarkerAnonChildFrame(),
                "Where is our anonymous child?");
     return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
   }
 
   // nsSVGMarkerFrame methods:
   void PaintMark(gfxContext& aContext,
                  const gfxMatrix& aToMarkedFrameUserSpace,
-                 mozilla::SVGGeometryFrame *aMarkedFrame,
-                 nsSVGMark *aMark,
+                 mozilla::SVGGeometryFrame* aMarkedFrame,
+                 const nsSVGMark& aMark,
                  float aStrokeWidth,
                  imgDrawingParams& aImgParams);
 
-  SVGBBox GetMarkBBoxContribution(const Matrix &aToBBoxUserspace,
+  SVGBBox GetMarkBBoxContribution(const Matrix& aToBBoxUserspace,
                                   uint32_t aFlags,
-                                  mozilla::SVGGeometryFrame *aMarkedFrame,
-                                  const nsSVGMark *aMark,
+                                  mozilla::SVGGeometryFrame* aMarkedFrame,
+                                  const nsSVGMark& aMark,
                                   float aStrokeWidth);
 
   // Update the style on our anonymous box child.
   void DoUpdateStyleOfOwnedAnonBoxes(mozilla::ServoStyleSet& aStyleSet,
                                      nsStyleChangeList& aChangeList,
                                      nsChangeHint aHintForThisFrame) override;
 
 private:
   // stuff needed for callback
   mozilla::SVGGeometryFrame *mMarkedFrame;
-  float mStrokeWidth, mX, mY, mAutoAngle;
-  bool mIsStart;  // whether the callback is for a marker-start marker
+  Matrix mMarkerTM;
 
   // nsSVGContainerFrame methods:
   virtual gfxMatrix GetCanvasTM() override;
 
   // A helper class to allow us to paint markers safely. The helper
   // automatically sets and clears the mInUse flag on the marker frame (to
   // prevent nasty reference loops) as well as the reference to the marked
   // frame and its coordinate context. It's easy to mess this up