Title: [292079] trunk
Revision
292079
Author
mattwood...@apple.com
Date
2022-03-29 16:04:15 -0700 (Tue, 29 Mar 2022)

Log Message

Don't mutate children during RenderGrid::computeIntrinsicLogicalWidths unless we're about to re-layout.
https://bugs.webkit.org/show_bug.cgi?id=237732

Reviewed by Dean Jackson.

Source/WebCore:

Test: fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html

* rendering/GridTrackSizingAlgorithm.cpp:
(WebCore::GridTrackSizingAlgorithm::gridAreaBreadthForChild const):
(WebCore::GridTrackSizingAlgorithm::advanceNextState):
(WebCore::GridTrackSizingAlgorithm::isValidTransition const):
* rendering/GridTrackSizingAlgorithm.h:
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::layoutBlock):
(WebCore::RenderGrid::computeIntrinsicLogicalWidths const):
* rendering/RenderGrid.h:

computeIntrinsicLogicalWidths can re-layout children (via performGridItemsPreLayout, as well as during
the track sizing algorithm), and does so using the estimated track sizes. This can be incorrect, and if
we're not about to do a full layout on this RenderGrid, it can leave the children in an invalid state.

This caches the intrinsic sizes when we do a full layout, so that we can use these values instead when
we just want to query the RenderGrid without mutating anything.

LayoutTests:

Don't mutate children during computeIntrinsicWidth

* TestExpectations:
* fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html: Added.
* fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html: Added.
* platform/ios/TestExpectations:

Marked existing WPT as passing on MacOS (since we run layout multiple times there).
Added new test for this implementation-specific bug.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (292078 => 292079)


--- trunk/LayoutTests/ChangeLog	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/LayoutTests/ChangeLog	2022-03-29 23:04:15 UTC (rev 292079)
@@ -1,3 +1,20 @@
+2022-03-29  Matt Woodrow  <mattwood...@apple.com>
+
+        Don't mutate children during RenderGrid::computeIntrinsicLogicalWidths unless we're about to re-layout.
+        https://bugs.webkit.org/show_bug.cgi?id=237732
+
+        Reviewed by Dean Jackson.
+
+        Don't mutate children during computeIntrinsicWidth
+
+        * TestExpectations:
+        * fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html: Added.
+        * fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html: Added.
+        * platform/ios/TestExpectations:
+
+        Marked existing WPT as passing on MacOS (since we run layout multiple times there).
+        Added new test for this implementation-specific bug.
+
 2022-03-29  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         [Cocoa] Automatically relayout the page when new fonts are installed

Modified: trunk/LayoutTests/TestExpectations (292078 => 292079)


--- trunk/LayoutTests/TestExpectations	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/LayoutTests/TestExpectations	2022-03-29 23:04:15 UTC (rev 292079)
@@ -1362,7 +1362,6 @@
 webkit.org/b/216145 imported/w3c/web-platform-tests/css/css-grid/alignment/grid-item-no-aspect-ratio-stretch-6.html [ ImageOnlyFailure ]
 
 imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-auto-repeat-dynamic-001.html [ ImageOnlyFailure ]
-imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-repeat-max-width-001.html [ ImageOnlyFailure ]
 
 webkit.org/b/234879 imported/w3c/web-platform-tests/css/css-grid/grid-items/grid-intrinsic-maximums.html [ ImageOnlyFailure ]
 imported/w3c/web-platform-tests/css/css-grid/grid-items/grid-item-inline-contribution-003.html [ ImageOnlyFailure ]

Added: trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html (0 => 292079)


--- trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children-expected.html	2022-03-29 23:04:15 UTC (rev 292079)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="background: red; max-width: 200px; padding: 20px;">
+    <div style="background: yellowgreen; display: grid; align-items: baseline;">
+        <span>Very long example text for testing line break which will not happen due to the bug</span>
+    </div>
+</div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html (0 => 292079)


--- trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html	2022-03-29 23:04:15 UTC (rev 292079)
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<body>
+<div style="display: grid;">
+    <div style="background: red; max-width: 200px; padding: 20px; display: flex;">
+        <div style="background: yellowgreen; display: grid; align-items: baseline;">
+            <span>Very long example text for testing line break which will not happen due to the bug</span>
+        </div>
+    </div>
+</div>
+</body>
+</html>

Modified: trunk/LayoutTests/platform/ios/TestExpectations (292078 => 292079)


--- trunk/LayoutTests/platform/ios/TestExpectations	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2022-03-29 23:04:15 UTC (rev 292079)
@@ -3147,6 +3147,8 @@
 webkit.org/b/212226 imported/w3c/web-platform-tests/css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-008.html [ ImageOnlyFailure ]
 webkit.org/b/212227 imported/w3c/web-platform-tests/css/css-grid/alignment/self-baseline/grid-self-baseline-changes-grid-area-size-002.html [ ImageOnlyFailure ]
 
+imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-repeat-max-width-001.html [ ImageOnlyFailure ]
+
 fast/text/text-styles/-apple-system [ Pass ]
 
 webkit.org/b/214155 imported/w3c/web-platform-tests/html/cross-origin-embedder-policy/blob.https.html [ Pass Failure ]

Modified: trunk/Source/WebCore/ChangeLog (292078 => 292079)


--- trunk/Source/WebCore/ChangeLog	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/ChangeLog	2022-03-29 23:04:15 UTC (rev 292079)
@@ -1,3 +1,29 @@
+2022-03-29  Matt Woodrow  <mattwood...@apple.com>
+
+        Don't mutate children during RenderGrid::computeIntrinsicLogicalWidths unless we're about to re-layout.
+        https://bugs.webkit.org/show_bug.cgi?id=237732
+
+        Reviewed by Dean Jackson.
+
+        Test: fast/css-grid-layout/compute-intrinsic-logical-widths-should-not-mutate-children.html
+
+        * rendering/GridTrackSizingAlgorithm.cpp:
+        (WebCore::GridTrackSizingAlgorithm::gridAreaBreadthForChild const):
+        (WebCore::GridTrackSizingAlgorithm::advanceNextState):
+        (WebCore::GridTrackSizingAlgorithm::isValidTransition const):
+        * rendering/GridTrackSizingAlgorithm.h:
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::layoutBlock):
+        (WebCore::RenderGrid::computeIntrinsicLogicalWidths const):
+        * rendering/RenderGrid.h:
+
+        computeIntrinsicLogicalWidths can re-layout children (via performGridItemsPreLayout, as well as during
+        the track sizing algorithm), and does so using the estimated track sizes. This can be incorrect, and if
+        we're not about to do a full layout on this RenderGrid, it can leave the children in an invalid state.
+
+        This caches the intrinsic sizes when we do a full layout, so that we can use these values instead when
+        we just want to query the RenderGrid without mutating anything.
+
 2022-03-29  Myles C. Maxfield  <mmaxfi...@apple.com>
 
         [Cocoa] Automatically relayout the page when new fonts are installed

Modified: trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp (292078 => 292079)


--- trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.cpp	2022-03-29 23:04:15 UTC (rev 292079)
@@ -623,11 +623,11 @@
     // To determine the column track's size based on an orthogonal grid item we need it's logical
     // height, which may depend on the row track's size. It's possible that the row tracks sizing
     // logic has not been performed yet, so we will need to do an estimation.
