Bug 864832 - Get rid of the majority of the remaining nsSVGUtils::InvalidateBounds calls, except for those related to transforms and nsSVGTextFrame2. r=mattwoodrow
authorJonathan Watt <jwatt@jwatt.org>
Thu, 25 Apr 2013 10:18:42 +0100
changeset 129851 96c350f2c64a03a58907ef13ddaa88fad16aee9f
parent 129850 78bdcb813be1cffebeb33a4f87b6eb8073ec3a1e
child 129852 9c11cfae5a695788d309d9b650aa5264ccc6b009
push id1550
push userttaubert@mozilla.com
push dateFri, 26 Apr 2013 12:46:41 +0000
treeherderfx-team@d360244c69ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs864832
milestone23.0a1
Bug 864832 - Get rid of the majority of the remaining nsSVGUtils::InvalidateBounds calls, except for those related to transforms and nsSVGTextFrame2. r=mattwoodrow
content/svg/content/src/SVGSwitchElement.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/svg/nsSVGForeignObjectFrame.cpp
layout/svg/nsSVGGlyphFrame.cpp
layout/svg/nsSVGImageFrame.cpp
layout/svg/nsSVGInnerSVGFrame.cpp
layout/svg/nsSVGPathGeometryFrame.cpp
layout/svg/nsSVGTSpanFrame.cpp
layout/svg/nsSVGTextFrame.cpp
layout/svg/nsSVGTextPathFrame.cpp
layout/svg/nsSVGUseFrame.cpp
--- a/content/svg/content/src/SVGSwitchElement.cpp
+++ b/content/svg/content/src/SVGSwitchElement.cpp
@@ -1,14 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/SVGSwitchElement.h"
+
+#include "nsSVGEffects.h"
 #include "nsSVGUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/SVGSwitchElementBinding.h"
 
 class nsIFrame;
 
 NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Switch)
 
