Bug 1425599 part 11 - [css-grid] Hoist the marking of excluded tracks out from GrowSelectedTracksUnlimited to a separate method (idempotent change). r=dholbert a=jcristau
authorMats Palmgren <mats@mozilla.com>
Thu, 15 Mar 2018 22:41:24 +0100
changeset 462725 f542fec596d962d589b76eb3ce3a44ad7f5db448
parent 462724 c8c86f719155e279cb7e2d102aaaa07dd12278cd
child 462726 ce0dfee9798f6fcdd0fe19f796df932ce5297173
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, jcristau
bugs1425599
milestone60.0
Bug 1425599 part 11 - [css-grid] Hoist the marking of excluded tracks out from GrowSelectedTracksUnlimited to a separate method (idempotent change). r=dholbert a=jcristau
layout/generic/nsGridContainerFrame.cpp
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -1407,67 +1407,86 @@ struct nsGridContainerFrame::Tracks
         aPlan[track].mState &= ~aSkipFlag;
       }
       numGrowable = aNumGrowable;
     }
     return numGrowable;
   }
 
   /**
-   * Increase the planned size for tracks in aGrowableTracks that match
-   * aSelector (or all tracks if aSelector is zero) beyond their limit.
+   * Mark all tracks in aGrowableTracks with an eSkipGrowUnlimited bit if
+   * they *shouldn't* grow unlimited in §11.5.1.2.3 "Distribute space beyond
+   * growth limits" https://drafts.csswg.org/css-grid/#extra-space
+   * Return the number of tracks that are still growable.
+   */
+  template<TrackSizingPhase phase>
+  static uint32_t
+  MarkExcludedTracks(nsTArray<TrackSize>&      aPlan,
+                     const nsTArray<uint32_t>& aGrowableTracks,
+                     TrackSize::StateBits      aSelector)
+  {
+    uint32_t numGrowable = aGrowableTracks.Length();
+    if (phase == TrackSizingPhase::eIntrinsicMaximums ||
+        phase == TrackSizingPhase::eMaxContentMaximums) {
+      // "when handling any intrinsic growth limit: all affected tracks"
+      return numGrowable;
+    }
+    MOZ_ASSERT(aSelector == (aSelector & TrackSize::eIntrinsicMinSizing) &&
+                            (aSelector & TrackSize::eMaxContentMinSizing),
+               "Should only get here for track sizing steps 2.1 to 2.3");
+    // Note that eMaxContentMinSizing is always included. We do those first:
+    numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks,
+                                     TrackSize::eMaxContentMinSizing,
+                                     TrackSize::eMaxContentMaxSizing,
+                                     TrackSize::eSkipGrowUnlimited1);
+    // Now mark min-content/auto min-sizing tracks if requested.
+    auto minOrAutoSelector = aSelector & ~TrackSize::eMaxContentMinSizing;
+    if (minOrAutoSelector) {
+      numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks,
+                                       minOrAutoSelector,
+                                       TrackSize::eIntrinsicMaxSizing,
+                                       TrackSize::eSkipGrowUnlimited2);
+    }
+    return numGrowable;
+  }
+
+  /**
+   * Increase the planned size for tracks in aGrowableTracks that aren't
+   * marked with a eSkipGrowUnlimited flag beyond their limit.
    * This implements the "Distribute space beyond growth limits" step in
    * https://drafts.csswg.org/css-grid/#distribute-extra-space
    */
   void GrowSelectedTracksUnlimited(nscoord                   aAvailableSpace,
                                    nsTArray<TrackSize>&      aPlan,
                                    const nsTArray<uint32_t>& aGrowableTracks,
-                                   TrackSize::StateBits      aSelector,
+                                   uint32_t                  aNumGrowable,
                                    const FitContentClamper&  aFitContentClamper) const
   {
-    MOZ_ASSERT(aAvailableSpace > 0 && aGrowableTracks.Length() > 0);
-    uint32_t numGrowable = aGrowableTracks.Length();
-    if (aSelector) {
-      MOZ_ASSERT(aSelector == (aSelector & TrackSize::eIntrinsicMinSizing) &&
-                 (aSelector & TrackSize::eMaxContentMinSizing),
-                 "Should only get here for track sizing steps 2.1 to 2.3");
-      // Note that eMaxContentMinSizing is always included. We do those first:
-      numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks,
-                                       TrackSize::eMaxContentMinSizing,
-                                       TrackSize::eMaxContentMaxSizing,
-                                       TrackSize::eSkipGrowUnlimited1);
-      // Now mark min-content/auto min-sizing tracks if requested.
-      auto minOrAutoSelector = aSelector & ~TrackSize::eMaxContentMinSizing;
-      if (minOrAutoSelector) {
-        numGrowable = MarkExcludedTracks(aPlan, numGrowable, aGrowableTracks,
-                                         minOrAutoSelector,
-                                         TrackSize::eIntrinsicMaxSizing,
-                                         TrackSize::eSkipGrowUnlimited2);
-      }
-    }
+    MOZ_ASSERT(aAvailableSpace > 0 && aGrowableTracks.Length() > 0 &&
+               aNumGrowable <= aGrowableTracks.Length());
     nscoord space = aAvailableSpace;
     DebugOnly<bool> didClamp = false;
