Commit 67e44b22 authored by Oriol Brufau's avatar Oriol Brufau Committed by Commit Bot

[css-grid] Cache the track sizing functions

Calculating the used sizing function for a track is not a very expensive
operation, but it's not trivial either, and the track sizing algorithm
needs to access sizing functions all over the place. This ends up having
a performance cost, especially for spanning items.

Intrinsic contributions from items that span a single track are handled
in a simpler way than when the span is greater than 1. In the former
case, SizeTrackToFitNonSpanningItem only calculates the track sizing
function of each track once per each item in that track. But in the
latter case we not only calculate the track sizing function of multiple
tracks per item, we also repeat this 5 times in order to handle the
various TrackSizeComputationPhase.

Therefore, to increase performance, this patch caches the used track
sizing functions in the tracks themselves.

This improves the auto-grid-lots-of-spanning-data perf test by 40-50%,
nested-grid by 10-15%, and auto-grid-lots-of-data by 5-10%.

Bug: 1021929
Change-Id: I4309629bfed28a78421889d157251643efc06b26
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1901292
Commit-Queue: Oriol Brufau <obrufau@igalia.com>
Reviewed-by: default avatarSergio Villar <svillar@igalia.com>
Cr-Commit-Position: refs/heads/master@{#714511}
parent 2b78d8db
...@@ -69,6 +69,10 @@ void GridTrack::SetGrowthLimitCap(base::Optional<LayoutUnit> growth_limit_cap) { ...@@ -69,6 +69,10 @@ void GridTrack::SetGrowthLimitCap(base::Optional<LayoutUnit> growth_limit_cap) {
growth_limit_cap_ = growth_limit_cap; growth_limit_cap_ = growth_limit_cap;
} }
void GridTrack::SetCachedTrackSize(const GridTrackSize& cached_track_size) {
cached_track_size_ = cached_track_size;
}
bool GridTrack::IsGrowthLimitBiggerThanBaseSize() const { bool GridTrack::IsGrowthLimitBiggerThanBaseSize() const {
return GrowthLimitIsInfinite() || growth_limit_ >= base_size_; return GrowthLimitIsInfinite() || growth_limit_ >= base_size_;
} }
...@@ -195,8 +199,12 @@ LayoutUnit GridTrackSizingAlgorithm::EstimatedGridAreaBreadthForChild( ...@@ -195,8 +199,12 @@ LayoutUnit GridTrackSizingAlgorithm::EstimatedGridAreaBreadthForChild(
// We may need to estimate the grid area size before running the track // We may need to estimate the grid area size before running the track
// sizing algorithm in order to perform the pre-layout of orthogonal // sizing algorithm in order to perform the pre-layout of orthogonal
// items. // items.
GridTrackSize track_size = // We cannot use Tracks(direction)[track_position].CachedTrackSize()
WasSetup() ? GetGridTrackSize(direction, track_position) // because Tracks(direction) is empty, since we are either performing
// pre-layout or are running the track sizing algorithm in the opposite
// direction and haven't run it in the desired direction yet.
const GridTrackSize& track_size =
WasSetup() ? CalculateGridTrackSize(direction, track_position)
: RawGridTrackSize(direction, track_position); : RawGridTrackSize(direction, track_position);
GridLength max_track_size = track_size.MaxTrackBreadth(); GridLength max_track_size = track_size.MaxTrackBreadth();
if (max_track_size.IsContentSized() || max_track_size.IsFlex() || if (max_track_size.IsContentSized() || max_track_size.IsFlex() ||
...@@ -394,7 +402,8 @@ LayoutUnit GridTrackSizingAlgorithmStrategy::MinSizeForChild( ...@@ -394,7 +402,8 @@ LayoutUnit GridTrackSizingAlgorithmStrategy::MinSizeForChild(
algorithm_.GetGrid().GridItemSpan(child, Direction()); algorithm_.GetGrid().GridItemSpan(child, Direction());
LayoutUnit max_breadth; LayoutUnit max_breadth;
for (const auto& track_position : span) { for (const auto& track_position : span) {
GridTrackSize track_size = GetGridTrackSize(Direction(), track_position); const GridTrackSize& track_size =
GetCachedGridTrackSize(Direction(), track_position);
if (!track_size.HasFixedMaxTrackBreadth()) if (!track_size.HasFixedMaxTrackBreadth())
return min_size; return min_size;
max_breadth += ValueForLength(track_size.MaxTrackBreadth().length(), max_breadth += ValueForLength(track_size.MaxTrackBreadth().length(),
...@@ -658,9 +667,10 @@ double IndefiniteSizeStrategy::FindUsedFlexFraction( ...@@ -658,9 +667,10 @@ double IndefiniteSizeStrategy::FindUsedFlexFraction(
// not to have to do that. // not to have to do that.
flex_fraction = std::max( flex_fraction = std::max(
flex_fraction, flex_fraction,
NormalizedFlexFraction( NormalizedFlexFraction(all_tracks[track_index],
all_tracks[track_index], GetCachedGridTrackSize(direction, track_index)
GetGridTrackSize(direction, track_index).MaxTrackBreadth().Flex())); .MaxTrackBreadth()
.Flex()));
} }
const Grid& grid = algorithm_.GetGrid(); const Grid& grid = algorithm_.GetGrid();
...@@ -894,7 +904,7 @@ bool GridTrackSizingAlgorithm::IsRelativeSizedTrackAsAuto( ...@@ -894,7 +904,7 @@ bool GridTrackSizingAlgorithm::IsRelativeSizedTrackAsAuto(
return false; return false;
} }
GridTrackSize GridTrackSizingAlgorithm::GetGridTrackSize( GridTrackSize GridTrackSizingAlgorithm::CalculateGridTrackSize(
GridTrackSizingDirection direction, GridTrackSizingDirection direction,
size_t translated_index) const { size_t translated_index) const {
DCHECK(WasSetup()); DCHECK(WasSetup());
...@@ -986,8 +996,9 @@ void GridTrackSizingAlgorithm::InitializeTrackSizes() { ...@@ -986,8 +996,9 @@ void GridTrackSizingAlgorithm::InitializeTrackSizes() {
direction_ == kForRows && !layout_grid_->CachedHasDefiniteLogicalHeight(); direction_ == kForRows && !layout_grid_->CachedHasDefiniteLogicalHeight();
size_t num_tracks = track_list.size(); size_t num_tracks = track_list.size();
for (size_t i = 0; i < num_tracks; ++i) { for (size_t i = 0; i < num_tracks; ++i) {
GridTrackSize track_size = GetGridTrackSize(direction_, i); const GridTrackSize& track_size = CalculateGridTrackSize(direction_, i);
GridTrack& track = track_list[i]; GridTrack& track = track_list[i];
track.SetCachedTrackSize(track_size);
track.SetBaseSize(InitialBaseSize(track_size)); track.SetBaseSize(InitialBaseSize(track_size));
track.SetGrowthLimit(InitialGrowthLimit(track_size, track.BaseSize())); track.SetGrowthLimit(InitialGrowthLimit(track_size, track.BaseSize()));
track.SetInfinitelyGrowable(false); track.SetInfinitelyGrowable(false);
...@@ -1019,7 +1030,8 @@ void GridTrackSizingAlgorithm::SizeTrackToFitNonSpanningItem( ...@@ -1019,7 +1030,8 @@ void GridTrackSizingAlgorithm::SizeTrackToFitNonSpanningItem(
LayoutBox& grid_item, LayoutBox& grid_item,
GridTrack& track) { GridTrack& track) {
const size_t track_position = span.StartLine(); const size_t track_position = span.StartLine();
GridTrackSize track_size = GetGridTrackSize(direction_, track_position); const GridTrackSize& track_size =
Tracks(direction_)[track_position].CachedTrackSize();
if (track_size.HasMinContentMinTrackBreadth()) { if (track_size.HasMinContentMinTrackBreadth()) {
track.SetBaseSize( track.SetBaseSize(
...@@ -1049,9 +1061,10 @@ void GridTrackSizingAlgorithm::SizeTrackToFitNonSpanningItem( ...@@ -1049,9 +1061,10 @@ void GridTrackSizingAlgorithm::SizeTrackToFitNonSpanningItem(
bool GridTrackSizingAlgorithm::SpanningItemCrossesFlexibleSizedTracks( bool GridTrackSizingAlgorithm::SpanningItemCrossesFlexibleSizedTracks(
const GridSpan& span) const { const GridSpan& span) const {
const Vector<GridTrack>& track_list = Tracks(direction_);
for (const auto& track_position : span) { for (const auto& track_position : span) {
const GridTrackSize& track_size = const GridTrackSize& track_size =
GetGridTrackSize(direction_, track_position); track_list[track_position].CachedTrackSize();
if (track_size.MinTrackBreadth().IsFlex() || if (track_size.MinTrackBreadth().IsFlex() ||
track_size.MaxTrackBreadth().IsFlex()) track_size.MaxTrackBreadth().IsFlex())
return true; return true;
...@@ -1358,8 +1371,8 @@ void GridTrackSizingAlgorithm::IncreaseSizesToAccommodateSpanningItems( ...@@ -1358,8 +1371,8 @@ void GridTrackSizingAlgorithm::IncreaseSizesToAccommodateSpanningItems(
filtered_tracks.Shrink(0); filtered_tracks.Shrink(0);
LayoutUnit spanning_tracks_size; LayoutUnit spanning_tracks_size;
for (const auto& track_position : item_span) { for (const auto& track_position : item_span) {
GridTrackSize track_size = GetGridTrackSize(direction_, track_position); GridTrack& track = all_tracks[track_position];
GridTrack& track = Tracks(direction_)[track_position]; const GridTrackSize& track_size = track.CachedTrackSize();
spanning_tracks_size += spanning_tracks_size +=
TrackSizeForTrackSizeComputationPhase(phase, track, kForbidInfinity); TrackSizeForTrackSizeComputationPhase(phase, track, kForbidInfinity);
if (!ShouldProcessTrackForTrackSizeComputationPhase(phase, track_size)) if (!ShouldProcessTrackForTrackSizeComputationPhase(phase, track_size))
...@@ -1399,12 +1412,13 @@ void GridTrackSizingAlgorithm::IncreaseSizesToAccommodateSpanningItems( ...@@ -1399,12 +1412,13 @@ void GridTrackSizingAlgorithm::IncreaseSizesToAccommodateSpanningItems(
} }
void GridTrackSizingAlgorithm::ResolveIntrinsicTrackSizes() { void GridTrackSizingAlgorithm::ResolveIntrinsicTrackSizes() {
Vector<GridTrack>& all_tracks = Tracks(direction_);
Vector<GridItemWithSpan> items_sorted_by_increasing_span; Vector<GridItemWithSpan> items_sorted_by_increasing_span;
if (grid_.HasGridItems()) { if (grid_.HasGridItems()) {
HashSet<LayoutBox*> items_set; HashSet<LayoutBox*> items_set;
for (const auto& track_index : content_sized_tracks_index_) { for (const auto& track_index : content_sized_tracks_index_) {
auto iterator = grid_.CreateIterator(direction_, track_index); auto iterator = grid_.CreateIterator(direction_, track_index);
GridTrack& track = Tracks(direction_)[track_index]; GridTrack& track = all_tracks[track_index];
while (auto* grid_item = iterator->NextGridItem()) { while (auto* grid_item = iterator->NextGridItem()) {
if (items_set.insert(grid_item).is_new_entry) { if (items_set.insert(grid_item).is_new_entry) {
const GridSpan& span = grid_.GridItemSpan(*grid_item, direction_); const GridSpan& span = grid_.GridItemSpan(*grid_item, direction_);
...@@ -1440,7 +1454,7 @@ void GridTrackSizingAlgorithm::ResolveIntrinsicTrackSizes() { ...@@ -1440,7 +1454,7 @@ void GridTrackSizingAlgorithm::ResolveIntrinsicTrackSizes() {
} }
for (const auto& track_index : content_sized_tracks_index_) { for (const auto& track_index : content_sized_tracks_index_) {
GridTrack& track = Tracks(direction_)[track_index]; GridTrack& track = all_tracks[track_index];
if (track.GrowthLimit() == kInfinity) if (track.GrowthLimit() == kInfinity)
track.SetGrowthLimit(track.BaseSize()); track.SetGrowthLimit(track.BaseSize());
} }
...@@ -1487,7 +1501,7 @@ double GridTrackSizingAlgorithm::FindFrUnitSize( ...@@ -1487,7 +1501,7 @@ double GridTrackSizingAlgorithm::FindFrUnitSize(
double flex_factor_sum = 0; double flex_factor_sum = 0;
Vector<size_t, 8> flexible_tracks_indexes; Vector<size_t, 8> flexible_tracks_indexes;
for (const auto& track_index : tracks_span) { for (const auto& track_index : tracks_span) {
GridTrackSize track_size = GetGridTrackSize(direction_, track_index); const GridTrackSize& track_size = all_tracks[track_index].CachedTrackSize();
if (!track_size.MaxTrackBreadth().IsFlex()) { if (!track_size.MaxTrackBreadth().IsFlex()) {
left_over_space -= all_tracks[track_index].BaseSize(); left_over_space -= all_tracks[track_index].BaseSize();
} else { } else {
...@@ -1527,7 +1541,7 @@ double GridTrackSizingAlgorithm::ComputeFlexFactorUnitSize( ...@@ -1527,7 +1541,7 @@ double GridTrackSizingAlgorithm::ComputeFlexFactorUnitSize(
continue; continue;
LayoutUnit base_size = tracks[index].BaseSize(); LayoutUnit base_size = tracks[index].BaseSize();
double flex_factor = double flex_factor =
GetGridTrackSize(direction_, index).MaxTrackBreadth().Flex(); tracks[index].CachedTrackSize().MaxTrackBreadth().Flex();
// treating all such tracks as inflexible. // treating all such tracks as inflexible.
if (base_size > hypothetical_factor_unit_size * flex_factor) { if (base_size > hypothetical_factor_unit_size * flex_factor) {
left_over_space -= base_size; left_over_space -= base_size;
...@@ -1557,7 +1571,7 @@ void GridTrackSizingAlgorithm::ComputeFlexSizedTracksGrowth( ...@@ -1557,7 +1571,7 @@ void GridTrackSizingAlgorithm::ComputeFlexSizedTracksGrowth(
const Vector<GridTrack>& all_tracks = Tracks(direction_); const Vector<GridTrack>& all_tracks = Tracks(direction_);
for (size_t i = 0; i < num_flex_tracks; ++i) { for (size_t i = 0; i < num_flex_tracks; ++i) {
size_t track_index = flexible_sized_tracks_index_[i]; size_t track_index = flexible_sized_tracks_index_[i];
auto track_size = GetGridTrackSize(direction_, track_index); const GridTrackSize& track_size = all_tracks[track_index].CachedTrackSize();
DCHECK(track_size.MaxTrackBreadth().IsFlex()); DCHECK(track_size.MaxTrackBreadth().IsFlex());
LayoutUnit old_base_size = all_tracks[track_index].BaseSize(); LayoutUnit old_base_size = all_tracks[track_index].BaseSize();
LayoutUnit new_base_size = std::max( LayoutUnit new_base_size = std::max(
...@@ -1768,7 +1782,7 @@ void GridTrackSizingAlgorithm::Reset() { ...@@ -1768,7 +1782,7 @@ void GridTrackSizingAlgorithm::Reset() {
bool GridTrackSizingAlgorithm::TracksAreWiderThanMinTrackBreadth() const { bool GridTrackSizingAlgorithm::TracksAreWiderThanMinTrackBreadth() const {
const Vector<GridTrack>& all_tracks = Tracks(direction_); const Vector<GridTrack>& all_tracks = Tracks(direction_);
for (size_t i = 0; i < all_tracks.size(); ++i) { for (size_t i = 0; i < all_tracks.size(); ++i) {
GridTrackSize track_size = GetGridTrackSize(direction_, i); const GridTrackSize& track_size = all_tracks[i].CachedTrackSize();
if (InitialBaseSize(track_size) > all_tracks[i].BaseSize()) if (InitialBaseSize(track_size) > all_tracks[i].BaseSize())
return false; return false;
} }
......
...@@ -66,6 +66,12 @@ class GridTrack { ...@@ -66,6 +66,12 @@ class GridTrack {
} }
void SetGrowthLimitCap(base::Optional<LayoutUnit>); void SetGrowthLimitCap(base::Optional<LayoutUnit>);
const GridTrackSize CachedTrackSize() const {
DCHECK(cached_track_size_.has_value());
return cached_track_size_.value();
}
void SetCachedTrackSize(const GridTrackSize&);
private: private:
bool IsGrowthLimitBiggerThanBaseSize() const; bool IsGrowthLimitBiggerThanBaseSize() const;
void EnsureGrowthLimitIsBiggerThanBaseSize(); void EnsureGrowthLimitIsBiggerThanBaseSize();
...@@ -76,6 +82,7 @@ class GridTrack { ...@@ -76,6 +82,7 @@ class GridTrack {
LayoutUnit size_during_distribution_; LayoutUnit size_during_distribution_;
base::Optional<LayoutUnit> growth_limit_cap_; base::Optional<LayoutUnit> growth_limit_cap_;
bool infinitely_growable_; bool infinitely_growable_;
base::Optional<GridTrackSize> cached_track_size_;
}; };
class GridTrackSizingAlgorithm final { class GridTrackSizingAlgorithm final {
...@@ -136,8 +143,8 @@ class GridTrackSizingAlgorithm final { ...@@ -136,8 +143,8 @@ class GridTrackSizingAlgorithm final {
GridTrackSizingDirection) const; GridTrackSizingDirection) const;
bool IsRelativeSizedTrackAsAuto(const GridTrackSize&, bool IsRelativeSizedTrackAsAuto(const GridTrackSize&,
GridTrackSizingDirection) const; GridTrackSizingDirection) const;
GridTrackSize GetGridTrackSize(GridTrackSizingDirection, GridTrackSize CalculateGridTrackSize(GridTrackSizingDirection,
size_t translated_index) const; size_t translated_index) const;
GridTrackSize RawGridTrackSize(GridTrackSizingDirection, GridTrackSize RawGridTrackSize(GridTrackSizingDirection,
size_t translated_index) const; size_t translated_index) const;
...@@ -318,9 +325,9 @@ class GridTrackSizingAlgorithmStrategy { ...@@ -318,9 +325,9 @@ class GridTrackSizingAlgorithmStrategy {
return algorithm_.AvailableSpace(); return algorithm_.AvailableSpace();
} }
GridTrackSize GetGridTrackSize(GridTrackSizingDirection direction, GridTrackSize GetCachedGridTrackSize(GridTrackSizingDirection direction,
size_t translated_index) const { size_t translated_index) const {
return algorithm_.GetGridTrackSize(direction, translated_index); return algorithm_.Tracks(direction)[translated_index].CachedTrackSize();
} }
// Helper functions // Helper functions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment