Ignore:
Timestamp:
Feb 12, 2015, 8:14:16 AM (11 years ago)
Author:
svillar@igalia.com
Message:

[CSS Grid Layout] Invalid initialization of track sizes with non spanning grid items
https://bugs.webkit.org/show_bug.cgi?id=140763

Reviewed by Antti Koivisto.

Source/WebCore:

Content sized tracks with non-spanning grid items were not
properly sized because the growth limit was sometimes infinity
(-1) after calling resolveContentBasedTrackSizingFunctions() when
it should not. This patch adds an special initialization phase for
non-spanning grid items as the new track sizing algorithm
describes.

Granted, that was handled in the old algorithm in
distributeSpaceToTracks() as a special case. The problem is that
it regressed after the optimization added in r173868 because that
method is no longer called when the space to distribute is 0.

That's why we could fix this by allowing calls to
distributeSpaceToTracks() with spaceToDistribute>=0 but by fixing
it with an explicit initialization our implementation becomes
closer to the new algorithm and the initialization is now explicit
in the code instead of a side effect of calling
distributeSpaceToTracks() with no space to be distributed. It also
brings a slight performance improvement as we save sorts and hash
lookups.

I also took the change to add caching to several GridTrackSize
methods that were hot on the profiler (each one accounted for ~1%
of the total time, now they account for ~0.3% each).

Test: fast/css-grid-layout/grid-initialize-span-one-items.html

  • rendering/RenderGrid.cpp:

(WebCore::GridItemWithSpan::span): New helper method for ASSERTs.
(WebCore::RenderGrid::resolveContentBasedTrackSizingFunctions):
Exclude non spanning grid items from the calls to
resolveContentBasedTrackSizingFunctionsForItems().
(WebCore::RenderGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems):
New method to resolve track sizes only using non-spanning grid
items.
(WebCore::RenderGrid::resolveContentBasedTrackSizingFunctionsForItems):
Ensure that it isn't called for non-spanning grid items.

  • rendering/RenderGrid.h:
  • rendering/style/GridTrackSize.h:

(WebCore::GridTrackSize::GridTrackSize): Cache return values.
(WebCore::GridTrackSize::setLength): Ditto.
(WebCore::GridTrackSize::setMinMax): Ditto.
(WebCore::GridTrackSize::cacheMinMaxTrackBreadthTypes): New method
that caches the return values for hasXXXTrackBreadth() methods.
(WebCore::GridTrackSize::hasMinOrMaxContentMinTrackBreadth): Use
the cached return value.
(WebCore::GridTrackSize::hasMaxContentMaxTrackBreadth): Ditto.
(WebCore::GridTrackSize::hasMinContentMaxTrackBreadth): Ditto.
(WebCore::GridTrackSize::hasMinOrMaxContentMaxTrackBreadth): Ditto.
(WebCore::GridTrackSize::hasMaxContentMinTrackBreadth): Ditto.
(WebCore::GridTrackSize::hasMinContentMinTrackBreadth): Ditto.
(WebCore::GridTrackSize::hasMinContentMinTrackBreadthAndMinOrMaxContentMaxTrackBreadth):
Ditto.
(WebCore::GridTrackSize::hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth):
Ditto.

LayoutTests:

  • fast/css-grid-layout/grid-content-sized-columns-resolution-expected.txt:
  • fast/css-grid-layout/grid-content-sized-columns-resolution.html:
  • fast/css-grid-layout/grid-initialize-span-one-items-expected.txt: Added.
  • fast/css-grid-layout/grid-initialize-span-one-items.html: Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderGrid.cpp

    r179824 r179987  
    585585    RenderBox& gridItem() const { return m_gridItem; }
    586586    GridCoordinate coordinate() const { return m_coordinate; }
     587#if !ASSERT_DISABLED
     588    size_t span() const { return m_span; }
     589#endif
    587590
    588591    bool operator<(const GridItemWithSpan other) const
     
    620623    for (auto trackIndex : sizingData.contentSizedTracksIndex) {
    621624        GridIterator iterator(m_grid, direction, trackIndex);
     625        GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
    622626
    623627        while (RenderBox* gridItem = iterator.nextGridItem()) {
    624628            if (itemsSet.add(gridItem).isNewEntry) {
    625629                const GridCoordinate& coordinate = cachedGridCoordinate(*gridItem);
    626                 // We should not include items spanning more than one track that span tracks with flexible sizing functions.
    627                 if (integerSpanForDirection(coordinate, direction) == 1 || !spanningItemCrossesFlexibleSizedTracks(coordinate, direction))
     630                if (integerSpanForDirection(coordinate, direction) == 1)
     631                    resolveContentBasedTrackSizingFunctionsForNonSpanningItems(direction, coordinate, *gridItem, track, sizingData.columnTracks);
     632                else if (!spanningItemCrossesFlexibleSizedTracks(coordinate, direction))
    628633                    sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*gridItem, coordinate, direction));
    629634            }
     
    646651}
    647652
     653void RenderGrid::resolveContentBasedTrackSizingFunctionsForNonSpanningItems(GridTrackSizingDirection direction, const GridCoordinate& coordinate, RenderBox& gridItem, GridTrack& track, Vector<GridTrack>& columnTracks)
     654{
     655    const GridResolvedPosition trackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPosition;
     656    GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt());
     657
     658    if (trackSize.hasMinContentMinTrackBreadth())
     659        track.setBaseSize(std::max(track.baseSize(), minContentForChild(gridItem, direction, columnTracks)));
     660    else if (trackSize.hasMaxContentMinTrackBreadth())
     661        track.setBaseSize(std::max(track.baseSize(), maxContentForChild(gridItem, direction, columnTracks)));
     662
     663    if (trackSize.hasMinContentMaxTrackBreadth())
     664        track.setGrowthLimit(std::max(track.growthLimit(), minContentForChild(gridItem, direction, columnTracks)));
     665    else if (trackSize.hasMaxContentMaxTrackBreadth())
     666        track.setGrowthLimit(std::max(track.growthLimit(), maxContentForChild(gridItem, direction, columnTracks)));
     667}
     668
    648669void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, GridItemWithSpan& gridItemWithSpan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, FilterFunction growAboveMaxBreadthFilterFunction)
    649670{
     671    ASSERT(gridItemWithSpan.span() > 1);
    650672    const GridCoordinate& coordinate = gridItemWithSpan.coordinate();
    651673    const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPosition;
Note: See TracChangeset for help on using the changeset viewer.