-    while (numGrowable) {
-      nscoord spacePerTrack = std::max<nscoord>(space / numGrowable, 1);
+    while (aNumGrowable) {
+      nscoord spacePerTrack = std::max<nscoord>(space / aNumGrowable, 1);
       for (uint32_t track : aGrowableTracks) {
         TrackSize& sz = aPlan[track];
         if (sz.mState & TrackSize::eSkipGrowUnlimited) {
           continue; // an excluded track
         }
         nscoord delta = spacePerTrack;
         nscoord newBase = sz.mBase + delta;
         if (MOZ_UNLIKELY((sz.mState & TrackSize::eFitContent) &&
                          aFitContentClamper)) {
           // Clamp newBase to the fit-content() size, for §12.5.2 step 5/6.
           if (aFitContentClamper(track, sz.mBase, &newBase)) {
             didClamp = true;
             delta = newBase - sz.mBase;
             MOZ_ASSERT(delta >= 0, "track size shouldn't shrink");
             sz.mState |= TrackSize::eSkipGrowUnlimited1;
-            --numGrowable;
+            --aNumGrowable;
           }
         }
         sz.mBase = newBase;
         space -= delta;
         MOZ_ASSERT(space >= 0);
         if (space == 0) {
           return;
         }
@@ -1488,18 +1507,20 @@ struct nsGridContainerFrame::Tracks
                               nsTArray<uint32_t>&  aGrowableTracks,
                               TrackSize::StateBits aSelector,
                               const FitContentClamper& aFitContentClamper)
   {
     InitializeItemPlan<phase>(aItemPlan, aGrowableTracks);
     nscoord space = GrowTracksToLimit(aAvailableSpace, aItemPlan, aGrowableTracks,
                                       aFitContentClamper);
     if (space > 0) {
-      GrowSelectedTracksUnlimited(space, aItemPlan, aGrowableTracks, aSelector,
-                                  aFitContentClamper);
+      uint32_t numGrowable =
+        MarkExcludedTracks<phase>(aItemPlan, aGrowableTracks, aSelector);
+      GrowSelectedTracksUnlimited(space, aItemPlan, aGrowableTracks,
+                                  numGrowable, aFitContentClamper);
     }
     for (uint32_t track : aGrowableTracks) {
       nscoord& plannedSize = aPlan[track].mBase;
       nscoord itemIncurredSize = aItemPlan[track].mBase;
       if (plannedSize < itemIncurredSize) {
         plannedSize = itemIncurredSize;
       }
     }