Bug 1499542 part 1: Don't do early-freeze of flexible-but-doomed-to-be-clamped flex items, if devtools are active. r=bradwerth
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 18 Oct 2018 23:44:42 +0000
changeset 497760 52bd865d757c2787845e1bb79ed3936484d6ce3b
parent 497759 12527d50a493ce5a8c96bd7e6990d751ce9846e6
child 497761 3ea646bde4de4772a439a31798406287d2be685e
push id10002
push userarchaeopteryx@coole-files.de
push dateFri, 19 Oct 2018 23:09:29 +0000
treeherdermozilla-beta@01378c910610 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbradwerth
bugs1499542
milestone64.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 1499542 part 1: Don't do early-freeze of flexible-but-doomed-to-be-clamped flex items, if devtools are active. r=bradwerth We'd like to be able to record the "desired" (pre-clamped) delta size from tentatively flexing for these items. That size would be computed during a loop of the flex layout algorithm -- but we can't do that if we freeze them before we start flexing. So let's bypass this early freeze so they get a chance to compute this tentative size, even though they can never have it. Differential Revision: https://phabricator.services.mozilla.com/D8922
layout/generic/nsFlexContainerFrame.cpp
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1074,17 +1074,18 @@ public:
 
   void PositionItemsInCrossAxis(nscoord aLineStartPosition,
                                 const FlexboxAxisTracker& aAxisTracker);
 
   friend class AutoFlexLineListClearer; // (needs access to mItems)
 
 private:
   // Helpers for ResolveFlexibleLengths():
-  void FreezeItemsEarly(bool aIsUsingFlexGrow);
+  void FreezeItemsEarly(bool aIsUsingFlexGrow,
+                        ComputedFlexLineInfo* aLineInfo);
 
   void FreezeOrRestoreEachFlexibleSize(const nscoord aTotalViolation,
                                        bool aIsFinalIteration);
 
   LinkedList<FlexItem> mItems; // Linked list of this line's flex items.
 
   uint32_t mNumItems; // Number of FlexItems in this line (in |mItems|).
                       // (Shouldn't change after GenerateFlexLines finishes
@@ -2498,17 +2499,18 @@ nsFlexContainerFrame::BuildDisplayList(n
   for (; !iter.AtEnd(); iter.Next()) {
     nsIFrame* childFrame = *iter;
     BuildDisplayListForChild(aBuilder, childFrame, childLists,
                              GetDisplayFlagsForFlexItem(childFrame));
   }
 }
 
 void
-FlexLine::FreezeItemsEarly(bool aIsUsingFlexGrow)
+FlexLine::FreezeItemsEarly(bool aIsUsingFlexGrow,
+                           ComputedFlexLineInfo* aLineInfo)
 {
   // After we've established the type of flexing we're doing (growing vs.
   // shrinking), and before we try to flex any items, we freeze items that
   // obviously *can't* flex.
   //
   // Quoting the spec:
   //  # Freeze, setting its target main size to its hypothetical main size...
   //  #  - any item that has a flex factor of zero
@@ -2527,17 +2529,23 @@ FlexLine::FreezeItemsEarly(bool aIsUsing
   uint32_t numUnfrozenItemsToBeSeen = mNumItems - mNumFrozenItems;
   for (FlexItem* item = mItems.getFirst();
        numUnfrozenItemsToBeSeen > 0; item = item->getNext()) {
     MOZ_ASSERT(item, "numUnfrozenItemsToBeSeen says items remain to be seen");
 
     if (!item->IsFrozen()) {
       numUnfrozenItemsToBeSeen--;
       bool shouldFreeze = (0.0f == item->GetFlexFactor(aIsUsingFlexGrow));
-      if (!shouldFreeze) {
+      // NOTE: We skip the "could flex but base size out of range"
+      // early-freezing if flex devtools are active, so that we can let the
+      // first run of the main flex layout loop compute how much this item
+      // wants to flex. (This skipping shouldn't impact results, because
+      // any affected items will just immediately be caught & frozen as min/max
+      // violations in that first loop, and that'll trigger another loop.)
+      if (!shouldFreeze && !aLineInfo) {
         if (aIsUsingFlexGrow) {
           if (item->GetFlexBaseSize() > item->GetMainSize()) {
             shouldFreeze = true;
           }
         } else { // using flex-shrink
           if (item->GetFlexBaseSize() < item->GetMainSize()) {
             shouldFreeze = true;
           }
@@ -2619,17 +2627,17 @@ FlexLine::ResolveFlexibleLengths(nscoord
   MOZ_LOG(gFlexContainerLog, LogLevel::Debug, ("ResolveFlexibleLengths\n"));
 
   // Determine whether we're going to be growing or shrinking items.
   const bool isUsingFlexGrow =
     (mTotalOuterHypotheticalMainSize < aFlexContainerMainSize);
 
   // Do an "early freeze" for flex items that obviously can't flex in the
   // direction we've chosen:
-  FreezeItemsEarly(isUsingFlexGrow);
+  FreezeItemsEarly(isUsingFlexGrow, aLineInfo);
 
   if ((mNumFrozenItems == mNumItems) && !aLineInfo) {
     // All our items are frozen, so we have no flexible lengths to resolve,
     // and we aren't being asked to generate computed line info.
     return;
   }
   MOZ_ASSERT(!IsEmpty() || aLineInfo,
              "empty lines should take the early-return above");