@@ -59,17 +61,17 @@ SVGSwitchElement::MaybeInvalidate()
   nsIContent *newActiveChild = FindActiveChild();
 
   if (newActiveChild == mActiveChild) {
     return;
   }
 
   nsIFrame *frame = GetPrimaryFrame();
   if (frame) {
-    nsSVGUtils::InvalidateBounds(frame, false);
+    nsSVGEffects::InvalidateRenderingObservers(frame);
     nsSVGUtils::ScheduleReflowSVG(frame);
   }
 
   mActiveChild = newActiveChild;
 }
 
 //----------------------------------------------------------------------
 // nsIDOMNode methods
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -7723,18 +7723,18 @@ DoApplyRenderingChangeToTree(nsIFrame* a
     bool needInvalidatingPaint = false;
 
     // if frame has view, will already be invalidated
     if (aChange & nsChangeHint_RepaintFrame) {
       if (aFrame->IsFrameOfType(nsIFrame::eSVG) &&
           !(aFrame->GetStateBits() & NS_STATE_IS_OUTER_SVG)) {
         if (aChange & nsChangeHint_UpdateEffects) {
           needInvalidatingPaint = true;
-          // Invalidate and update our area:
-          nsSVGUtils::InvalidateBounds(aFrame, false);
+          nsSVGEffects::InvalidateRenderingObservers(aFrame);
+          // Need to update our overflow rects:
           nsSVGUtils::ScheduleReflowSVG(aFrame);
         } else {
           needInvalidatingPaint = true;
           // Just invalidate our area:
           nsSVGEffects::InvalidateRenderingObservers(aFrame);
           aFrame->InvalidateFrameSubtree();
         }
       } else {
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -88,30 +88,34 @@ nsSVGForeignObjectFrame::GetType() const
 NS_IMETHODIMP
 nsSVGForeignObjectFrame::AttributeChanged(int32_t  aNameSpaceID,
                                           nsIAtom *aAttribute,
                                           int32_t  aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::width ||
         aAttribute == nsGkAtoms::height) {
-      nsSVGUtils::InvalidateBounds(this, false);
+      nsSVGEffects::InvalidateRenderingObservers(this);
       nsSVGUtils::ScheduleReflowSVG(this);
       // XXXjwatt: why mark intrinsic widths dirty? can't we just use eResize?
       RequestReflow(nsIPresShell::eStyleChange);
     } else if (aAttribute == nsGkAtoms::x ||
-               aAttribute == nsGkAtoms::y ||
-               aAttribute == nsGkAtoms::transform) {
+               aAttribute == nsGkAtoms::y) {
+      // make sure our cached transform matrix gets (lazily) updated
+      mCanvasTM = nullptr;
+      nsSVGEffects::InvalidateRenderingObservers(this);
+      nsSVGUtils::ScheduleReflowSVG(this);
+    } else if (aAttribute == nsGkAtoms::transform) {
       // make sure our cached transform matrix gets (lazily) updated
       mCanvasTM = nullptr;
       nsSVGUtils::InvalidateBounds(this, false);
       nsSVGUtils::ScheduleReflowSVG(this);
     } else if (aAttribute == nsGkAtoms::viewBox ||
                aAttribute == nsGkAtoms::preserveAspectRatio) {
-      nsSVGUtils::InvalidateBounds(this);
+      nsSVGEffects::InvalidateRenderingObservers(this);
     }
   }
 
   return NS_OK;
 }
 
 /* virtual */ void
 nsSVGForeignObjectFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
@@ -120,17 +124,17 @@ nsSVGForeignObjectFrame::DidSetStyleCont
 
   // No need to invalidate before first reflow - that will happen elsewhere.
   // Moreover we haven't been initialised properly yet so we may not have the
   // right state bits.
   if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     // XXXperf: probably only need a bounds update if 'font-size' changed and
     // we have em unit width/height. Or, once we map 'transform' into style,
     // if some transform property changed.
-    nsSVGUtils::InvalidateBounds(this, false);
+    nsSVGEffects::InvalidateRenderingObservers(this);
     nsSVGUtils::ScheduleReflowSVG(this);
   }
 }
 
 NS_IMETHODIMP
 nsSVGForeignObjectFrame::Reflow(nsPresContext*           aPresContext,
                                 nsHTMLReflowMetrics&     aDesiredSize,
                                 const nsHTMLReflowState& aReflowState,
--- a/layout/svg/nsSVGGlyphFrame.cpp
+++ b/layout/svg/nsSVGGlyphFrame.cpp
@@ -285,17 +285,17 @@ nsSVGGlyphFrame::CharacterDataChanged(Ch
   NotifyGlyphMetricsChange();
 
   ClearTextRun();
   if (IsTextEmpty()) {
     // The one time that NotifyGlyphMetricsChange fails to call
     // nsSVGUtils::InvalidateAndScheduleBoundsUpdate properly is when all our
     // text is gone, since it skips empty frames. So we have to invalidate
     // ourself.
-    nsSVGUtils::InvalidateBounds(this);
+    nsSVGEffects::InvalidateRenderingObservers(this);
   }
 
   return NS_OK;
 }
 
 // Usable font size range in devpixels / user-units
 #define CLAMP_MIN_SIZE 8
 #define CLAMP_MAX_SIZE 200
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -179,17 +179,17 @@ nsSVGImageFrame::AttributeChanged(int32_
                                   nsIAtom*        aAttribute,
                                   int32_t         aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::x ||
         aAttribute == nsGkAtoms::y ||
         aAttribute == nsGkAtoms::width ||
         aAttribute == nsGkAtoms::height) {
-      nsSVGUtils::InvalidateBounds(this, false);
+      nsSVGEffects::InvalidateRenderingObservers(this);
       nsSVGUtils::ScheduleReflowSVG(this);
       return NS_OK;
     }
     else if (aAttribute == nsGkAtoms::preserveAspectRatio) {
       nsSVGUtils::InvalidateBounds(this);
       return NS_OK;
     }
   }
@@ -554,29 +554,28 @@ nsSVGImageListener::nsSVGImageListener(n
 
 NS_IMETHODIMP
 nsSVGImageListener::Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData)
 {
   if (!mFrame)
     return NS_ERROR_FAILURE;
 
   if (aType == imgINotificationObserver::LOAD_COMPLETE) {
-    nsSVGUtils::InvalidateBounds(mFrame, false);
+    nsSVGEffects::InvalidateRenderingObservers(mFrame);
     nsSVGUtils::ScheduleReflowSVG(mFrame);
   }
 
   if (aType == imgINotificationObserver::FRAME_UPDATE) {
     // No new dimensions, so we don't need to call
     // nsSVGUtils::InvalidateAndScheduleBoundsUpdate.
     nsSVGEffects::InvalidateRenderingObservers(mFrame);
-    nsSVGUtils::InvalidateBounds(mFrame);
   }
 
   if (aType == imgINotificationObserver::SIZE_AVAILABLE) {
     // Called once the resource's dimensions have been obtained.
     aRequest->GetImage(getter_AddRefs(mFrame->mImageContainer));
-    nsSVGUtils::InvalidateBounds(mFrame, false);
+    nsSVGEffects::InvalidateRenderingObservers(mFrame);
     nsSVGUtils::ScheduleReflowSVG(mFrame);
   }
 
   return NS_OK;
 }
 
