Bug 1180118 - Part 7: Split out FindClosestRestyleRoot and allow passing in a pre-computed restyle root to AddPendingRestyle. r=bzbarsky
☠☠ backed out by 01576b408ea7 ☠ ☠
authorCameron McCormack <cam@mcc.id.au>
Tue, 04 Aug 2015 17:27:53 +1000
changeset 287741 b7ec8d4d2d7ec81147f6c37d536693a722c8f10b
parent 287740 cfeeae42d514010575d03a9a767fa98640ec0f34
child 287742 37493f6eef20c1dbf6d6c042a609474e93e1d996
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky
bugs1180118
milestone42.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 1180118 - Part 7: Split out FindClosestRestyleRoot and allow passing in a pre-computed restyle root to AddPendingRestyle. r=bzbarsky
layout/base/RestyleTracker.h
--- a/layout/base/RestyleTracker.h
+++ b/layout/base/RestyleTracker.h
@@ -12,16 +12,17 @@
 #define mozilla_RestyleTracker_h
 
 #include "mozilla/dom/Element.h"
 #include "nsClassHashtable.h"
 #include "nsContainerFrame.h"
 #include "mozilla/SplayTree.h"
 #include "mozilla/RestyleLogging.h"
 #include "GeckoProfiler.h"
+#include "mozilla/Maybe.h"
 
 #if defined(MOZ_ENABLE_PROFILER_SPS) && !defined(MOZILLA_XPCOMRT_API)
 #include "ProfilerBacktrace.h"
 #endif
 
 namespace mozilla {
 
 class RestyleManager;
@@ -251,20 +252,29 @@ public:
 
   uint32_t Count() const {
     return mPendingRestyles.Count();
   }
 
   /**
    * Add a restyle for the given element to the tracker.  Returns true
    * if the element already had eRestyle_LaterSiblings set on it.
+   *
+   * aRestyleRoot is the closest restyle root for aElement.  If the caller
+   * does not know what the closest restyle root is, Nothing should be
+   * passed.  A Some(nullptr) restyle root can be passed if there is no
+   * ancestor element that is a restyle root.
    */
   bool AddPendingRestyle(Element* aElement, nsRestyleHint aRestyleHint,
                          nsChangeHint aMinChangeHint,
-                         const RestyleHintData* aRestyleHintData = nullptr);
+                         const RestyleHintData* aRestyleHintData = nullptr,
+                         mozilla::Maybe<Element*> aRestyleRoot =
+                           mozilla::Nothing());
+
+  Element* FindClosestRestyleRoot(Element* aElement);
 
   /**
    * Process the restyles we've been tracking.
    */
   void DoProcessRestyles();
 
   // Return our ELEMENT_HAS_PENDING_(ANIMATION_)RESTYLE bit
   uint32_t RestyleBit() const {
@@ -432,54 +442,65 @@ RestyleTracker::AddPendingRestyleToTable
   if (aRestyleHintData) {
     existingData->mRestyleHintData.mSelectorsForDescendants
       .AppendElements(aRestyleHintData->mSelectorsForDescendants);
   }
 
   return hadRestyleLaterSiblings;
 }
 
+inline mozilla::dom::Element*
+RestyleTracker::FindClosestRestyleRoot(Element* aElement)
+{
+  Element* cur = aElement;
+  while (!cur->HasFlag(RootBit())) {
+    nsIContent* parent = cur->GetFlattenedTreeParent();
+    // Stop if we have no parent or the parent is not an element or
+    // we're part of the viewport scrollbars (because those are not
+    // frametree descendants of the primary frame of the root
+    // element).
+    // XXXbz maybe the primary frame of the root should be the root scrollframe?
+    if (!parent || !parent->IsElement() ||
+        // If we've hit the root via a native anonymous kid and that
+        // this native anonymous kid is not obviously a descendant
+        // of the root's primary frame, assume we're under the root
+        // scrollbars.  Since those don't get reresolved when
+        // reresolving the root, we need to make sure to add the
+        // element to mRestyleRoots.
+        (cur->IsInNativeAnonymousSubtree() && !parent->GetParent() &&
+         cur->GetPrimaryFrame() &&
+         cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) {
+      return nullptr;
+    }
+    cur = parent->AsElement();
+  }
+  return cur;
+}
+
 inline bool
 RestyleTracker::AddPendingRestyle(Element* aElement,
                                   nsRestyleHint aRestyleHint,
                                   nsChangeHint aMinChangeHint,
-                                  const RestyleHintData* aRestyleHintData)
+                                  const RestyleHintData* aRestyleHintData,
+                                  mozilla::Maybe<Element*> aRestyleRoot)
 {
   bool hadRestyleLaterSiblings =
     AddPendingRestyleToTable(aElement, aRestyleHint, aMinChangeHint,
                              aRestyleHintData);
 
   // We can only treat this element as a restyle root if we would
   // actually restyle its descendants (so either call
   // ReResolveStyleContext on it or just reframe it).
   if ((aRestyleHint & ~eRestyle_LaterSiblings) ||
       (aMinChangeHint & nsChangeHint_ReconstructFrame)) {
-    Element* cur = aElement;
-    while (!cur->HasFlag(RootBit())) {
-      nsIContent* parent = cur->GetFlattenedTreeParent();
-      // Stop if we have no parent or the parent is not an element or
-      // we're part of the viewport scrollbars (because those are not
-      // frametree descendants of the primary frame of the root
-      // element).
-      // XXXbz maybe the primary frame of the root should be the root scrollframe?
-      if (!parent || !parent->IsElement() ||
-          // If we've hit the root via a native anonymous kid and that
-          // this native anonymous kid is not obviously a descendant
-          // of the root's primary frame, assume we're under the root
-          // scrollbars.  Since those don't get reresolved when
-          // reresolving the root, we need to make sure to add the
-          // element to mRestyleRoots.
-          (cur->IsInNativeAnonymousSubtree() && !parent->GetParent() &&
-           cur->GetPrimaryFrame() &&
-           cur->GetPrimaryFrame()->GetParent() != parent->GetPrimaryFrame())) {
-        mRestyleRoots.AppendElement(aElement);
-        cur = aElement;
-        break;
-      }
-      cur = parent->AsElement();
+    Element* cur =
+      aRestyleRoot ? *aRestyleRoot : FindClosestRestyleRoot(aElement);
+    if (!cur) {
+      mRestyleRoots.AppendElement(aElement);
+      cur = aElement;
     }
     // At this point some ancestor of aElement (possibly aElement
     // itself) is in mRestyleRoots.  Set the root bit on aElement, to
     // speed up searching for an existing root on its descendants.
     aElement->SetFlags(RootBit());
     if (cur != aElement) {
       // We are already going to restyle cur, one of aElement's ancestors,
       // but we might not end up restyling all the way down to aElement.