Bug 1510295. Stop SVGRenderingObserver subclasses observing reflow, except for -moz-element. r=longsonr
authorJonathan Watt <jwatt@jwatt.org>
Wed, 14 Nov 2018 10:39:12 +0000
changeset 504846 e524ab71423449bd1b9e534ec0a7ee88d0b51e6d
parent 504845 1e9f3b7f0e6daaec8bf9329a43d4abdaa07682d6
child 504847 4688e47fcb9dd1bc48c14108eb87931c8e0dc648
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslongsonr
bugs1510295
milestone65.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 1510295. Stop SVGRenderingObserver subclasses observing reflow, except for -moz-element. r=longsonr Differential Revision: https://phabricator.services.mozilla.com/D13080
layout/svg/SVGObserverUtils.cpp
layout/svg/SVGObserverUtils.h
--- a/layout/svg/SVGObserverUtils.cpp
+++ b/layout/svg/SVGObserverUtils.cpp
@@ -367,20 +367,16 @@ nsSVGRenderingObserverProperty::OnRender
 class SVGTextPathObserver final : public nsSVGRenderingObserverProperty
 {
 public:
   SVGTextPathObserver(URLAndReferrerInfo* aURI, nsIFrame* aFrame, bool aReferenceImage)
     : nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage)
     , mValid(true)
   {}
 
-  bool ObservesReflow() override {
-    return false;
-  }
-
 protected:
   void OnRenderingChange() override;
 
 private:
   /**
    * Returns true if the target of the textPath is the frame of a 'path' element.
    */
   bool TargetIsValid() {
@@ -461,17 +457,17 @@ SVGMarkerObserver::OnRenderingChange()
     nsSVGUtils::ScheduleReflowSVG(frame);
   }
   frame->PresContext()->RestyleManager()->PostRestyleEvent(
     frame->GetContent()->AsElement(), nsRestyleHint(0),
     nsChangeHint_RepaintFrame);
 }
 
 
-class nsSVGPaintingProperty final : public nsSVGRenderingObserverProperty
+class nsSVGPaintingProperty : public nsSVGRenderingObserverProperty
 {
 public:
   nsSVGPaintingProperty(URLAndReferrerInfo* aURI, nsIFrame* aFrame, bool aReferenceImage)
     : nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage)
   {}
 
 protected:
   void OnRenderingChange() override;
@@ -493,16 +489,34 @@ nsSVGPaintingProperty::OnRenderingChange
     for (nsIFrame* f = frame; f;
          f = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(f)) {
       f->InvalidateFrame();
     }
   }
 }
 
 
+class SVGMozElementObserver final : public nsSVGPaintingProperty
+{
+public:
+  SVGMozElementObserver(URLAndReferrerInfo* aURI, nsIFrame* aFrame,
+                        bool aReferenceImage)
+    : nsSVGPaintingProperty(aURI, aFrame, aReferenceImage)
+  {}
+
+  // We only return true here because GetAndObserveBackgroundImage uses us
+  // to implement observing of arbitrary elements (including HTML elements)
+  // that may require us to repaint if the referenced element is reflowed.
+  // Bug 1496065 has been filed to remove that support though.
+  bool ObservesReflow() override {
+    return true;
+  }
+};
+
+
 /**
  * In a filter chain, there can be multiple SVG reference filters.
  * e.g. filter: url(#svg-filter-1) blur(10px) url(#svg-filter-2);
  *
  * This class keeps track of one SVG reference filter in a filter chain.
  * e.g. url(#svg-filter-1)
  *
  * It fires invalidations when the SVG filter element's id changes or when
@@ -1465,20 +1479,20 @@ SVGObserverUtils::GetAndObserveBackgroun
     base);
   RefPtr<URLAndReferrerInfo> url = new URLAndReferrerInfo(
     targetURI,
     aFrame->GetContent()->OwnerDoc()->GetDocumentURI(),
     aFrame->GetContent()->OwnerDoc()->GetReferrerPolicy());
 
   // XXXjwatt: this is broken - we're using the address of a new
   // URLAndReferrerInfo as the hash key every time!
-  nsSVGPaintingProperty* observer =
-    static_cast<nsSVGPaintingProperty*>(hashtable->GetWeak(url));
+  SVGMozElementObserver* observer =
+    static_cast<SVGMozElementObserver*>(hashtable->GetWeak(url));
   if (!observer) {
-    observer = new nsSVGPaintingProperty(url, aFrame, /* aWatchImage */ true);
+    observer = new SVGMozElementObserver(url, aFrame, /* aWatchImage */ true);
     hashtable->Put(url, observer);
   }
   return observer->GetAndObserveReferencedElement();
 }
 
 nsSVGPaintServerFrame *
 SVGObserverUtils::GetAndObservePaintServer(nsIFrame* aTargetFrame,
                                            nsStyleSVGPaint nsStyleSVG::* aPaint)
--- a/layout/svg/SVGObserverUtils.h
+++ b/layout/svg/SVGObserverUtils.h
@@ -140,17 +140,17 @@ public:
    * @param aOK this is only for the convenience of callers. We set *aOK to false
    * if the frame is the wrong type
    */
   nsIFrame* GetAndObserveReferencedFrame(mozilla::LayoutFrameType aFrameType,
                                          bool* aOK);
 
   Element* GetAndObserveReferencedElement();
 
-  virtual bool ObservesReflow() { return true; }
+  virtual bool ObservesReflow() { return false; }
 
 protected:
   void StartObserving();
   void StopObserving();
 
   /**
    * Called whenever the rendering of the observed element may have changed.
    *
@@ -398,16 +398,23 @@ public:
    * used as a callback to lazily get the href value, if necessary.
    */
   static nsIFrame*
   GetAndObserveTemplate(nsIFrame* aFrame, HrefToTemplateCallback aGetHref);
 
   static void
   RemoveTemplateObserver(nsIFrame* aFrame);
 
+  /**
+   * Gets an arbitrary element and starts observing it.  Used to implement
+   * '-moz-element'.
+   *
+   * Note that bug 1496065 has been filed to remove support for referencing
+   * arbitrary elements using '-moz-element'.
+   */
   static Element*
   GetAndObserveBackgroundImage(nsIFrame* aFrame,
                                const nsAtom* aHref);
 
   /**
    * A helper function to resolve filter URL.
    */
   static already_AddRefed<URLAndReferrerInfo>