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)); |