Bug 813531 - Part 2: Stop reconstructing the entire SVG frame tree after the initial reflow of nsSVGOuterSVGFrame frames that have a viewBox. r=roc.
authorJonathan Watt <jwatt@jwatt.org>
Tue, 18 Dec 2012 02:25:16 +0000
changeset 125477 d622ae0a8a23bc65cfb86b6fb860c30ebf3180be
parent 125476 55b179e8c9805bf3d0d3d59e1f87f867a9e7b92e
child 125478 d433d1a9fd78fa6a78931cd82595294d75be2d25
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs813531
milestone20.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 813531 - Part 2: Stop reconstructing the entire SVG frame tree after the initial reflow of nsSVGOuterSVGFrame frames that have a viewBox. r=roc.
content/svg/content/src/nsSVGSVGElement.cpp
content/svg/content/src/nsSVGSVGElement.h
layout/svg/nsSVGOuterSVGFrame.cpp
--- a/content/svg/content/src/nsSVGSVGElement.cpp
+++ b/content/svg/content/src/nsSVGSVGElement.cpp
@@ -912,31 +912,42 @@ nsSVGSVGElement::GetViewBoxTransform() c
   return SVGContentUtils::GetViewBoxTransform(this,
                                               viewportWidth, viewportHeight,
                                               viewBox.x, viewBox.y,
                                               viewBox.width, viewBox.height,
                                               GetPreserveAspectRatioWithOverride());
 }
 
 void
+nsSVGSVGElement::UpdateHasChildrenOnlyTransform()
+{
+  bool hasChildrenOnlyTransform =
+    HasViewBoxOrSyntheticViewBox() ||
+    (IsRoot() && (mCurrentTranslate != nsSVGTranslatePoint(0.0f, 0.0f) ||
+                  mCurrentScale != 1.0f));
+  mHasChildrenOnlyTransform = hasChildrenOnlyTransform;
+}
+
+void
 nsSVGSVGElement::ChildrenOnlyTransformChanged(uint32_t aFlags)
 {
   // Avoid wasteful calls:
   NS_ABORT_IF_FALSE(!(GetPrimaryFrame()->GetStateBits() &
                       NS_STATE_SVG_NONDISPLAY_CHILD),
                     "Non-display SVG frames don't maintain overflow rects");
 
   nsChangeHint changeHint;
 
-  bool hasChildrenOnlyTransform = HasViewBoxOrSyntheticViewBox() ||
-    (IsRoot() && (mCurrentTranslate != nsSVGTranslatePoint(0.0f, 0.0f) ||
-                  mCurrentScale != 1.0f));
+  bool hadChildrenOnlyTransform = mHasChildrenOnlyTransform;
+
+  UpdateHasChildrenOnlyTransform();
 
-  if (hasChildrenOnlyTransform != mHasChildrenOnlyTransform) {
+  if (hadChildrenOnlyTransform != mHasChildrenOnlyTransform) {
     // Reconstruct the frame tree to handle stacking context changes:
+    // XXXjwatt don't do this for root-<svg> or even outer-<svg>?
     changeHint = nsChangeHint_ReconstructFrame;
   } else {
     // We just assume the old and new transforms are different.
     changeHint = nsChangeHint(nsChangeHint_RepaintFrame |
                    nsChangeHint_UpdateOverflow |
                    nsChangeHint_ChildrenOnlyTransform);
   }
 
@@ -944,18 +955,16 @@ nsSVGSVGElement::ChildrenOnlyTransformCh
   // PostRestyleEvent if we're not being called under reflow to avoid recursing
   // to death. See bug 767056 comments 10 and 12. Since our nsSVGOuterSVGFrame
   // is being reflowed we're going to invalidate and repaint its entire area
   // anyway (which will include our children).
   if ((changeHint & nsChangeHint_ReconstructFrame) ||
       !(aFlags & eDuringReflow)) {
     nsLayoutUtils::PostRestyleEvent(this, nsRestyleHint(0), changeHint);
   }
-
-  mHasChildrenOnlyTransform = hasChildrenOnlyTransform;
 }
 
 nsresult
 nsSVGSVGElement::BindToTree(nsIDocument* aDocument,
                             nsIContent* aParent,
                             nsIContent* aBindingParent,
                             bool aCompileEventHandlers)
 {
--- a/content/svg/content/src/nsSVGSVGElement.h
+++ b/content/svg/content/src/nsSVGSVGElement.h
@@ -205,16 +205,18 @@ public:
   }
 
   gfxMatrix GetViewBoxTransform() const;
 
   bool HasChildrenOnlyTransform() const {
     return mHasChildrenOnlyTransform;
   }
 
+  void UpdateHasChildrenOnlyTransform();
+
   enum ChildrenOnlyTransformChangedFlags {
     eDuringReflow = 1
   };
 
   /**
    * This method notifies the style system that the overflow rects of our
    * immediate childrens' frames need to be updated. It is called by our own
    * frame when changes (e.g. to currentScale) cause our children-only
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -409,18 +409,17 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext
 
   nsSVGSVGElement *svgElem = static_cast<nsSVGSVGElement*>(mContent);
 
   nsSVGOuterSVGAnonChildFrame *anonKid =
     static_cast<nsSVGOuterSVGAnonChildFrame*>(GetFirstPrincipalChild());
 
   if (mState & NS_FRAME_FIRST_REFLOW) {
     // Initialize
-    svgElem->mHasChildrenOnlyTransform =
-      anonKid->HasChildrenOnlyTransform(nullptr);
+    svgElem->UpdateHasChildrenOnlyTransform();
   }
 
   // If our SVG viewport has changed, update our content and notify.
   // http://www.w3.org/TR/SVG11/coords.html#ViewportSpace
 
   svgFloatSize newViewportSize(
     nsPresContext::AppUnitsToFloatCSSPixels(aReflowState.ComputedWidth()),
     nsPresContext::AppUnitsToFloatCSSPixels(aReflowState.ComputedHeight()));
@@ -446,20 +445,20 @@ nsSVGOuterSVGFrame::Reflow(nsPresContext
     }
     changeBits |= COORD_CONTEXT_CHANGED;
     svgElem->SetViewportSize(newViewportSize);
   }
   if (mFullZoom != PresContext()->GetFullZoom()) {
     changeBits |= FULL_ZOOM_CHANGED;
     mFullZoom = PresContext()->GetFullZoom();
   }
-  mViewportInitialized = true;
   if (changeBits) {
     NotifyViewportOrTransformChanged(changeBits);
   }
+  mViewportInitialized = true;
 
   if (!(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
     // Now that we've marked the necessary children as dirty, call
     // ReflowSVG() on them:
 
     mCallingReflowSVG = true;
 
     // Update the mRects and visual overflow rects of all our descendants,