Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1676)

Unified Diff: Source/core/rendering/RenderGrid.cpp

Issue 24331003: Cache several vectors to avoid malloc/free churn (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/RenderGrid.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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));
« no previous file with comments | « Source/core/rendering/RenderGrid.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698