size_t m_childIndex;
};
+class 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, PassRef<RenderStyle> style)
: RenderBlock(element, std::move(style), 0)
, m_orderIterator(*this)
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);
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);
+ if (!sizingData.contentSizedTracksIndex.isEmpty())
+ resolveContentBasedTrackSizingFunctions(direction, sizingData);
for (size_t i = 0; i < tracks.size(); ++i) {
ASSERT(tracks[i].m_maxBreadth != infinity);
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.
return logicalContentHeightForChild(child, columnTracks);
}
-void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, Vector<size_t>& contentSizedTracks)
+void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, GridSizingData& sizingData)
{
// FIXME: Split the grid tracks into groups that doesn't overlap a <flex> grid track.
- 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)
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];
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;
}
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);
}
{
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));
for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
- LayoutPoint childPosition = findChildLogicalPosition(child, columnTracks, rowTracks);
+ LayoutPoint childPosition = findChildLogicalPosition(child, sizingData);
// Because the grid area cannot be styled, we don't need to adjust
// the grid breadth to account for 'box-sizing'.
// FIXME: For children in a content sized track, we clear the overrideContainingBlockContentLogicalHeight
// in minContentForChild / maxContentForChild which means that we will always relayout the child.
- 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);
if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != overrideContainingBlockContentLogicalHeight && (child->hasRelativeLogicalHeight() || child->hasViewportPercentageLogicalHeight())))
child->setNeedsLayout(MarkOnlyThis);
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.
return gridAreaBreadth;
}
-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);
// The grid items should be inside the grid container's border box, that's why they need to be shifted.
LayoutPoint offset(borderAndPaddingStart(), borderAndPaddingBefore());
// FIXME: |columnTrack| and |rowTrack| should be smaller than our column / row count.
- for (size_t i = 0; i < coordinate.columns.initialPositionIndex && i < columnTracks.size(); ++i)
- offset.setX(offset.x() + columnTracks[i].m_usedBreadth);
- for (size_t i = 0; i < coordinate.rows.initialPositionIndex && i < rowTracks.size(); ++i)
- offset.setY(offset.y() + rowTracks[i].m_usedBreadth);
+ for (size_t i = 0; i < coordinate.columns.initialPositionIndex && i < sizingData.columnTracks.size(); ++i)
+ offset.setX(offset.x() + sizingData.columnTracks[i].m_usedBreadth);
+ for (size_t i = 0; i < coordinate.rows.initialPositionIndex && i < sizingData.rowTracks.size(); ++i)
+ offset.setY(offset.y() + sizingData.rowTracks[i].m_usedBreadth);
// FIXME: Handle margins on the grid item.
return offset;
LayoutUnit computePreferredTrackWidth(const GridLength&, size_t) const;
class GridIterator;
+ class GridSizingData;
enum TrackSizingDirection { ForColumns, ForRows };
- void computedUsedBreadthOfGridTracks(TrackSizingDirection, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks);
+ void computedUsedBreadthOfGridTracks(TrackSizingDirection, GridSizingData&);
LayoutUnit computeUsedBreadthOfMinLength(TrackSizingDirection, const GridLength&) const;
LayoutUnit computeUsedBreadthOfMaxLength(TrackSizingDirection, const GridLength&, LayoutUnit usedBreadth) const;
LayoutUnit computeUsedBreadthOfSpecifiedLength(TrackSizingDirection, const Length&) const;
- void resolveContentBasedTrackSizingFunctions(TrackSizingDirection, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, Vector<size_t>& contentSizedTracks);
+ void resolveContentBasedTrackSizingFunctions(TrackSizingDirection, GridSizingData&);
void growGrid(TrackSizingDirection);
void insertItemIntoGrid(RenderBox*, size_t rowTrack, size_t columnTrack);
typedef LayoutUnit (GridTrack::* AccumulatorGetter)() const;
typedef void (GridTrack::* AccumulatorGrowFunction)(LayoutUnit);
typedef bool (GridTrackSize::* FilterFunction)() const;
- void resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, RenderBox*, FilterFunction, SizingFunction, AccumulatorGetter, AccumulatorGrowFunction);
- void distributeSpaceToTracks(Vector<GridTrack*>&, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter, AccumulatorGrowFunction, LayoutUnit& availableLogicalSpace);
+ void resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection, GridSizingData&, RenderBox*, FilterFunction, SizingFunction, AccumulatorGetter, AccumulatorGrowFunction);
+ void distributeSpaceToTracks(Vector<GridTrack*>&, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter, AccumulatorGrowFunction, GridSizingData&, LayoutUnit& availableLogicalSpace);
double computeNormalizedFractionBreadth(Vector<GridTrack>&, TrackSizingDirection, LayoutUnit availableLogicalSpace) const;
LayoutUnit logicalContentHeightForChild(RenderBox*, Vector<GridTrack>&);
LayoutUnit minContentForChild(RenderBox*, TrackSizingDirection, Vector<GridTrack>& columnTracks);
LayoutUnit maxContentForChild(RenderBox*, TrackSizingDirection, Vector<GridTrack>& columnTracks);
- LayoutPoint findChildLogicalPosition(RenderBox*, const Vector<GridTrack>& columnTracks, const Vector<GridTrack>& rowTracks);
+ LayoutPoint findChildLogicalPosition(RenderBox*, const GridSizingData&);
GridCoordinate cachedGridCoordinate(const RenderBox*) const;
GridSpan resolveGridPositionsFromAutoPlacementPosition(const RenderBox*, TrackSizingDirection, size_t) const;