Bug 1348857 part 1 - [css-grid] Add a bit on GridItemInfo that says if we should apply Automatic Minimum Size or not (idempotent patch). r=dholbert a=gchang
authorMats Palmgren <mats@mozilla.com>
Tue, 18 Apr 2017 22:35:04 +0200
changeset 395991 0065e54275aa65e9718c7a67db5c002b9605e8af
parent 395990 f2197e50ffbb1b06129a4fd19ef94c3ef7a7a7e7
child 395992 20cc389b33bd8a4e80b253a14b7ee27e61f5acfa
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert, gchang
bugs1348857
milestone54.0
Bug 1348857 part 1 - [css-grid] Add a bit on GridItemInfo that says if we should apply Automatic Minimum Size or not (idempotent patch). r=dholbert a=gchang This renames ShouldClampMinSize to ShouldApplyAutoMinSize, which is more accurate, and caches the value on the grid item for later use. No functional changes other than that. MozReview-Commit-ID: E1mvBZsMIxh
layout/generic/nsGridContainerFrame.cpp
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -813,18 +813,21 @@ struct nsGridContainerFrame::GridItemInf
     // ditto 'last baseline', mutually exclusive w. eFirstBaseline
     eLastBaseline =           0x4,
     eIsBaselineAligned = eFirstBaseline | eLastBaseline,
     // One of e[Self|Content]Baseline is set when eIsBaselineAligned is true
     eSelfBaseline =           0x8, // is it *-self:[last ]baseline alignment?
     // Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline.
     eContentBaseline =       0x10,
     eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline,
+    // Should apply Automatic Minimum Size per:
+    // https://drafts.csswg.org/css-grid/#min-size-auto
+    eApplyAutoMinSize =      0x20,
     // Clamp per https://drafts.csswg.org/css-grid/#min-size-auto
-    eClampMarginBoxMinSize = 0x20,
+    eClampMarginBoxMinSize = 0x40,
   };
 
   explicit GridItemInfo(nsIFrame* aFrame,
                         const GridArea& aArea)
     : mFrame(aFrame)
     , mArea(aArea)
   {
     mState[eLogicalAxisBlock] = StateBits(0);
@@ -846,21 +849,21 @@ struct nsGridContainerFrame::GridItemInf
     if (!(mState[aAxis] & eSelfBaseline)) {
       return aAlign == NS_STYLE_ALIGN_BASELINE ? NS_STYLE_ALIGN_SELF_START
                                                : NS_STYLE_ALIGN_SELF_END;
     }
     *aBaselineOffset = mBaselineOffset[aAxis];
     return aAlign;
   }
 
-  // Return true if we should we clamp this item's Automatic Minimum Size.
+  // Return true if we should apply Automatic Minimum Size to this item.
   // https://drafts.csswg.org/css-grid/#min-size-auto
-  bool ShouldClampMinSize(WritingMode aContainerWM,
-                          LogicalAxis aContainerAxis,
-                          nscoord aPercentageBasis) const
+  bool ShouldApplyAutoMinSize(WritingMode aContainerWM,
+                              LogicalAxis aContainerAxis,
+                              nscoord aPercentageBasis) const
   {
     const auto pos = mFrame->StylePosition();
     const auto& size = aContainerAxis == eLogicalAxisInline ?
       pos->ISize(aContainerWM) : pos->BSize(aContainerWM);
     // NOTE: if we have a definite or 'max-content' size then our automatic
     // minimum size can't affect our size.  Excluding these simplifies applying
     // the clamping in the right cases later.
     if (size.GetUnit() == eStyleUnit_Auto ||
@@ -3984,19 +3987,19 @@ nsGridContainerFrame::Tracks::ResolveInt
   const LineRange&            aRange,
   const GridItemInfo&         aGridItem)
 {
   CachedIntrinsicSizes cache;
   TrackSize& sz = mSizes[aRange.mStart];
   WritingMode wm = aState.mWM;
   // Calculate data for "Automatic Minimum Size" clamping, if needed.
   bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) ||
-                 aConstraint == SizingConstraint::eNoConstraint);
-  if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState) &&
-      aGridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+                 aConstraint == SizingConstraint::eNoConstraint) &&
+                (aGridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
+  if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState)) {
     if (sz.mState & TrackSize::eIntrinsicMinSizing) {
       auto maxCoord = aFunctions.MaxSizingFor(aRange.mStart);
       cache.mMinSizeClamp =
         nsRuleNode::ComputeCoordPercentCalc(maxCoord, aPercentageBasis);
     }
     aGridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize;
   }
   // min sizing
