Commit 7dcf0e7c authored by Jacques Newman's avatar Jacques Newman Committed by Chromium LUCI CQ

[GridNG] Refactor NGGridLayoutAlgorithm

Refactors NGGridLayoutAlgorithm to reduce member variable usage.
This change should not have any functional changes.
The helpers used in NGGridLayoutAlgorithm::Layout need to be used
to help compute the min/max sizes, to do this they must be static
or const. This refactor has an emphasis on moving data from the
class to the stack whenever possible.
This change also removes the state machine, as the added complexity
was determined to not be needed.

Bug: 1045599
Change-Id: I6af79bc2e3093ccfd33d8c6cb5cc6d46c2ed3698
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2542766
Commit-Queue: Jacques Newman <janewman@microsoft.com>
Reviewed-by: default avatarKurt Catti-Schmidt <kschmi@microsoft.com>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#832589}
parent 679c0abd
......@@ -76,9 +76,6 @@ class CORE_EXPORT NGGridLayoutAlgorithm
MinMaxSizesResult ComputeMinMaxSizes(const MinMaxSizesInput&) const override;
const NGGridLayoutAlgorithmTrackCollection& ColumnTrackCollection() const;
const NGGridLayoutAlgorithmTrackCollection& RowTrackCollection() const;
private:
using NGGridSetVector = Vector<NGGridSet*, 16>;
......@@ -120,15 +117,13 @@ class CORE_EXPORT NGGridLayoutAlgorithm
Vector<GridItemData>& grid_items_;
};
ReorderedGridItems GetReorderedGridItems();
NGGridLayoutAlgorithmTrackCollection& TrackCollection(
GridTrackSizingDirection track_direction);
// Returns an iterator for every |NGGridSet| contained within an item's span
// in the relevant track collection.
NGGridLayoutAlgorithmTrackCollection::SetIterator GetSetIteratorForItem(
const GridItemData& item,
GridTrackSizingDirection track_direction);
static NGGridLayoutAlgorithmTrackCollection::SetIterator
GetSetIteratorForItem(const GridItemData& item,
GridTrackSizingDirection track_direction,
NGGridLayoutAlgorithmTrackCollection& track_collection);
// Returns the size that a grid item will distribute across the tracks with an
// intrinsic sizing function it spans in the relevant track direction.
......@@ -137,48 +132,82 @@ class CORE_EXPORT NGGridLayoutAlgorithm
GridTrackSizingDirection track_direction,
GridItemContributionType contribution_type) const;
void ConstructAndAppendGridItems();
GridItemData MeasureGridItem(const NGBlockNode node);
void ConstructAndAppendGridItems(
Vector<GridItemData>* grid_items,
Vector<GridItemData>* out_of_flow_items) const;
GridItemData MeasureGridItem(const NGBlockNode node) const;
NGConstraintSpace BuildSpaceForGridItem(const NGBlockNode node) const;
// Sets the specified tracks for row and column track lists.
void SetSpecifiedTracks();
void BuildBlockTrackCollections(
Vector<GridItemData>* grid_items,
NGGridBlockTrackCollection* column_track_collection,
NGGridBlockTrackCollection* row_track_collection) const;
void BuildAlgorithmTrackCollections(
Vector<GridItemData>* grid_items,
NGGridLayoutAlgorithmTrackCollection* column_track_collection,
NGGridLayoutAlgorithmTrackCollection* row_track_collection) const;
// Sets specified track lists on |track_collection|.
void SetSpecifiedTracks(GridTrackSizingDirection track_direction,
wtf_size_t automatic_repetitions,
NGGridBlockTrackCollection* track_collection) const;
// Determines the explicit column and row track starts.
void DetermineExplicitTrackStarts();
void DetermineExplicitTrackStarts(wtf_size_t automatic_column_repetitions,
wtf_size_t automatic_row_repetitions,
wtf_size_t* explicit_column_start,
wtf_size_t* explicit_row_start,
wtf_size_t* column_count,
wtf_size_t* row_count) const;
// For every item and track direction, computes and stores the pair of indices
// "begin" and "end" such that the item spans every set from the respective
// collection's |sets_| with an index in the range [begin, end).
void CacheItemSetIndices();
void CacheItemSetIndices(
GridTrackSizingDirection track_direction,
const NGGridLayoutAlgorithmTrackCollection* track_collection,
Vector<GridItemData>* grid_items) const;
// For every grid item, determines if it spans a track with an intrinsic or
// flexible sizing function and caches the answer in its |GridItemData|.
void DetermineGridItemsSpanningIntrinsicOrFlexTracks(
GridTrackSizingDirection track_direction);
GridTrackSizingDirection track_direction,
Vector<GridItemData>* grid_items,
Vector<wtf_size_t>* reordered_item_indices,
NGGridLayoutAlgorithmTrackCollection* track_collection) const;
// Calculates from the min and max track sizing functions the used track size.
void ComputeUsedTrackSizes(GridTrackSizingDirection track_direction);
void ComputeUsedTrackSizes(
GridTrackSizingDirection track_direction,
Vector<GridItemData>* grid_items,
NGGridLayoutAlgorithmTrackCollection* track_collection) const;
// These methods implement the steps of the algorithm for intrinsic track size
// resolution defined in https://drafts.csswg.org/css-grid-1/#algo-content.
void ResolveIntrinsicTrackSizes(GridTrackSizingDirection track_direction);
void ResolveIntrinsicTrackSizes(
GridTrackSizingDirection track_direction,
Vector<GridItemData>* grid_items,
Vector<wtf_size_t>* reordered_item_indices,
NGGridLayoutAlgorithmTrackCollection* track_collection) const;
void IncreaseTrackSizesToAccommodateGridItems(
GridTrackSizingDirection track_direction,
ReorderedGridItems::Iterator group_begin,
ReorderedGridItems::Iterator group_end,
GridItemContributionType contribution_type);
void DistributeExtraSpaceToSets(LayoutUnit extra_space,
GridItemContributionType contribution_type,
NGGridLayoutAlgorithmTrackCollection* track_collection) const;
static void DistributeExtraSpaceToSets(
LayoutUnit extra_space,
GridItemContributionType contribution_type,
NGGridSetVector* sets_to_grow,
NGGridSetVector* sets_to_grow_beyond_limit);
// Allows a test to set the value for automatic track repetition.
void SetAutomaticTrackRepetitionsForTesting(wtf_size_t auto_column,
wtf_size_t auto_row);
wtf_size_t AutoRepeatCountForDirection(
GridTrackSizingDirection track_direction) const;
// Lays out and computes inline and block offsets for grid items.
void PlaceGridItems();
void PlaceGridItems(
const Vector<GridItemData>& grid_items,
const Vector<GridItemData>& out_of_flow_items,
NGGridLayoutAlgorithmTrackCollection& column_track_collection,
NGGridLayoutAlgorithmTrackCollection& row_track_collection,
LayoutUnit* intrinsic_block_size);
// Lays out |grid_item| based on the offsets and sizes provided.
void PlaceGridItem(const GridItemData& grid_item,
......@@ -187,42 +216,22 @@ class CORE_EXPORT NGGridLayoutAlgorithm
// Gets the row or column gap of the grid.
LayoutUnit GridGap(GridTrackSizingDirection track_direction,
LayoutUnit available_size = kIndefiniteSize);
LayoutUnit available_size = kIndefiniteSize) const;
// Calculates inline and block offsets for all tracks.
Vector<LayoutUnit> ComputeSetOffsets(GridTrackSizingDirection track_direction,
LayoutUnit grid_gap);
Vector<LayoutUnit> ComputeSetOffsets(
GridTrackSizingDirection track_direction,
LayoutUnit grid_gap,
NGGridLayoutAlgorithmTrackCollection& track_collection) const;
// Tests whether the row gap is unresolvable based on its type and the
// available size.
bool IsRowGridGapUnresolvable(LayoutUnit available_size);
bool IsRowGridGapUnresolvable(LayoutUnit available_size) const;
GridTrackSizingDirection AutoFlowDirection() const;
GridLayoutAlgorithmState state_;
LogicalSize border_box_size_;
LogicalSize child_percentage_size_;
LayoutUnit intrinsic_block_size_;
Vector<GridItemData> grid_items_;
Vector<GridItemData> out_of_flow_items_;
Vector<wtf_size_t> reordered_item_indices_;
NGGridBlockTrackCollection block_column_track_collection_;
NGGridBlockTrackCollection block_row_track_collection_;
NGGridLayoutAlgorithmTrackCollection algorithm_column_track_collection_;
NGGridLayoutAlgorithmTrackCollection algorithm_row_track_collection_;
wtf_size_t explicit_column_start_ = 0;
wtf_size_t explicit_row_start_ = 0;
wtf_size_t column_count_ = 0;
wtf_size_t row_count_ = 0;
wtf_size_t automatic_column_repetitions_ =
NGGridBlockTrackCollection::kInvalidRangeIndex;
wtf_size_t automatic_row_repetitions_ =
NGGridBlockTrackCollection::kInvalidRangeIndex;
};
} // namespace blink
......
......@@ -16,9 +16,9 @@ NGGridPlacement::NGGridPlacement(
const GridTrackSizingDirection major_direction,
const ComputedStyle& grid_style,
wtf_size_t minor_max_end_line,
NGGridBlockTrackCollection& row_collection,
NGGridBlockTrackCollection& column_collection,
Vector<NGGridLayoutAlgorithm::GridItemData>& items)
NGGridBlockTrackCollection* row_collection,
NGGridBlockTrackCollection* column_collection,
Vector<NGGridLayoutAlgorithm::GridItemData>* items)
: row_auto_repeat_(row_auto_repeat),
column_auto_repeat_(column_auto_repeat),
row_explicit_start_(row_explicit_start),
......@@ -30,9 +30,10 @@ NGGridPlacement::NGGridPlacement(
minor_max_end_line_(minor_max_end_line),
row_collection_(row_collection),
column_collection_(column_collection),
items_(items)
{
items_(items) {
DCHECK(row_collection_);
DCHECK(column_collection_);
DCHECK(items_);
placement_cursor_major = ExplicitStart(major_direction_);
placement_cursor_minor = ExplicitStart(minor_direction_);
}
......@@ -60,10 +61,10 @@ void NGGridPlacement::RunAutoPlacementAlgorithm() {
DCHECK(grid_item);
switch (grid_item->AutoPlacement(major_direction_)) {
case NGGridLayoutAlgorithm::AutoPlacementType::kBoth:
PlaceAutoBothAxisGridItem(*grid_item);
PlaceAutoBothAxisGridItem(grid_item);
break;
case NGGridLayoutAlgorithm::AutoPlacementType::kMajor:
PlaceAutoMajorAxisGridItem(*grid_item);
PlaceAutoMajorAxisGridItem(grid_item);
break;
case NGGridLayoutAlgorithm::AutoPlacementType::kMinor:
case NGGridLayoutAlgorithm::AutoPlacementType::kNotNeeded:
......@@ -73,11 +74,11 @@ void NGGridPlacement::RunAutoPlacementAlgorithm() {
}
bool NGGridPlacement::PlaceNonAutoGridItems() {
for (NGGridLayoutAlgorithm::GridItemData& grid_item : items_) {
for (NGGridLayoutAlgorithm::GridItemData& grid_item : *items_) {
bool has_definite_major_placement =
PlaceGridItem(major_direction_, grid_item);
PlaceGridItem(major_direction_, &grid_item);
bool has_definite_minor_placement =
PlaceGridItem(minor_direction_, grid_item);
PlaceGridItem(minor_direction_, &grid_item);
// If the item has definite positions on both axis then no auto placement is
// needed.
......@@ -131,20 +132,21 @@ void NGGridPlacement::PlaceGridItemsLockedToMajorAxis() {
// Update placement and ensure track coverage.
UpdatePlacementAndEnsureTrackCoverage(
GridSpan::TranslatedDefiniteGridSpan(minor_start, minor_end),
minor_direction_, *grid_item);
minor_direction_, grid_item);
}
}
void NGGridPlacement::PlaceAutoMajorAxisGridItem(
NGGridLayoutAlgorithm::GridItemData& grid_item) {
wtf_size_t major_span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem(
grid_item.node.Style(), major_direction_);
void NGGridPlacement::PlaceAutoMajorAxisGridItem(
NGGridLayoutAlgorithm::GridItemData* grid_item) {
wtf_size_t major_span_size =
GridPositionsResolver::SpanSizeForAutoPlacedItem(
grid_item->node.Style(), major_direction_);
switch (packing_behavior_) {
case PackingBehavior::kSparse:
// Set the minor position of the cursor to the grid item’s minor starting
// line. If this is less than the previous column position of the cursor,
// increment the major position by 1.
if (grid_item.StartLine(minor_direction_) < placement_cursor_minor) {
// Set the minor position of the cursor to the grid item’s minor
// starting line. If this is less than the previous column position of
// the cursor, increment the major position by 1.
if (grid_item->StartLine(minor_direction_) < placement_cursor_minor) {
placement_cursor_major++;
}
break;
......@@ -153,13 +155,13 @@ void NGGridPlacement::PlaceAutoMajorAxisGridItem(
break;
}
placement_cursor_minor = grid_item.StartLine(minor_direction_);
// Increment the cursor’s major position until a value is found where the grid
// item does not overlap any occupied grid cells
placement_cursor_minor = grid_item->StartLine(minor_direction_);
// Increment the cursor’s major position until a value is found where the
// grid item does not overlap any occupied grid cells
while (DoesItemOverlap(placement_cursor_major,
placement_cursor_major + major_span_size,
grid_item.StartLine(minor_direction_),
grid_item.EndLine(minor_direction_))) {
grid_item->StartLine(minor_direction_),
grid_item->EndLine(minor_direction_))) {
placement_cursor_major++;
}
......@@ -168,20 +170,22 @@ void NGGridPlacement::PlaceAutoMajorAxisGridItem(
GridSpan::TranslatedDefiniteGridSpan(
placement_cursor_major, placement_cursor_major + major_span_size),
major_direction_, grid_item);
}
}
void NGGridPlacement::PlaceAutoBothAxisGridItem(
NGGridLayoutAlgorithm::GridItemData& grid_item) {
void NGGridPlacement::PlaceAutoBothAxisGridItem(
NGGridLayoutAlgorithm::GridItemData* grid_item) {
if (packing_behavior_ == PackingBehavior::kDense) {
// Set the cursor’s major and minor positions to start-most row and column
// lines in the implicit grid.
placement_cursor_major = ExplicitStart(major_direction_);
placement_cursor_minor = ExplicitStart(minor_direction_);
}
wtf_size_t major_span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem(
grid_item.node.Style(), major_direction_);
wtf_size_t minor_span_size = GridPositionsResolver::SpanSizeForAutoPlacedItem(
grid_item.node.Style(), minor_direction_);
wtf_size_t major_span_size =
GridPositionsResolver::SpanSizeForAutoPlacedItem(
grid_item->node.Style(), major_direction_);
wtf_size_t minor_span_size =
GridPositionsResolver::SpanSizeForAutoPlacedItem(
grid_item->node.Style(), minor_direction_);
// Check to see if there would be overlap if this item was placed at the
// cursor. If overlap exists, increment minor position until no conflict
// exists or the item would overflow the minor axis.
......@@ -205,13 +209,13 @@ void NGGridPlacement::PlaceAutoBothAxisGridItem(
GridSpan::TranslatedDefiniteGridSpan(
placement_cursor_minor, placement_cursor_minor + minor_span_size),
minor_direction_, grid_item);
}
}
bool NGGridPlacement::PlaceGridItem(
bool NGGridPlacement::PlaceGridItem(
GridTrackSizingDirection direction,
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData& grid_item) {
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData* grid_item) {
GridSpan span = GridPositionsResolver::ResolveGridPositionsFromStyle(
grid_style_, grid_item.node.Style(), direction, AutoRepeat(direction));
grid_style_, grid_item->node.Style(), direction, AutoRepeat(direction));
// Indefinite positions are resolved with the auto placement algorithm.
if (span.IsIndefinite())
return false;
......@@ -219,16 +223,16 @@ bool NGGridPlacement::PlaceGridItem(
span.Translate(ExplicitStart(direction));
UpdatePlacementAndEnsureTrackCoverage(span, direction, grid_item);
return true;
}
}
void NGGridPlacement::UpdatePlacementAndEnsureTrackCoverage(
void NGGridPlacement::UpdatePlacementAndEnsureTrackCoverage(
GridSpan span,
GridTrackSizingDirection track_direction,
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData& grid_item) {
grid_item.SetSpan(span, track_direction);
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData* grid_item) {
grid_item->SetSpan(span, track_direction);
BlockCollection(track_direction)
.EnsureTrackCoverage(span.StartLine(), span.IntegerSpan());
}
}
bool NGGridPlacement::DoesItemOverlap(wtf_size_t major_start,
wtf_size_t major_end,
......@@ -238,7 +242,7 @@ bool NGGridPlacement::DoesItemOverlap(wtf_size_t major_start,
DCHECK_LE(minor_start, minor_end);
// TODO(janewman): Implement smarter collision detection, iterating over all
// items is not ideal and has large performance implications.
for (const NGGridLayoutAlgorithm::GridItemData& grid_item : items_) {
for (const NGGridLayoutAlgorithm::GridItemData& grid_item : *items_) {
if (grid_item.Span(major_direction_).IsIndefinite())
continue;
// Only test against definite positions.
......@@ -287,9 +291,9 @@ NGGridBlockTrackCollection& NGGridPlacement::BlockCollection(
GridTrackSizingDirection direction) {
switch (direction) {
case kForRows:
return row_collection_;
return *row_collection_;
case kForColumns:
return column_collection_;
return *column_collection_;
}
}
......
......@@ -27,9 +27,9 @@ class CORE_EXPORT NGGridPlacement {
const GridTrackSizingDirection major_direction,
const ComputedStyle& grid_style,
wtf_size_t minor_max_end_line,
NGGridBlockTrackCollection& row_collection,
NGGridBlockTrackCollection& column_collection,
Vector<NGGridLayoutAlgorithm::GridItemData>& items);
NGGridBlockTrackCollection* row_collection,
NGGridBlockTrackCollection* column_collection,
Vector<NGGridLayoutAlgorithm::GridItemData>* items);
void RunAutoPlacementAlgorithm();
private:
......@@ -42,21 +42,21 @@ class CORE_EXPORT NGGridPlacement {
// Place item that has a definite position on the minor axis but need auto
// placement on the major axis.
void PlaceAutoMajorAxisGridItem(
NGGridLayoutAlgorithm::GridItemData& item_data);
NGGridLayoutAlgorithm::GridItemData* item_data);
// Place items that need automatic placement on both the major and minor axis.
void PlaceAutoBothAxisGridItem(
NGGridLayoutAlgorithm::GridItemData& item_data);
NGGridLayoutAlgorithm::GridItemData* item_data);
// Places a grid item if it has a definite position in the given direction,
// returns true if item was able to be positioned, false if item needs auto
// positioning in the given direction.
bool PlaceGridItem(
GridTrackSizingDirection grid_direction,
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData& item_data);
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData* item_data);
void UpdatePlacementAndEnsureTrackCoverage(
GridSpan span,
GridTrackSizingDirection track_direction,
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData& item_data);
NGGridLayoutAlgorithm::NGGridLayoutAlgorithm::GridItemData* item_data);
// Returns true if the given placement would overlap with a placed item.
bool DoesItemOverlap(wtf_size_t major_start,
......@@ -83,9 +83,9 @@ class CORE_EXPORT NGGridPlacement {
// major line.
wtf_size_t minor_max_end_line_ = 0;
NGGridBlockTrackCollection& row_collection_;
NGGridBlockTrackCollection& column_collection_;
Vector<NGGridLayoutAlgorithm::GridItemData>& items_;
NGGridBlockTrackCollection* row_collection_;
NGGridBlockTrackCollection* column_collection_;
Vector<NGGridLayoutAlgorithm::GridItemData>* items_;
wtf_size_t starting_minor_line_ = 0;
wtf_size_t ending_minor_line_ = 0;
......
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