Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimise CSS Grid #338

Merged
merged 12 commits into from
Jan 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 4 additions & 11 deletions benches/big_tree_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn build_deep_grid_tree(
create_container_node: &mut impl FnMut(&mut Taffy, Vec<Node>) -> Node,
) -> Vec<Node> {
// The extra one is for a position:absolute child
let child_count = track_count.pow(2) + 1;
let child_count = track_count * track_count;

if levels == 1 {
// Build leaf nodes
Expand All @@ -80,13 +80,6 @@ pub fn build_deep_grid_tree(
.map(|_| {
let sub_children =
build_deep_grid_tree(tree, levels - 1, track_count, create_leaf_node, create_container_node);
tree.set_style(sub_children[child_count - 1], {
let mut style = tree.style(sub_children[child_count - 1]).unwrap().clone();
style.position = Position::Absolute;
style.size = percent(0.5);
style
})
.unwrap();
create_container_node(tree, sub_children)
})
.collect()
Expand Down Expand Up @@ -127,8 +120,8 @@ fn taffy_benchmarks(c: &mut Criterion) {

let mut group = c.benchmark_group("grid/deep");
group.sample_size(10);
for (tracks, levels) in [(3, 3), (3, 4) /*, (3, 5)*/, (2, 3), (2, 4), (2, 5), (2, 6)].iter() {
let children_per_level: usize = (tracks * tracks) + 1;
for (tracks, levels) in [(2, 5), (3, 4), (2, 7) /*, (3, 5)*/].iter() {
let children_per_level: usize = tracks * tracks;
group.bench_with_input(
BenchmarkId::new(format!("{c}x{c}", c = tracks), children_per_level.pow(*levels as u32)),
&(*levels, *tracks),
Expand All @@ -145,7 +138,7 @@ fn taffy_benchmarks(c: &mut Criterion) {

let mut group = c.benchmark_group("grid/superdeep");
group.sample_size(10);
for levels in [10, 20].iter() {
for levels in [100, 1000].iter() {
group.bench_with_input(BenchmarkId::new("1x1", levels), levels, |b, &levels| {
b.iter_batched(
|| build_taffy_deep_grid_hierarchy(levels, 1),
Expand Down
2 changes: 1 addition & 1 deletion src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ fn compute_preliminary(
// We have the container size.
// If our caller does not care about performing layout we are done now.
if run_mode == RunMode::ComputeSize {
return SizeAndBaselines { size: constants.container_size, first_baselines: Point::NONE };
return constants.container_size.into();
}

// 16. Align all flex lines per align-content.
Expand Down
21 changes: 7 additions & 14 deletions src/compute/grid/explicit_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ use super::types::{GridTrack, TrackCounts};
use crate::axis::AbsoluteAxis;
use crate::math::MaybeMath;
use crate::resolve::ResolveOrZero;
use crate::style::{
AvailableSpace, GridTrackRepetition, LengthPercentage, NonRepeatedTrackSizingFunction, Style, TrackSizingFunction,
};
use crate::style::{GridTrackRepetition, LengthPercentage, NonRepeatedTrackSizingFunction, Style, TrackSizingFunction};
use crate::style_helpers::TaffyAuto;
use crate::sys::{GridTrackVec, Vec};
use core::cmp::{max, min};
Expand Down Expand Up @@ -83,25 +81,20 @@ pub(crate) fn compute_explicit_grid_size_in_axis(style: &Style, axis: AbsoluteAx
let num_repetitions: u16 = match inner_container_size {
None => 1,
Some(inner_container_size) => {
let available_space = AvailableSpace::Definite(inner_container_size);
let parent_size = Some(inner_container_size);

/// ...treating each track as its max track sizing function if that is definite or as its minimum track sizing function
/// otherwise, flooring the max track sizing function by the min track sizing function if both are definite
fn track_definite_value(
sizing_function: &NonRepeatedTrackSizingFunction,
available_space: AvailableSpace,
) -> f32 {
let max_size = sizing_function.max.definite_value(available_space);
let min_size = sizing_function.max.definite_value(available_space);
fn track_definite_value(sizing_function: &NonRepeatedTrackSizingFunction, parent_size: Option<f32>) -> f32 {
let max_size = sizing_function.max.definite_value(parent_size);
let min_size = sizing_function.max.definite_value(parent_size);
max_size.map(|max| max.maybe_min(min_size)).or(min_size).unwrap()
}

let non_repeating_track_used_space: f32 = template
.iter()
.map(|track_def| match track_def {
TrackSizingFunction::Single(sizing_function) => {
track_definite_value(sizing_function, available_space)
}
TrackSizingFunction::Single(sizing_function) => track_definite_value(sizing_function, parent_size),
TrackSizingFunction::AutoRepeat(_, _) => 0.0,
})
.sum();
Expand All @@ -110,7 +103,7 @@ pub(crate) fn compute_explicit_grid_size_in_axis(style: &Style, axis: AbsoluteAx
// Compute the amount of space that a single repetition of the repeated track list takes
let per_repetition_track_used_space: f32 = repetition_definition
.iter()
.map(|sizing_function| track_definite_value(sizing_function, available_space))
.map(|sizing_function| track_definite_value(sizing_function, parent_size))
.sum::<f32>();

// We special case the first repetition here because the number of gaps in the first repetition
Expand Down
61 changes: 34 additions & 27 deletions src/compute/grid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub fn compute(
known_dimensions: Size<Option<f32>>,
parent_size: Size<Option<f32>>,
available_space: Size<AvailableSpace>,
_run_mode: RunMode,
run_mode: RunMode,
) -> SizeAndBaselines {
let get_child_styles_iter = |node| tree.children(node).map(|child_node: &Node| tree.style(*child_node));
let style = tree.style(node).clone();
Expand Down Expand Up @@ -181,16 +181,15 @@ pub fn compute(
track_sizing_algorithm(
tree,
AbstractAxis::Inline,
available_space,
min_size.get(AbstractAxis::Inline),
max_size.get(AbstractAxis::Inline),
style.grid_align_content(AbstractAxis::Block),
available_grid_space,
inner_node_size,
&style,
&mut columns,
&mut rows,
&mut items,
|track: &GridTrack, available_space: AvailableSpace| {
track.max_track_sizing_function.definite_value(available_space)
},
|track: &GridTrack, parent_size: Option<f32>| track.max_track_sizing_function.definite_value(parent_size),
);
let initial_column_sum = columns.iter().map(|track| track.base_size).sum::<f32>();
inner_node_size.width = inner_node_size.width.or_else(|| initial_column_sum.into());
Expand All @@ -199,10 +198,11 @@ pub fn compute(
track_sizing_algorithm(
tree,
AbstractAxis::Block,
available_space,
min_size.get(AbstractAxis::Block),
max_size.get(AbstractAxis::Block),
style.grid_align_content(AbstractAxis::Inline),
available_grid_space,
inner_node_size,
&style,
&mut rows,
&mut columns,
&mut items,
Expand All @@ -211,14 +211,35 @@ pub fn compute(
let initial_row_sum = rows.iter().map(|track| track.base_size).sum::<f32>();
inner_node_size.height = inner_node_size.height.or_else(|| initial_row_sum.into());

// 6. Compute container size
let resolved_style_size = known_dimensions.or(style.size.maybe_resolve(parent_size));
let container_border_box = Size {
width: resolved_style_size
.get(AbstractAxis::Inline)
.unwrap_or_else(|| initial_column_sum + padding.horizontal_axis_sum() + border.horizontal_axis_sum()),
height: resolved_style_size
.get(AbstractAxis::Block)
.unwrap_or_else(|| initial_row_sum + padding.vertical_axis_sum() + border.vertical_axis_sum()),
};
let container_content_box = Size {
width: container_border_box.width - padding.horizontal_axis_sum() - border.horizontal_axis_sum(),
height: container_border_box.height - padding.vertical_axis_sum() - border.vertical_axis_sum(),
};

// If only the container's size has been requested
if run_mode == RunMode::ComputeSize {
return container_border_box.into();
}

// Re-run track sizing algorithm for Inline axis
track_sizing_algorithm(
tree,
AbstractAxis::Inline,
available_space,
min_size.get(AbstractAxis::Inline),
max_size.get(AbstractAxis::Inline),
style.grid_align_content(AbstractAxis::Block),
available_grid_space,
inner_node_size,
&style,
&mut columns,
&mut rows,
&mut items,
Expand All @@ -229,31 +250,17 @@ pub fn compute(
track_sizing_algorithm(
tree,
AbstractAxis::Block,
available_space,
min_size.get(AbstractAxis::Block),
max_size.get(AbstractAxis::Block),
style.grid_align_content(AbstractAxis::Inline),
available_grid_space,
inner_node_size,
&style,
&mut rows,
&mut columns,
&mut items,
|track: &GridTrack, _| Some(track.base_size),
);

// 6. Compute container size
let resolved_style_size = known_dimensions.or(style.size.maybe_resolve(parent_size));
let container_border_box = Size {
width: resolved_style_size
.get(AbstractAxis::Inline)
.unwrap_or_else(|| initial_column_sum + padding.horizontal_axis_sum() + border.horizontal_axis_sum()),
height: resolved_style_size
.get(AbstractAxis::Block)
.unwrap_or_else(|| initial_row_sum + padding.vertical_axis_sum() + border.vertical_axis_sum()),
};
let container_content_box = Size {
width: container_border_box.width - padding.horizontal_axis_sum() - border.horizontal_axis_sum(),
height: container_border_box.height - padding.vertical_axis_sum() - border.vertical_axis_sum(),
};

// 7. Resolve percentage track base sizes
// In the case of an indefinitely sized container these resolve to zero during the "Initialise Tracks" step
// and therefore need to be re-resolved here based on the content-sized content box of the container
Expand Down
Loading