Changeset 291952 in webkit


Ignore:
Timestamp:
Mar 27, 2022 1:24:03 PM (4 months ago)
Author:
Matt Woodrow
Message:

Lazily allocate backing store for grid columns.
https://bugs.webkit.org/show_bug.cgi?id=212201

Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

  • web-platform-tests/css/css-grid/grid-definition/grid-limits-001-expected.txt: Added.

Add passing expectations file for previously skipped test.

Source/WebCore:

Existing WPT test grid-limits-001.html marked as passing.

  • rendering/Grid.cpp:

(WebCore::Grid::ensureGridSize):
(WebCore::Grid::ensureStorageForRow):
(WebCore::Grid::insert):
(WebCore::Grid::cell const):

Only grow the first row's column storage (since we use this
to remember the column count) and lazily grow the others when
we try write to them.

(WebCore::GridIterator::GridIterator):
(WebCore::GridIterator::nextGridItem):
(WebCore::GridIterator::isEmptyAreaEnough const):
(WebCore::GridIterator::nextEmptyGridArea):

  • rendering/Grid.h:

Changes GridIterator to use the Grid API rather than directly
accessing the inner Vector using 'friend'. This makes it easier to
ensure that we never access areas outside of our lazy allocations.

LayoutTests:

Remove skip annotation for test grid-limits-001 that now passes.

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r291951 r291952  
     12022-03-27  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Lazily allocate backing store for grid columns.
     4        https://bugs.webkit.org/show_bug.cgi?id=212201
     5
     6        Reviewed by Dean Jackson.
     7
     8        * TestExpectations:
     9
     10        Remove skip annotation for test grid-limits-001 that now passes.
     11
    1122022-03-27  Alan Bujtas  <zalan@apple.com>
    213
  • trunk/LayoutTests/TestExpectations

    r291949 r291952  
    42514251webkit.org/b/209460 imported/w3c/web-platform-tests/css/css-grid/abspos/descendant-static-position-002.html [ ImageOnlyFailure ]
    42524252webkit.org/b/209460 imported/w3c/web-platform-tests/css/css-grid/abspos/descendant-static-position-003.html [ ImageOnlyFailure ]
    4253 webkit.org/b/212201 imported/w3c/web-platform-tests/css/css-grid/grid-definition/grid-limits-001.html [ Skip ]
    42544253webkit.org/b/212246 imported/w3c/web-platform-tests/css/css-grid/alignment/grid-baseline-align-cycles-001.html [ ImageOnlyFailure ]
    42554254webkit.org/b/231021 imported/w3c/web-platform-tests/css/css-grid/alignment/grid-inline-baseline.html [ ImageOnlyFailure ]
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r291949 r291952  
     12022-03-27  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Lazily allocate backing store for grid columns.
     4        https://bugs.webkit.org/show_bug.cgi?id=212201
     5
     6        Reviewed by Dean Jackson.
     7
     8        * web-platform-tests/css/css-grid/grid-definition/grid-limits-001-expected.txt: Added.
     9
     10        Add passing expectations file for previously skipped test.
     11
    1122022-03-26  Noam Rosenthal  <noam@webkit.org>
    213
  • trunk/Source/WebCore/ChangeLog

    r291951 r291952  
     12022-03-27  Matt Woodrow  <mattwoodrow@apple.com>
     2
     3        Lazily allocate backing store for grid columns.
     4        https://bugs.webkit.org/show_bug.cgi?id=212201
     5
     6        Reviewed by Dean Jackson.
     7
     8        Existing WPT test grid-limits-001.html marked as passing.
     9
     10        * rendering/Grid.cpp:
     11        (WebCore::Grid::ensureGridSize):
     12        (WebCore::Grid::ensureStorageForRow):
     13        (WebCore::Grid::insert):
     14        (WebCore::Grid::cell const):
     15
     16        Only grow the first row's column storage (since we use this
     17        to remember the column count) and lazily grow the others when
     18        we try write to them.
     19
     20        (WebCore::GridIterator::GridIterator):
     21        (WebCore::GridIterator::nextGridItem):
     22        (WebCore::GridIterator::isEmptyAreaEnough const):
     23        (WebCore::GridIterator::nextEmptyGridArea):
     24        * rendering/Grid.h:
     25
     26        Changes GridIterator to use the Grid API rather than directly
     27        accessing the inner Vector using 'friend'. This makes it easier to
     28        ensure that we never access areas outside of our lazy allocations.
     29
    1302022-03-27  Alan Bujtas  <zalan@apple.com>
    231
  • trunk/Source/WebCore/rendering/Grid.cpp

    r290572 r291952  
    5252    if (maximumRowSize > oldRowSize) {
    5353        m_grid.grow(maximumRowSize);
    54         for (size_t row = oldRowSize; row < maximumRowSize; ++row)
    55             m_grid[row].grow(oldColumnSize);
    56     }
    57 
    58     if (maximumColumnSize > oldColumnSize) {
    59         for (size_t row = 0; row < numTracks(ForRows); ++row)
    60             m_grid[row].grow(maximumColumnSize);
    61     }
     54    }
     55
     56    // Just grow the first row for now so that we know the requested size,
     57    // and we'll lazily allocate the others when they get used.
     58    if (maximumColumnSize > oldColumnSize && maximumRowSize) {
     59        m_grid[0].grow(maximumColumnSize);
     60    }
     61}
     62
     63void Grid::ensureStorageForRow(unsigned row)
     64{
     65    m_grid[row].grow(m_grid[0].size());
    6266}
    6367
     
    7478
    7579    for (auto row : clampedArea.rows) {
     80        ensureStorageForRow(row);
    7681        for (auto column : clampedArea.columns)
    7782            m_grid[row][column].append(child);
     
    8085    setGridItemArea(child, clampedArea);
    8186    return clampedArea;
     87}
     88
     89const GridCell& Grid::cell(unsigned row, unsigned column) const
     90{
     91    // Storage for rows other than the first is lazily allocated. We can
     92    // just return a fake entry if the request is outside the allocated area,
     93    // since it must be empty.
     94    static const NeverDestroyed<GridCell> emptyCell;
     95    if (row && m_grid[row].size() <= column)
     96        return emptyCell;
     97
     98    return m_grid[row][column];
    8299}
    83100
     
    192209
    193210GridIterator::GridIterator(const Grid& grid, GridTrackSizingDirection direction, unsigned fixedTrackIndex, unsigned varyingTrackIndex)
    194     : m_grid(grid.m_grid)
     211    : m_grid(grid)
    195212    , m_direction(direction)
    196213    , m_rowIndex((direction == ForColumns) ? varyingTrackIndex : fixedTrackIndex)
     
    198215    , m_childIndex(0)
    199216{
    200     ASSERT(!m_grid.isEmpty());
    201     ASSERT(!m_grid[0].isEmpty());
    202     ASSERT(m_rowIndex < m_grid.size());
    203     ASSERT(m_columnIndex < m_grid[0].size());
     217    ASSERT(m_grid.numTracks(ForRows));
     218    ASSERT(m_grid.numTracks(ForColumns));
     219    ASSERT(m_rowIndex < m_grid.numTracks(ForRows));
     220    ASSERT(m_columnIndex < m_grid.numTracks(ForColumns));
    204221}
    205222
    206223RenderBox* GridIterator::nextGridItem()
    207224{
    208     ASSERT(!m_grid.isEmpty());
    209     ASSERT(!m_grid[0].isEmpty());
     225    ASSERT(m_grid.numTracks(ForRows));
     226    ASSERT(m_grid.numTracks(ForColumns));
    210227
    211228    unsigned& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
    212     const unsigned endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
     229    const unsigned endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.numTracks(ForRows) : m_grid.numTracks(ForColumns);
    213230    for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
    214         const auto& children = m_grid[m_rowIndex][m_columnIndex];
     231        const auto& children = m_grid.cell(m_rowIndex, m_columnIndex);
    215232        if (m_childIndex < children.size())
    216233            return children[m_childIndex++].get();
     
    223240bool GridIterator::isEmptyAreaEnough(unsigned rowSpan, unsigned columnSpan) const
    224241{
    225     ASSERT(!m_grid.isEmpty());
    226     ASSERT(!m_grid[0].isEmpty());
     242    ASSERT(m_grid.numTracks(ForRows));
     243    ASSERT(m_grid.numTracks(ForColumns));
    227244
    228245    // Ignore cells outside current grid as we will grow it later if needed.
    229     unsigned maxRows = std::min<unsigned>(m_rowIndex + rowSpan, m_grid.size());
    230     unsigned maxColumns = std::min<unsigned>(m_columnIndex + columnSpan, m_grid[0].size());
     246    unsigned maxRows = std::min<unsigned>(m_rowIndex + rowSpan, m_grid.numTracks(ForRows));
     247    unsigned maxColumns = std::min<unsigned>(m_columnIndex + columnSpan, m_grid.numTracks(ForColumns));
    231248
    232249    // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spanning areas to be small.
    233250    for (unsigned row = m_rowIndex; row < maxRows; ++row) {
    234251        for (unsigned column = m_columnIndex; column < maxColumns; ++column) {
    235             auto& children = m_grid[row][column];
     252            auto& children = m_grid.cell(row, column);
    236253            if (!children.isEmpty())
    237254                return false;
     
    244261std::unique_ptr<GridArea> GridIterator::nextEmptyGridArea(unsigned fixedTrackSpan, unsigned varyingTrackSpan)
    245262{
    246     ASSERT(!m_grid.isEmpty());
    247     ASSERT(!m_grid[0].isEmpty());
     263    ASSERT(m_grid.numTracks(ForRows));
     264    ASSERT(m_grid.numTracks(ForColumns));
    248265    ASSERT(fixedTrackSpan >= 1);
    249266    ASSERT(varyingTrackSpan >= 1);
    250267
    251     if (m_grid.isEmpty())
     268    if (!m_grid.hasGridItems())
    252269        return nullptr;
    253270
     
    256273
    257274    unsigned& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
    258     const unsigned endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
     275    const unsigned endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.numTracks(ForRows) : m_grid.numTracks(ForColumns);
    259276    for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
    260277        if (isEmptyAreaEnough(rowSpan, columnSpan)) {
  • trunk/Source/WebCore/rendering/Grid.h

    r290077 r291952  
    6060    GridSpan gridItemSpan(const RenderBox&, GridTrackSizingDirection) const;
    6161
    62     const GridCell& cell(unsigned row, unsigned column) const { return m_grid[row][column]; }
     62    const GridCell& cell(unsigned row, unsigned column) const;
    6363
    6464    unsigned explicitGridStart(GridTrackSizingDirection) const;
     
    8787
    8888private:
    89     friend class GridIterator;
     89    void ensureStorageForRow(unsigned row);
    9090
    9191    OrderIterator m_orderIterator;
     
    129129
    130130private:
    131     const GridAsMatrix& m_grid;
     131    const Grid& m_grid;
    132132    GridTrackSizingDirection m_direction;
    133133    unsigned m_rowIndex;
Note: See TracChangeset for help on using the changeset viewer.