Bug 1330375 - P1: Helper for checking for ancestor of dirty reflow root. r?emilio draft
authorDan Glastonbury <dan.glastonbury@gmail.com>
Thu, 19 Jul 2018 14:18:53 +1000
changeset 821877 ac2723b4daecbef307fe967554debded65fbe056
parent 821749 fe48e26ca88c7919f0c075dc01d5f9fdccdb1260
child 821878 580bf0dab38832046663ac9598d68229344e4945
push id117207
push userbmo:dglastonbury@mozilla.com
push dateTue, 24 Jul 2018 05:13:45 +0000
reviewersemilio
bugs1330375
milestone63.0a1
Bug 1330375 - P1: Helper for checking for ancestor of dirty reflow root. r?emilio Including refactoring mDirtyRoots into nsIPresShell to avoid virtual call. MozReview-Commit-ID: KxST8FMsZl9
layout/base/PresShell.cpp
layout/base/PresShell.h
layout/base/nsIPresShell.h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4558,16 +4558,37 @@ PresShell::ContentRemoved(nsIContent* aC
 
 void
 PresShell::NotifyCounterStylesAreDirty()
 {
   nsAutoCauseReflowNotifier reflowNotifier(this);
   mFrameConstructor->NotifyCounterStylesAreDirty();
 }
 
+bool
+nsIPresShell::FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const
+{
+  MOZ_ASSERT(aFrame);
+
+  // Look for a path from any dirty roots to aFrame, following GetParent().
+  // This check mirrors what FrameNeedsReflow() would have done if the reflow
+  // root didn't get in the way.
+  for (nsIFrame* dirtyFrame : mDirtyRoots) {
+    while (dirtyFrame) {
+      if (dirtyFrame == aFrame) {
+        return true;
+      }
+
+      dirtyFrame = dirtyFrame->GetParent();
+    }
+  }
+
+  return false;
+}
+
 void
 PresShell::ReconstructFrames()
 {
   MOZ_ASSERT(!mFrameConstructor->GetRootFrame() || mDidInitialize,
              "Must not have root frame before initial reflow");
   if (!mDidInitialize || mIsDestroying) {
     // Nothing to do here
     return;
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -779,19 +779,16 @@ private:
 
   // mStyleSet owns it but we maintain a ref, may be null
   RefPtr<StyleSheet> mPrefStyleSheet;
 
   // Set of frames that we should mark with NS_FRAME_HAS_DIRTY_CHILDREN after
   // we finish reflowing mCurrentReflowRoot.
   nsTHashtable<nsPtrHashKey<nsIFrame> > mFramesToDirty;
 
-  // Reflow roots that need to be reflowed.
-  nsTArray<nsIFrame*> mDirtyRoots;
-
   nsTArray<nsAutoPtr<DelayedEvent> > mDelayedEvents;
 private:
   nsIFrame* mCurrentEventFrame;
   nsCOMPtr<nsIContent> mCurrentEventContent;
   nsTArray<nsIFrame*> mCurrentEventFrameStack;
   nsCOMArray<nsIContent> mCurrentEventContentStack;
   nsRevocableEventPtr<nsSynthMouseMoveEvent> mSynthMouseMoveEvent;
   nsCOMPtr<nsIContent> mLastAnchorScrolledTo;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -498,16 +498,18 @@ public:
    * other than NS_FRAME_HAS_DIRTY_CHILDREN.
    */
   virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) = 0;
 
   virtual void CancelAllPendingReflows() = 0;
 
   virtual void NotifyCounterStylesAreDirty() = 0;
 
+  bool FrameIsAncestorOfDirtyRoot(nsIFrame* aFrame) const;
+
   /**
    * Destroy the frames for aElement, and reconstruct them asynchronously if
    * needed.
    *
    * Note that this may destroy frames for an ancestor instead.
    */
   void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement);
 
@@ -1756,16 +1758,19 @@ protected:
   nsPoint                   mVisualViewportOffset;
 
   // A list of stack weak frames. This is a pointer to the last item in the list.
   AutoWeakFrame*            mAutoWeakFrames;
 
   // A hash table of heap allocated weak frames.
   nsTHashtable<nsPtrHashKey<WeakFrame>> mWeakFrames;
 
+  // Reflow roots that need to be reflowed.
+  nsTArray<nsIFrame*> mDirtyRoots;
+
 #ifdef MOZ_GECKO_PROFILER
   // These two fields capture call stacks of any changes that require a restyle
   // or a reflow. Only the first change per restyle / reflow is recorded (the
   // one that caused a call to SetNeedStyleFlush() / SetNeedLayoutFlush()).
   UniqueProfilerBacktrace mStyleCause;
   UniqueProfilerBacktrace mReflowCause;
 #endif