--- a/layout/svg/nsSVGInnerSVGFrame.cpp
+++ b/layout/svg/nsSVGInnerSVGFrame.cpp
@@ -7,16 +7,17 @@
 #include "nsSVGInnerSVGFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxContext.h"
 #include "nsIFrame.h"
 #include "nsISVGChildFrame.h"
 #include "nsRenderingContext.h"
 #include "nsSVGContainerFrame.h"
+#include "nsSVGEffects.h"
 #include "nsSVGIntegrationUtils.h"
 #include "mozilla/dom/SVGSVGElement.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsIFrame*
 NS_NewSVGInnerSVGFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -167,17 +168,17 @@ nsSVGInnerSVGFrame::AttributeChanged(int
 {
   if (aNameSpaceID == kNameSpaceID_None &&
       !(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) {
 
     SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
 
     if (aAttribute == nsGkAtoms::width ||
         aAttribute == nsGkAtoms::height) {
-      nsSVGUtils::InvalidateBounds(this, false);
+      nsSVGEffects::InvalidateRenderingObservers(this);
       nsSVGUtils::ScheduleReflowSVG(this);
 
       if (content->HasViewBoxOrSyntheticViewBox()) {
         // make sure our cached transform matrix gets (lazily) updated
         mCanvasTM = nullptr;
         content->ChildrenOnlyTransformChanged();
         nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
       } else {
@@ -192,26 +193,31 @@ nsSVGInnerSVGFrame::AttributeChanged(int
     } else if (aAttribute == nsGkAtoms::transform ||
                aAttribute == nsGkAtoms::preserveAspectRatio ||
                aAttribute == nsGkAtoms::viewBox ||
                aAttribute == nsGkAtoms::x ||
                aAttribute == nsGkAtoms::y) {
       // make sure our cached transform matrix gets (lazily) updated
       mCanvasTM = nullptr;
 
-      nsSVGUtils::InvalidateBounds(this, false);
-      nsSVGUtils::ScheduleReflowSVG(this);
-
       nsSVGUtils::NotifyChildrenOfSVGChange(
           this, aAttribute == nsGkAtoms::viewBox ?
                   TRANSFORM_CHANGED | COORD_CONTEXT_CHANGED : TRANSFORM_CHANGED);
 
-      if (aAttribute == nsGkAtoms::viewBox ||
-          (aAttribute == nsGkAtoms::preserveAspectRatio &&
-           content->HasViewBoxOrSyntheticViewBox())) {
+      if (aAttribute == nsGkAtoms::x || aAttribute == nsGkAtoms::y) {
+        nsSVGEffects::InvalidateRenderingObservers(this);
+        nsSVGUtils::ScheduleReflowSVG(this);
+      } else if (aAttribute == nsGkAtoms::transform) {
+        nsSVGUtils::InvalidateBounds(this, false);
+        nsSVGUtils::ScheduleReflowSVG(this);
+      } else if (aAttribute == nsGkAtoms::viewBox ||
+                 (aAttribute == nsGkAtoms::preserveAspectRatio &&
+                  content->HasViewBoxOrSyntheticViewBox())) {
+        nsSVGUtils::InvalidateBounds(this, false);
+        nsSVGUtils::ScheduleReflowSVG(this);
         content->ChildrenOnlyTransformChanged();
       }
     }
   }
 
   return NS_OK;
 }
 
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -103,18 +103,20 @@ nsDisplaySVGPathGeometry::Paint(nsDispla
 
 NS_IMETHODIMP
 nsSVGPathGeometryFrame::AttributeChanged(int32_t         aNameSpaceID,
                                          nsIAtom*        aAttribute,
                                          int32_t         aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None &&
       (static_cast<nsSVGPathGeometryElement*>
-                  (mContent)->AttributeDefinesGeometry(aAttribute) ||
-       aAttribute == nsGkAtoms::transform)) {
+                  (mContent)->AttributeDefinesGeometry(aAttribute))) {
+    nsSVGEffects::InvalidateRenderingObservers(this);
+    nsSVGUtils::ScheduleReflowSVG(this);
+  } else if (aAttribute == nsGkAtoms::transform) {
     nsSVGUtils::InvalidateBounds(this, false);
     nsSVGUtils::ScheduleReflowSVG(this);
   }
   return NS_OK;
 }
 
 /* virtual */ void
 nsSVGPathGeometryFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
@@ -122,17 +124,17 @@ nsSVGPathGeometryFrame::DidSetStyleConte
   nsSVGPathGeometryFrameBase::DidSetStyleContext(aOldStyleContext);
 
   // XXX: we'd like to use the style_hint mechanism and the
   // ContentStateChanged/AttributeChanged functions for style changes
   // to get slightly finer granularity, but unfortunately the
   // style_hints don't map very well onto svg. Here seems to be the
   // best place to deal with style changes:
 
-  nsSVGUtils::InvalidateBounds(this, false);
+  nsSVGEffects::InvalidateRenderingObservers(this);
   nsSVGUtils::ScheduleReflowSVG(this);
 }
 
 nsIAtom *
 nsSVGPathGeometryFrame::GetType() const
 {
   return nsGkAtoms::svgPathGeometryFrame;
 }
--- a/layout/svg/nsSVGTSpanFrame.cpp
+++ b/layout/svg/nsSVGTSpanFrame.cpp
@@ -2,16 +2,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
 #include "nsSVGTSpanFrame.h"
 
 // Keep others in (case-insensitive) order:
+#include "nsSVGEffects.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 
 //----------------------------------------------------------------------
 // Implementation
 
 nsIFrame*
 NS_NewSVGTSpanFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
@@ -73,17 +74,17 @@ nsSVGTSpanFrame::AttributeChanged(int32_
                                   int32_t         aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None &&
       (aAttribute == nsGkAtoms::x ||
        aAttribute == nsGkAtoms::y ||
        aAttribute == nsGkAtoms::dx ||
        aAttribute == nsGkAtoms::dy ||
        aAttribute == nsGkAtoms::rotate)) {
-    nsSVGUtils::InvalidateBounds(this, false);
+    nsSVGEffects::InvalidateRenderingObservers(this);
     nsSVGUtils::ScheduleReflowSVG(this);
     NotifyGlyphMetricsChange();
   }
 
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
--- a/layout/svg/nsSVGTextFrame.cpp
+++ b/layout/svg/nsSVGTextFrame.cpp
@@ -5,16 +5,17 @@
 
 // Main header first:
 #include "nsSVGTextFrame.h"
 
 // Keep others in (case-insensitive) order:
 #include "nsGkAtoms.h"
 #include "mozilla/dom/SVGIRect.h"
 #include "nsISVGGlyphFragmentNode.h"
+#include "nsSVGEffects.h"
 #include "nsSVGGlyphFrame.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGTextPathFrame.h"
 #include "nsSVGUtils.h"
 #include "SVGGraphicsElement.h"
 #include "SVGLengthList.h"
 
 using namespace mozilla;
@@ -57,17 +58,17 @@ nsSVGTextFrame::AttributeChanged(int32_t
     nsSVGUtils::InvalidateBounds(this, false);
     nsSVGUtils::ScheduleReflowSVG(this);
     NotifySVGChanged(TRANSFORM_CHANGED);
   } else if (aAttribute == nsGkAtoms::x ||
              aAttribute == nsGkAtoms::y ||
              aAttribute == nsGkAtoms::dx ||
              aAttribute == nsGkAtoms::dy ||
              aAttribute == nsGkAtoms::rotate) {
-    nsSVGUtils::InvalidateBounds(this, false);
+    nsSVGEffects::InvalidateRenderingObservers(this);
     nsSVGUtils::ScheduleReflowSVG(this);
     NotifyGlyphMetricsChange();
   }
 
  return NS_OK;
 }
 
 nsIAtom *
@@ -315,17 +316,17 @@ MarkDirtyBitsOnDescendants(nsIFrame *aFr
 
 void
 nsSVGTextFrame::NotifyGlyphMetricsChange()
 {
   // NotifySVGChanged isn't appropriate here, so we just mark our descendants
   // as fully dirty to get ReflowSVG() called on them:
   MarkDirtyBitsOnDescendants(this);
 
-  nsSVGUtils::InvalidateBounds(this, false);
+  nsSVGEffects::InvalidateRenderingObservers(this);
   nsSVGUtils::ScheduleReflowSVG(this);
 
   mPositioningDirty = true;
 }
 
 void
 nsSVGTextFrame::SetWhitespaceHandling(nsSVGGlyphFrame *aFrame)
 {
--- a/layout/svg/nsSVGTextPathFrame.cpp
+++ b/layout/svg/nsSVGTextPathFrame.cpp
@@ -153,22 +153,22 @@ nsSVGTextPathFrame::GetOffsetScale()
 
 NS_IMETHODIMP
 nsSVGTextPathFrame::AttributeChanged(int32_t         aNameSpaceID,
                                      nsIAtom*        aAttribute,
                                      int32_t         aModType)
 {
   if (aNameSpaceID == kNameSpaceID_None &&
       aAttribute == nsGkAtoms::startOffset) {
-    nsSVGUtils::InvalidateBounds(this, false);
+    nsSVGEffects::InvalidateRenderingObservers(this);
     nsSVGUtils::ScheduleReflowSVG(this);
     NotifyGlyphMetricsChange();
   } else if (aNameSpaceID == kNameSpaceID_XLink &&
              aAttribute == nsGkAtoms::href) {
-    nsSVGUtils::InvalidateBounds(this, false);
+    nsSVGEffects::InvalidateRenderingObservers(this);
     nsSVGUtils::ScheduleReflowSVG(this);
     // Blow away our reference, if any
     Properties().Delete(nsSVGEffects::HrefProperty());
     NotifyGlyphMetricsChange();
   }
 
   return NS_OK;
 }
--- a/layout/svg/nsSVGUseFrame.cpp
+++ b/layout/svg/nsSVGUseFrame.cpp
@@ -1,15 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Keep in (case-insensitive) order:
 #include "nsIAnonymousContentCreator.h"
+#include "nsSVGEffects.h"
 #include "nsSVGGFrame.h"
 #include "mozilla/dom/SVGUseElement.h"
 #include "nsContentList.h"
 
 typedef nsSVGGFrame nsSVGUseFrameBase;
 
 using namespace mozilla::dom;
 
@@ -118,39 +119,39 @@ nsSVGUseFrame::AttributeChanged(int32_t 
 {
   SVGUseElement *useElement = static_cast<SVGUseElement*>(mContent);
 
   if (aNameSpaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::x ||
         aAttribute == nsGkAtoms::y) {
       // make sure our cached transform matrix gets (lazily) updated
       mCanvasTM = nullptr;
-      nsSVGUtils::InvalidateBounds(this, false);
+      nsSVGEffects::InvalidateRenderingObservers(this);
       nsSVGUtils::ScheduleReflowSVG(this);
       nsSVGUtils::NotifyChildrenOfSVGChange(this, TRANSFORM_CHANGED);
     } else if (aAttribute == nsGkAtoms::width ||
                aAttribute == nsGkAtoms::height) {
       bool invalidate = false;
       if (mHasValidDimensions != useElement->HasValidDimensions()) {
         mHasValidDimensions = !mHasValidDimensions;
         invalidate = true;
       }
       if (useElement->OurWidthAndHeightAreUsed()) {
         invalidate = true;
         useElement->SyncWidthOrHeight(aAttribute);
       }
       if (invalidate) {
-        nsSVGUtils::InvalidateBounds(this, false);
+        nsSVGEffects::InvalidateRenderingObservers(this);
         nsSVGUtils::ScheduleReflowSVG(this);
       }
     }
   } else if (aNameSpaceID == kNameSpaceID_XLink &&
              aAttribute == nsGkAtoms::href) {
     // we're changing our nature, clear out the clone information
-    nsSVGUtils::InvalidateBounds(this, false);
+    nsSVGEffects::InvalidateRenderingObservers(this);
     nsSVGUtils::ScheduleReflowSVG(this);
     useElement->mOriginal = nullptr;
     useElement->UnlinkSource();
     useElement->TriggerReclone();
   }
 
   return nsSVGUseFrameBase::AttributeChanged(aNameSpaceID,
                                              aAttribute, aModType);