-    if (direction == ForRows && (m_sizingState == ColumnSizingFirstIteration || m_sizingState == ColumnSizingSecondIteration)) {
+    if (direction == ForRows && (m_sizingState == ColumnSizingFirstIteration || m_sizingState == ColumnSizingExtraIterationForSizeContainment || m_sizingState == ColumnSizingSecondIteration)) {
         ASSERT(GridLayoutFunctions::isOrthogonalChild(*m_renderGrid, child));
         // FIXME (jfernandez) Content Alignment should account for this heuristic.
         // https://github.com/w3c/csswg-drafts/issues/2697
-        if (m_sizingState == ColumnSizingFirstIteration)
+        if (m_sizingState == ColumnSizingFirstIteration || m_sizingState == ColumnSizingExtraIterationForSizeContainment)
             return estimatedGridAreaBreadthForChild(child, ForRows);
         addContentAlignmentOffset = true;
     }
@@ -1410,6 +1410,9 @@
 {
     switch (m_sizingState) {
     case ColumnSizingFirstIteration:
+        m_sizingState = m_strategy->isComputingSizeContainment() ? ColumnSizingExtraIterationForSizeContainment : RowSizingFirstIteration;
+        return;
+    case ColumnSizingExtraIterationForSizeContainment:
         m_sizingState = RowSizingFirstIteration;
         return;
     case RowSizingFirstIteration:
@@ -1433,6 +1436,7 @@
 {
     switch (m_sizingState) {
     case ColumnSizingFirstIteration:
+    case ColumnSizingExtraIterationForSizeContainment:
     case ColumnSizingSecondIteration:
         return m_direction == ForColumns;
     case RowSizingFirstIteration:

Modified: trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h (292078 => 292079)


--- trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/GridTrackSizingAlgorithm.h	2022-03-29 23:04:15 UTC (rev 292079)
@@ -241,6 +241,7 @@
 
     enum SizingState {
         ColumnSizingFirstIteration,
+        ColumnSizingExtraIterationForSizeContainment,
         RowSizingFirstIteration,
         RowSizingExtraIterationForSizeContainment,
         ColumnSizingSecondIteration,

Modified: trunk/Source/WebCore/rendering/RenderGrid.cpp (292078 => 292079)


--- trunk/Source/WebCore/rendering/RenderGrid.cpp	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/RenderGrid.cpp	2022-03-29 23:04:15 UTC (rev 292079)
@@ -280,8 +280,16 @@
         // logical width is always definite as the above call to updateLogicalWidth() properly resolves intrinsic 
         // sizes. We cannot do the same for heights though because many code paths inside updateLogicalHeight() require 
         // a previous call to setLogicalHeight() to resolve heights properly (like for positioned items for example).
-        computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
+        if (shouldApplySizeContainment(*this))
+            computeTrackSizesForIndefiniteSize(m_trackSizingAlgorithm, ForColumns);
+        else
+            computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
 
+        m_minContentSize = m_trackSizingAlgorithm.minContentSize();
+        m_maxContentSize = m_trackSizingAlgorithm.maxContentSize();
+        if (shouldApplySizeContainment(*this))
+            computeTrackSizesForDefiniteSize(ForColumns, availableSpaceForColumns);
+
         // 1.5- Compute Content Distribution offsets for column tracks
         computeContentPositionAndDistributionOffset(ForColumns, m_trackSizingAlgorithm.freeSpace(ForColumns).value(), nonCollapsedTracks(ForColumns));
 
@@ -459,24 +467,30 @@
     LayoutUnit childMaxWidth;
     bool hadExcludedChildren = computePreferredWidthsForExcludedChildren(childMinWidth, childMaxWidth);
 
-    GridTrackSizingAlgorithm algorithm(this, const_cast<Grid&>(m_grid));
-    placeItemsOnGrid(algorithm, std::nullopt);
+    if (needsLayout()) {
+        GridTrackSizingAlgorithm algorithm(this, const_cast<Grid&>(m_grid));
+        placeItemsOnGrid(algorithm, std::nullopt);
 
-    performGridItemsPreLayout(algorithm);
+        performGridItemsPreLayout(algorithm);
 
-    if (m_baselineItemsCached)
-        algorithm.copyBaselineItemsCache(m_trackSizingAlgorithm, GridRowAxis);
-    else {
-        for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
-            if (child->isOutOfFlowPositioned())
-                continue;
-            if (isBaselineAlignmentForChild(*child, GridRowAxis))
-                algorithm.cacheBaselineAlignedItem(*child, GridRowAxis);
+        if (m_baselineItemsCached)
+            algorithm.copyBaselineItemsCache(m_trackSizingAlgorithm, GridRowAxis);
+        else {
+            for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) {
+                if (child->isOutOfFlowPositioned())
+                    continue;
+                if (isBaselineAlignmentForChild(*child, GridRowAxis))
+                    algorithm.cacheBaselineAlignedItem(*child, GridRowAxis);
+            }
         }
+
+        computeTrackSizesForIndefiniteSize(algorithm, ForColumns, &minLogicalWidth, &maxLogicalWidth);
+    } else {
+        LayoutUnit totalGuttersSize = guttersSize(m_grid, ForColumns, 0, numTracks(ForColumns), std::nullopt);
+        minLogicalWidth = *m_minContentSize + totalGuttersSize;
+        maxLogicalWidth = *m_maxContentSize + totalGuttersSize;
     }
 
-    computeTrackSizesForIndefiniteSize(algorithm, ForColumns, &minLogicalWidth, &maxLogicalWidth);
-
     if (hadExcludedChildren) {
         minLogicalWidth = std::max(minLogicalWidth, childMinWidth);
         maxLogicalWidth = std::max(maxLogicalWidth, childMaxWidth);

Modified: trunk/Source/WebCore/rendering/RenderGrid.h (292078 => 292079)


--- trunk/Source/WebCore/rendering/RenderGrid.h	2022-03-29 22:54:07 UTC (rev 292078)
+++ trunk/Source/WebCore/rendering/RenderGrid.h	2022-03-29 23:04:15 UTC (rev 292079)
@@ -243,6 +243,9 @@
     OutOfFlowPositionsMap m_outOfFlowItemColumn;
     OutOfFlowPositionsMap m_outOfFlowItemRow;
 
+    std::optional<LayoutUnit> m_minContentSize;
+    std::optional<LayoutUnit> m_maxContentSize;
+
     bool m_hasAnyOrthogonalItem {false};
     bool m_hasAspectRatioBlockSizeDependentItem { false };
     bool m_baselineItemsCached {false};
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to