@@ -4389,16 +4392,24 @@ nsGridContainerFrame::Tracks::ResolveInt
   // Setup track selector for step 2.3:
   const auto maxContentMinSelector =
     aConstraint == SizingConstraint::eMaxContent ?
     (TrackSize::eMaxContentMinSizing | TrackSize::eAutoMinSizing) :
     TrackSize::eMaxContentMinSizing;
   iter.Reset();
   for (; !iter.AtEnd(); iter.Next()) {
     auto& gridItem = aGridItems[iter.GridItemIndex()];
+
+    // Check if we need to apply "Automatic Minimum Size" and cache it.
+    MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
+               "Why is eApplyAutoMinSize set already?");
+    if (gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) {
+      gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize;
+    }
+
     const GridArea& area = gridItem.mArea;
     const LineRange& lineRange = area.*aRange;
     uint32_t span = lineRange.Extent();
     if (span == 1) {
       // Step 1. Size tracks to fit non-spanning items.
       if (ResolveIntrinsicSizeStep1(aState, aFunctions, aPercentageBasis,
                                     aConstraint, lineRange, gridItem)) {
         gridItem.mState[mAxis] |= ItemState::eIsFlexing;
@@ -4414,19 +4425,19 @@ nsGridContainerFrame::Tracks::ResolveInt
           for (uint32_t i = stateBitsPerSpan.Length(); i < len; ++i) {
             stateBitsPerSpan.AppendElement(TrackSize::StateBits(0));
           }
         }
         stateBitsPerSpan[span] |= state;
         CachedIntrinsicSizes cache;
         // Calculate data for "Automatic Minimum Size" clamping, if needed.
         bool needed = ((state & TrackSize::eIntrinsicMinSizing) ||
-                       aConstraint == SizingConstraint::eNoConstraint);
-        if (needed && TrackSize::IsDefiniteMaxSizing(state) &&
-            gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+                       aConstraint == SizingConstraint::eNoConstraint) &&
+                      (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize);
+        if (needed && TrackSize::IsDefiniteMaxSizing(state)) {
           nscoord minSizeClamp = 0;
           for (auto i = lineRange.mStart, end = lineRange.mEnd; i < end; ++i) {
             auto maxCoord = aFunctions.MaxSizingFor(i);
             minSizeClamp +=
               nsRuleNode::ComputeCoordPercentCalc(maxCoord, aPercentageBasis);
           }
           minSizeClamp += mGridGap * (span - 1);
           cache.mMinSizeClamp = minSizeClamp;
@@ -4452,21 +4463,24 @@ nsGridContainerFrame::Tracks::ResolveInt
         step2Items.AppendElement(
           Step2ItemData({span, state, lineRange, minSize,
                          minContent, maxContent, *iter}));
       } else {
         if (state & TrackSize::eFlexMaxSizing) {
           gridItem.mState[mAxis] |= ItemState::eIsFlexing;
         } else if (aConstraint == SizingConstraint::eNoConstraint &&
                    TrackSize::IsDefiniteMaxSizing(state) &&
-                   gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) {
+                   (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize)) {
           gridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize;
         }
       }
     }
+    MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eClampMarginBoxMinSize) ||
+               (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize),
+               "clamping only applies to Automatic Minimum Size");
   }
 
   // Step 2.
   if (maxSpan) {
     // Sort the collected items on span length, shortest first.
     std::stable_sort(step2Items.begin(), step2Items.end(),
                      Step2ItemData::IsSpanLessThan);