| Index: Source/core/rendering/RenderGrid.cpp
|
| diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp
|
| index 9de8da1819b6546d3b10c4c92cbe74e360e9ec30..86e84fae10379453d1c6c6678a48a950d2d74955 100644
|
| --- a/Source/core/rendering/RenderGrid.cpp
|
| +++ b/Source/core/rendering/RenderGrid.cpp
|
| @@ -146,6 +146,24 @@ private:
|
| size_t m_childIndex;
|
| };
|
|
|
| +struct RenderGrid::GridSizingData {
|
| + WTF_MAKE_NONCOPYABLE(GridSizingData);
|
| +public:
|
| + GridSizingData(size_t gridColumnCount, size_t gridRowCount)
|
| + : columnTracks(gridColumnCount)
|
| + , rowTracks(gridRowCount)
|
| + {
|
| + }
|
| +
|
| + Vector<GridTrack> columnTracks;
|
| + Vector<GridTrack> rowTracks;
|
| + Vector<size_t> contentSizedTracksIndex;
|
| +
|
| + // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free.
|
| + Vector<LayoutUnit> distributeTrackVector;
|
| + Vector<GridTrack*> filteredTracks;
|
| +};
|
| +
|
| RenderGrid::RenderGrid(Element* element)
|
| : RenderBlock(element)
|
| , m_gridIsDirty(true)
|
| @@ -353,11 +371,11 @@ LayoutUnit RenderGrid::computePreferredTrackWidth(const GridLength& gridLength,
|
| return 0;
|
| }
|
|
|
| -void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks)
|
| +void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction, GridSizingData& sizingData)
|
| {
|
| LayoutUnit availableLogicalSpace = (direction == ForColumns) ? availableLogicalWidth() : availableLogicalHeight(IncludeMarginBorderPadding);
|
| - Vector<GridTrack>& tracks = (direction == ForColumns) ? columnTracks : rowTracks;
|
| - Vector<size_t> contentSizedTracks;
|
| + Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTracks : sizingData.rowTracks;
|
| + sizingData.contentSizedTracksIndex.shrink(0);
|
| for (size_t i = 0; i < tracks.size(); ++i) {
|
| GridTrack& track = tracks[i];
|
| const GridTrackSize& trackSize = gridTrackSize(direction, i);
|
| @@ -370,11 +388,11 @@ void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction,
|
| track.m_maxBreadth = std::max(track.m_maxBreadth, track.m_usedBreadth);
|
|
|
| if (trackSize.isContentSized())
|
| - contentSizedTracks.append(i);
|
| + sizingData.contentSizedTracksIndex.append(i);
|
| }
|
|
|
| - if (!contentSizedTracks.isEmpty())
|
| - resolveContentBasedTrackSizingFunctions(direction, columnTracks, rowTracks, contentSizedTracks, availableLogicalSpace);
|
| + if (!sizingData.contentSizedTracksIndex.isEmpty())
|
| + resolveContentBasedTrackSizingFunctions(direction, sizingData, availableLogicalSpace);
|
|
|
| for (size_t i = 0; i < tracks.size(); ++i) {
|
| ASSERT(tracks[i].m_maxBreadth != infinity);
|
| @@ -389,7 +407,7 @@ void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction,
|
| for (size_t i = 0; i < tracksSize; ++i)
|
| tracksForDistribution[i] = tracks.data() + i;
|
|
|
| - distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, availableLogicalSpace);
|
| + distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, sizingData, availableLogicalSpace);
|
|
|
| // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
|
|
|
| @@ -563,54 +581,54 @@ LayoutUnit RenderGrid::maxContentForChild(RenderBox* child, TrackSizingDirection
|
| return logicalContentHeightForChild(child, columnTracks);
|
| }
|
|
|
| -void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, const Vector<size_t>& contentSizedTracks, LayoutUnit& availableLogicalSpace)
|
| +void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
|
| {
|
| // FIXME: Split the grid tracks into groups that doesn't overlap a <flex> grid track (crbug.com/235258).
|
|
|
| // FIXME: Per step 2 of the specification, we should order the grid items by increasing span.
|
|
|
| - for (size_t i = 0; i < contentSizedTracks.size(); ++i) {
|
| - GridIterator iterator(m_grid, direction, contentSizedTracks[i]);
|
| + for (size_t i = 0; i < sizingData.contentSizedTracksIndex.size(); ++i) {
|
| + GridIterator iterator(m_grid, direction, sizingData.contentSizedTracksIndex[i]);
|
| while (RenderBox* gridItem = iterator.nextGridItem()) {
|
| - resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, gridItem, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::minContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
|
| - resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, gridItem, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
|
| - resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, gridItem, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::minContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
|
| - resolveContentBasedTrackSizingFunctionsForItems(direction, columnTracks, rowTracks, gridItem, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
|
| + resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::minContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
|
| + resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
|
| + resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::minContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
|
| + resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
|
| }
|
|
|
| - GridTrack& track = (direction == ForColumns) ? columnTracks[i] : rowTracks[i];
|
| + GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[i] : sizingData.rowTracks[i];
|
| if (track.m_maxBreadth == infinity)
|
| track.m_maxBreadth = track.m_usedBreadth;
|
| }
|
| }
|
|
|
| -void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, RenderBox* gridItem, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction)
|
| +void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection direction, GridSizingData& sizingData, RenderBox* gridItem, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction)
|
| {
|
| const GridCoordinate coordinate = cachedGridCoordinate(gridItem);
|
| const size_t initialTrackIndex = (direction == ForColumns) ? coordinate.columns.initialPositionIndex : coordinate.rows.initialPositionIndex;
|
| const size_t finalTrackIndex = (direction == ForColumns) ? coordinate.columns.finalPositionIndex : coordinate.rows.finalPositionIndex;
|
|
|
| - Vector<GridTrack*> tracks;
|
| + sizingData.filteredTracks.shrink(0);
|
| for (size_t trackIndex = initialTrackIndex; trackIndex <= finalTrackIndex; ++trackIndex) {
|
| const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
|
| if (!(trackSize.*filterFunction)())
|
| continue;
|
|
|
| - GridTrack& track = (direction == ForColumns) ? columnTracks[trackIndex] : rowTracks[trackIndex];
|
| - tracks.append(&track);
|
| + GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
|
| + sizingData.filteredTracks.append(&track);
|
| }
|
|
|
| - if (tracks.isEmpty())
|
| + if (sizingData.filteredTracks.isEmpty())
|
| return;
|
|
|
| - LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direction, columnTracks);
|
| + LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direction, sizingData.columnTracks);
|
| for (size_t trackIndexForSpace = initialTrackIndex; trackIndexForSpace <= finalTrackIndex; ++trackIndexForSpace) {
|
| - GridTrack& track = (direction == ForColumns) ? columnTracks[trackIndexForSpace] : rowTracks[trackIndexForSpace];
|
| + GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndexForSpace] : sizingData.rowTracks[trackIndexForSpace];
|
| additionalBreadthSpace -= (track.*trackGetter)();
|
| }
|
|
|
| // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadth|.
|
| - distributeSpaceToTracks(tracks, &tracks, trackGetter, trackGrowthFunction, additionalBreadthSpace);
|
| + distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.filteredTracks, trackGetter, trackGrowthFunction, sizingData, additionalBreadthSpace);
|
| }
|
|
|
| static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTrack* track2)
|
| @@ -618,12 +636,12 @@ static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr
|
| return (track1->m_maxBreadth - track1->m_usedBreadth) < (track2->m_maxBreadth - track2->m_usedBreadth);
|
| }
|
|
|
| -void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, LayoutUnit& availableLogicalSpace)
|
| +void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
|
| {
|
| std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
|
|
|
| size_t tracksSize = tracks.size();
|
| - Vector<LayoutUnit> updatedTrackBreadths(tracksSize);
|
| + sizingData.distributeTrackVector.resize(tracksSize);
|
|
|
| for (size_t i = 0; i < tracksSize; ++i) {
|
| GridTrack& track = *tracks[i];
|
| @@ -631,7 +649,7 @@ void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<Grid
|
| LayoutUnit trackBreadth = (tracks[i]->*trackGetter)();
|
| LayoutUnit growthShare = std::max(LayoutUnit(), std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBreadth));
|
| // We should never shrink any grid track or else we can't guarantee we abide by our min-sizing function.
|
| - updatedTrackBreadths[i] = trackBreadth + growthShare;
|
| + sizingData.distributeTrackVector[i] = trackBreadth + growthShare;
|
| availableLogicalSpace -= growthShare;
|
| }
|
|
|
| @@ -639,13 +657,13 @@ void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<Grid
|
| tracksSize = tracksForGrowthAboveMaxBreadth->size();
|
| for (size_t i = 0; i < tracksSize; ++i) {
|
| LayoutUnit growthShare = availableLogicalSpace / (tracksSize - i);
|
| - updatedTrackBreadths[i] += growthShare;
|
| + sizingData.distributeTrackVector[i] += growthShare;
|
| availableLogicalSpace -= growthShare;
|
| }
|
| }
|
|
|
| for (size_t i = 0; i < tracksSize; ++i) {
|
| - LayoutUnit growth = updatedTrackBreadths[i] - (tracks[i]->*trackGetter)();
|
| + LayoutUnit growth = sizingData.distributeTrackVector[i] - (tracks[i]->*trackGetter)();
|
| if (growth >= 0)
|
| (tracks[i]->*trackGrowthFunction)(growth);
|
| }
|
| @@ -847,14 +865,13 @@ void RenderGrid::layoutGridItems()
|
| {
|
| placeItemsOnGrid();
|
|
|
| - Vector<GridTrack> columnTracks(gridColumnCount());
|
| - Vector<GridTrack> rowTracks(gridRowCount());
|
| - computedUsedBreadthOfGridTracks(ForColumns, columnTracks, rowTracks);
|
| - ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, columnTracks));
|
| - computedUsedBreadthOfGridTracks(ForRows, columnTracks, rowTracks);
|
| - ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, rowTracks));
|
| + GridSizingData sizingData(gridColumnCount(), gridRowCount());
|
| + computedUsedBreadthOfGridTracks(ForColumns, sizingData);
|
| + ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
|
| + computedUsedBreadthOfGridTracks(ForRows, sizingData);
|
| + ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
|
|
|
| - populateGridPositions(columnTracks, rowTracks);
|
| + populateGridPositions(sizingData);
|
|
|
| for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
|
| // Because the grid area cannot be styled, we don't need to adjust
|
| @@ -862,8 +879,8 @@ void RenderGrid::layoutGridItems()
|
| LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWidth() : LayoutUnit();
|
| LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOverrideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogicalHeight() : LayoutUnit();
|
|
|
| - LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, columnTracks);
|
| - LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadthForChild(child, ForRows, rowTracks);
|
| + LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, sizingData.columnTracks);
|
| + LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadthForChild(child, ForRows, sizingData.rowTracks);
|
|
|
| SubtreeLayoutScope layoutScope(child);
|
| if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth || (child->hasRelativeLogicalHeight() && oldOverrideContainingBlockContentLogicalHeight != overrideContainingBlockContentLogicalHeight))
|
| @@ -879,7 +896,7 @@ void RenderGrid::layoutGridItems()
|
| // now, just size as if we were a regular child.
|
| child->layoutIfNeeded();
|
|
|
| - child->setLogicalLocation(findChildLogicalPosition(child, columnTracks, rowTracks));
|
| + child->setLogicalLocation(findChildLogicalPosition(child, sizingData));
|
|
|
| // If the child moved, we have to repaint it as well as any floating/positioned
|
| // descendants. An exception is if we need a layout. In this case, we know we're going to
|
| @@ -888,8 +905,8 @@ void RenderGrid::layoutGridItems()
|
| child->repaintDuringLayoutIfMoved(oldChildRect);
|
| }
|
|
|
| - for (size_t i = 0; i < rowTracks.size(); ++i)
|
| - setLogicalHeight(logicalHeight() + rowTracks[i].m_usedBreadth);
|
| + for (size_t i = 0; i < sizingData.rowTracks.size(); ++i)
|
| + setLogicalHeight(logicalHeight() + sizingData.rowTracks[i].m_usedBreadth);
|
|
|
| // FIXME: We should handle min / max logical height.
|
|
|
| @@ -1118,24 +1135,24 @@ LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, TrackSizi
|
| return gridAreaBreadth;
|
| }
|
|
|
| -void RenderGrid::populateGridPositions(const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks)
|
| +void RenderGrid::populateGridPositions(const GridSizingData& sizingData)
|
| {
|
| - m_columnPositions.resize(columnTracks.size() + 1);
|
| + m_columnPositions.resize(sizingData.columnTracks.size() + 1);
|
| m_columnPositions[0] = borderAndPaddingStart();
|
| for (size_t i = 0; i < m_columnPositions.size() - 1; ++i)
|
| - m_columnPositions[i + 1] = m_columnPositions[i] + columnTracks[i].m_usedBreadth;
|
| + m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnTracks[i].m_usedBreadth;
|
|
|
| - m_rowPositions.resize(rowTracks.size() + 1);
|
| + m_rowPositions.resize(sizingData.rowTracks.size() + 1);
|
| m_rowPositions[0] = borderAndPaddingBefore();
|
| for (size_t i = 0; i < m_rowPositions.size() - 1; ++i)
|
| - m_rowPositions[i + 1] = m_rowPositions[i] + rowTracks[i].m_usedBreadth;
|
| + m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].m_usedBreadth;
|
| }
|
|
|
| -LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks)
|
| +LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const GridSizingData& sizingData)
|
| {
|
| const GridCoordinate& coordinate = cachedGridCoordinate(child);
|
| - ASSERT(coordinate.columns.initialPositionIndex < columnTracks.size());
|
| - ASSERT(coordinate.rows.initialPositionIndex < rowTracks.size());
|
| + ASSERT(coordinate.columns.initialPositionIndex < sizingData.columnTracks.size());
|
| + ASSERT(coordinate.rows.initialPositionIndex < sizingData.rowTracks.size());
|
|
|
| // The grid items should be inside the grid container's border box, that's why they need to be shifted.
|
| return LayoutPoint(m_columnPositions[coordinate.columns.initialPositionIndex] + marginStartForChild(child), m_rowPositions[coordinate.rows.initialPositionIndex] + marginBeforeForChild(child));
|
|
|