Bug 1535986 - Skip recomputing the position for frames that have a pending reflow. r=dholbert a=pascalc
authorMats Palmgren <mats@mozilla.com>
Mon, 18 Mar 2019 16:25:28 +0100
changeset 525773 9b874010673d878cb9772770bc8ba7f6572ee693
parent 525772 6b273123543412fa98b0c551863efb7d8270bf2e
child 525774 7c3c3ffea0a4fb284e99afecdd15bc37bfeec12c
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, pascalc
bugs1535986
milestone67.0
Bug 1535986 - Skip recomputing the position for frames that have a pending reflow. r=dholbert a=pascalc Differential Revision: https://phabricator.services.mozilla.com/D23971
layout/base/RestyleManager.cpp
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -638,19 +638,20 @@ static nsIFrame* GetFrameForChildrenOnly
     MOZ_ASSERT(aFrame->IsSVGOuterSVGAnonChildFrame(),
                "Where is the nsSVGOuterSVGFrame's anon child??");
   }
   MOZ_ASSERT(aFrame->IsFrameOfType(nsIFrame::eSVG | nsIFrame::eSVGContainer),
              "Children-only transforms only expected on SVG frames");
   return aFrame;
 }
 
-// Returns true if this function managed to successfully move a frame, and
-// false if it could not process the position change, and a reflow should
-// be performed instead.
+// This function tries to optimize a position style change by either
+// moving aFrame or ignoring the style change when it's safe to do so.
+// It returns true when that succeeds, otherwise it posts a reflow request
+// and returns false.
 static bool RecomputePosition(nsIFrame* aFrame) {
   // Don't process position changes on table frames, since we already handle
   // the dynamic position change on the table wrapper frame, and the
   // reflow-based fallback code path also ignores positions on inner table
   // frames.
   if (aFrame->IsTableFrame()) {
     return true;
   }
@@ -677,16 +678,22 @@ static bool RecomputePosition(nsIFrame* 
     nsIFrame* ph = aFrame->GetPlaceholderFrame();
     if (ph && ph->HasAnyStateBits(PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN)) {
       StyleChangeReflow(aFrame, nsChangeHint_NeedReflow |
                                     nsChangeHint_ReflowChangesSizeOrPosition);
       return false;
     }
   }
 
+  // It's pointless to move around frames that have never been reflowed or
+  // are dirty (i.e. they will be reflowed).
+  if (aFrame->HasAnyStateBits(NS_FRAME_FIRST_REFLOW | NS_FRAME_IS_DIRTY)) {
+    return true;
+  }
+
   aFrame->SchedulePaint();
 
   // For relative positioning, we can simply update the frame rect
   if (display->IsRelativelyPositionedStyle()) {
     // Move the frame
     if (display->mPosition == NS_STYLE_POSITION_STICKY) {
       // Update sticky positioning for an entire element at once, starting with
       // the first continuation or ib-split sibling.