Skip to content

Commit

Permalink
Rayon WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoburns committed May 11, 2024
1 parent 066949d commit dde8c6a
Show file tree
Hide file tree
Showing 12 changed files with 92 additions and 75 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ num-traits = { version = "0.2", default-features = false }
serde = { version = "1.0", default-features = false, optional = true, features = ["serde_derive"] }
slotmap = { version = "1.0.6", default-features = false, optional = true }
grid = { version = "0.13.0", default-features = false, optional = true }
rayon = "1.10.0"

### FEATURES #################################################################

Expand Down
10 changes: 5 additions & 5 deletions src/compute/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ struct BlockItem {
}

/// Computes the layout of [`LayoutPartialTree`] according to the block layout algorithm
pub fn compute_block_layout(tree: &mut impl LayoutPartialTree, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput {
pub fn compute_block_layout(tree: &impl LayoutPartialTree, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput {
let LayoutInput { known_dimensions, parent_size, available_space, run_mode, .. } = inputs;
let style = tree.get_style(node_id);

Expand Down Expand Up @@ -104,7 +104,7 @@ pub fn compute_block_layout(tree: &mut impl LayoutPartialTree, node_id: NodeId,
}

/// Computes the layout of [`LayoutPartialTree`] according to the block layout algorithm
fn compute_inner(tree: &mut impl LayoutPartialTree, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput {
fn compute_inner(tree: &impl LayoutPartialTree, node_id: NodeId, inputs: LayoutInput) -> LayoutOutput {
let LayoutInput {
known_dimensions, parent_size, available_space, run_mode, vertical_margins_are_collapsible, ..
} = inputs;
Expand Down Expand Up @@ -298,7 +298,7 @@ fn generate_item_list(
/// Compute the content-based width in the case that the width of the container is not known
#[inline]
fn determine_content_based_container_width(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
items: &[BlockItem],
available_width: AvailableSpace,
) -> f32 {
Expand Down Expand Up @@ -333,7 +333,7 @@ fn determine_content_based_container_width(
/// Compute each child's final size and position
#[inline]
fn perform_final_layout_on_in_flow_children(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
items: &mut [BlockItem],
container_outer_width: f32,
content_box_inset: Rect<f32>,
Expand Down Expand Up @@ -488,7 +488,7 @@ fn perform_final_layout_on_in_flow_children(
/// Perform absolute layout on all absolutely positioned children.
#[inline]
fn perform_absolute_layout_on_absolute_children(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
items: &[BlockItem],
area_size: Size<f32>,
area_offset: Point<f32>,
Expand Down
39 changes: 23 additions & 16 deletions src/compute/flexbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::util::debug::debug_log;
use crate::util::sys::{f32_max, new_vec_with_capacity, Vec};
use crate::util::MaybeMath;
use crate::util::{MaybeResolve, ResolveOrZero};
use rayon::prelude::*;

#[cfg(feature = "content_size")]
use super::common::content_size::compute_content_size_contribution;
Expand Down Expand Up @@ -152,7 +153,7 @@ struct AlgoConstants {
}

/// Computes the layout of [`LayoutPartialTree`] according to the flexbox algorithm
pub fn compute_flexbox_layout(tree: &mut impl LayoutPartialTree, node: NodeId, inputs: LayoutInput) -> LayoutOutput {
pub fn compute_flexbox_layout(tree: &impl LayoutPartialTree, node: NodeId, inputs: LayoutInput) -> LayoutOutput {
let LayoutInput { known_dimensions, parent_size, run_mode, .. } = inputs;
let style = tree.get_style(node);

Expand Down Expand Up @@ -186,7 +187,7 @@ pub fn compute_flexbox_layout(tree: &mut impl LayoutPartialTree, node: NodeId, i
}

/// Compute a preliminary size for an item
fn compute_preliminary(tree: &mut impl LayoutPartialTree, node: NodeId, inputs: LayoutInput) -> LayoutOutput {
fn compute_preliminary(tree: &impl LayoutPartialTree, node: NodeId, inputs: LayoutInput) -> LayoutOutput {
let LayoutInput { known_dimensions, parent_size, available_space, run_mode, .. } = inputs;

// Define some general constants we will need for the remainder of the algorithm.
Expand Down Expand Up @@ -562,14 +563,15 @@ fn determine_available_space(
/// (For example, an item with a specified size of zero, positive padding, and box-sizing: border-box will have an outer flex base size of zero—and hence a negative inner flex base size.)
#[inline]
fn determine_flex_base_size(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
constants: &AlgoConstants,
available_space: Size<AvailableSpace>,
flex_items: &mut [FlexItem],
) {
let dir = constants.dir;

for child in flex_items.iter_mut() {
let block_size = (flex_items.len() / 8).max(1);
flex_items.par_iter_mut().by_uniform_blocks(block_size).for_each(|child| {
let child_style = tree.get_style(child.node);

// Parent size for child sizing
Expand Down Expand Up @@ -717,7 +719,7 @@ fn determine_flex_base_size(
min_content_main_size.maybe_min(child.size.main(dir)).maybe_min(child.max_size.main(dir));
clamped_min_content_size.maybe_max(padding_border_axes_sums.main(dir))
});
}
});
}

/// Collect flex items into flex lines.
Expand Down Expand Up @@ -802,7 +804,7 @@ fn collect_flex_lines<'a>(

/// Determine the container's main size (if not already known)
fn determine_container_main_size(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
available_space: Size<AvailableSpace>,
lines: &mut [FlexLine<'_>],
constants: &mut AlgoConstants,
Expand Down Expand Up @@ -1208,7 +1210,7 @@ fn resolve_flexible_lengths(line: &mut FlexLine, constants: &AlgoConstants, orig
/// by performing layout with the used main size and the available space, treating auto as fit-content.
#[inline]
fn determine_hypothetical_cross_size(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
line: &mut FlexLine,
constants: &AlgoConstants,
available_space: Size<AvailableSpace>,
Expand Down Expand Up @@ -1258,7 +1260,7 @@ fn determine_hypothetical_cross_size(
/// Calculate the base lines of the children.
#[inline]
fn calculate_children_base_lines(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
node_size: Size<Option<f32>>,
available_space: Size<AvailableSpace>,
flex_lines: &mut [FlexLine],
Expand Down Expand Up @@ -1722,7 +1724,7 @@ fn align_flex_lines_per_align_content(flex_lines: &mut [FlexLine], constants: &A
/// Calculates the layout for a flex-item
#[allow(clippy::too_many_arguments)]
fn calculate_flex_item(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
item: &mut FlexItem,
total_offset_main: &mut f32,
total_offset_cross: f32,
Expand Down Expand Up @@ -1803,7 +1805,7 @@ fn calculate_flex_item(
/// Calculates the layout line
#[allow(clippy::too_many_arguments)]
fn calculate_layout_line(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
line: &mut FlexLine,
total_offset_cross: &mut f32,
#[cfg(feature = "content_size")] content_size: &mut Size<f32>,
Expand All @@ -1815,8 +1817,11 @@ fn calculate_layout_line(
let mut total_offset_main = padding_border.main_start(direction);
let line_offset_cross = line.offset_cross;

let block_size = (line.items.len() / 8).max(1);
if direction.is_reverse() {
for item in line.items.iter_mut().rev() {
line.items.par_iter_mut().rev().by_uniform_blocks(block_size).for_each(|item| {
let mut total_offset_main = 0.0;
let mut content_size = &mut Size::ZERO;
calculate_flex_item(
tree,
item,
Expand All @@ -1829,9 +1834,11 @@ fn calculate_layout_line(
node_inner_size,
direction,
);
}
});
} else {
for item in line.items.iter_mut() {
line.items.par_iter_mut().by_uniform_blocks(block_size).for_each(|item| {
let mut total_offset_main = 0.0;
let mut content_size = &mut Size::ZERO;
calculate_flex_item(
tree,
item,
Expand All @@ -1844,7 +1851,7 @@ fn calculate_layout_line(
node_inner_size,
direction,
);
}
});
}

*total_offset_cross += line_offset_cross + line.cross_size;
Expand All @@ -1853,7 +1860,7 @@ fn calculate_layout_line(
/// Do a final layout pass and collect the resulting layouts.
#[inline]
fn final_layout_pass(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
flex_lines: &mut [FlexLine],
constants: &AlgoConstants,
) -> Size<f32> {
Expand Down Expand Up @@ -1898,7 +1905,7 @@ fn final_layout_pass(
/// Perform absolute layout on all absolutely positioned children.
#[inline]
fn perform_absolute_layout_on_absolute_children(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
node: NodeId,
constants: &AlgoConstants,
) -> Size<f32> {
Expand Down
2 changes: 1 addition & 1 deletion src/compute/grid/alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pub(super) fn align_tracks(

/// Align and size a grid item into it's final position
pub(super) fn align_and_position_item(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
node: NodeId,
order: u32,
grid_area: Rect<f32>,
Expand Down
2 changes: 1 addition & 1 deletion src/compute/grid/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ mod util;
/// - Placing items (which also resolves the implicit grid)
/// - Track (row/column) sizing
/// - Alignment & Final item placement
pub fn compute_grid_layout(tree: &mut impl LayoutPartialTree, node: NodeId, inputs: LayoutInput) -> LayoutOutput {
pub fn compute_grid_layout(tree: &impl LayoutPartialTree, node: NodeId, inputs: LayoutInput) -> LayoutOutput {
let LayoutInput { known_dimensions, parent_size, available_space, run_mode, .. } = inputs;

let get_child_styles_iter = |node| tree.child_ids(node).map(|child_node: NodeId| tree.get_style(child_node));
Expand Down
10 changes: 5 additions & 5 deletions src/compute/grid/track_sizing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ where
EstimateFunction: Fn(&GridTrack, Option<f32>) -> Option<f32>,
{
/// The layout tree
tree: &'tree mut Tree,
tree: &'tree Tree,
/// The tracks in the opposite axis to the one we are currently sizing
other_axis_tracks: &'oat [GridTrack],
/// A function that computes an estimate of an other-axis track's size which is passed to
Expand Down Expand Up @@ -261,7 +261,7 @@ pub(super) fn determine_if_item_crosses_flexible_or_intrinsic_tracks(
/// Note: Gutters are treated as empty fixed-size tracks for the purpose of the track sizing algorithm.
#[allow(clippy::too_many_arguments)]
pub(super) fn track_sizing_algorithm<Tree: LayoutPartialTree>(
tree: &mut Tree,
tree: &Tree,
axis: AbstractAxis,
axis_min_size: Option<f32>,
axis_max_size: Option<f32>,
Expand Down Expand Up @@ -435,7 +435,7 @@ fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_inner_node_size: O

/// 11.5.1 Shim baseline-aligned items so their intrinsic size contributions reflect their baseline alignment.
fn resolve_item_baselines(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
axis: AbstractAxis,
items: &mut [GridItem],
inner_node_size: Size<Option<f32>>,
Expand Down Expand Up @@ -508,7 +508,7 @@ fn resolve_item_baselines(
/// 11.5 Resolve Intrinsic Track Sizes
#[allow(clippy::too_many_arguments)]
fn resolve_intrinsic_track_sizes(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
axis: AbstractAxis,
axis_tracks: &mut [GridTrack],
other_axis_tracks: &[GridTrack],
Expand Down Expand Up @@ -1139,7 +1139,7 @@ fn maximise_tracks(
#[allow(clippy::too_many_arguments)]
#[inline(always)]
fn expand_flexible_tracks(
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
axis: AbstractAxis,
axis_tracks: &mut [GridTrack],
items: &mut [GridItem],
Expand Down
12 changes: 6 additions & 6 deletions src/compute/grid/types/grid_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl GridItem {
pub fn min_content_contribution(
&self,
axis: AbstractAxis,
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
available_space: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
Expand All @@ -364,7 +364,7 @@ impl GridItem {
pub fn min_content_contribution_cached(
&mut self,
axis: AbstractAxis,
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
available_space: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
Expand All @@ -379,7 +379,7 @@ impl GridItem {
pub fn max_content_contribution(
&self,
axis: AbstractAxis,
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
available_space: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
Expand All @@ -403,7 +403,7 @@ impl GridItem {
pub fn max_content_contribution_cached(
&mut self,
axis: AbstractAxis,
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
available_space: Size<Option<f32>>,
inner_node_size: Size<Option<f32>>,
) -> f32 {
Expand All @@ -423,7 +423,7 @@ impl GridItem {
/// See: https://www.w3.org/TR/css-grid-1/#min-size-auto
pub fn minimum_contribution(
&mut self,
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
axis: AbstractAxis,
axis_tracks: &[GridTrack],
known_dimensions: Size<Option<f32>>,
Expand Down Expand Up @@ -482,7 +482,7 @@ impl GridItem {
#[inline(always)]
pub fn minimum_contribution_cached(
&mut self,
tree: &mut impl LayoutPartialTree,
tree: &impl LayoutPartialTree,
axis: AbstractAxis,
axis_tracks: &[GridTrack],
known_dimensions: Size<Option<f32>>,
Expand Down
10 changes: 5 additions & 5 deletions src/compute/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//!
//! ### Layout functions
//!
//! The layout functions all take an [`&mut impl LayoutPartialTree`](crate::LayoutPartialTree) parameter, which represents a single container node and it's direct children.
//! The layout functions all take an [`&impl LayoutPartialTree`](crate::LayoutPartialTree) parameter, which represents a single container node and it's direct children.
//!
//! | Function | Purpose |
//! | --- | --- |
Expand Down Expand Up @@ -54,7 +54,7 @@ use crate::util::sys::round;
use crate::util::ResolveOrZero;

/// Compute layout for the root node in the tree
pub fn compute_root_layout(tree: &mut impl LayoutPartialTree, root: NodeId, available_space: Size<AvailableSpace>) {
pub fn compute_root_layout(tree: &impl LayoutPartialTree, root: NodeId, available_space: Size<AvailableSpace>) {
// Recursively compute node layout
let output = tree.perform_child_layout(
root,
Expand Down Expand Up @@ -93,13 +93,13 @@ pub fn compute_root_layout(tree: &mut impl LayoutPartialTree, root: NodeId, avai
/// Uses the provided closure to compute the layout (and then stores the result in the cache) if no cached layout is found.
#[inline(always)]
pub fn compute_cached_layout<Tree: LayoutPartialTree + ?Sized, ComputeFunction>(
tree: &mut Tree,
tree: &Tree,
node: NodeId,
inputs: LayoutInput,
mut compute_uncached: ComputeFunction,
) -> LayoutOutput
where
ComputeFunction: FnMut(&mut Tree, NodeId, LayoutInput) -> LayoutOutput,
ComputeFunction: FnMut(&Tree, NodeId, LayoutInput) -> LayoutOutput,
{
debug_push_node!(node);
let LayoutInput { known_dimensions, available_space, run_mode, .. } = inputs;
Expand Down Expand Up @@ -194,7 +194,7 @@ pub fn round_layout(tree: &mut impl RoundTree, node_id: NodeId) {

/// Creates a layout for this node and its children, recursively.
/// Each hidden node has zero size and is placed at the origin
pub fn compute_hidden_layout(tree: &mut impl LayoutPartialTree, node: NodeId) -> LayoutOutput {
pub fn compute_hidden_layout(tree: &impl LayoutPartialTree, node: NodeId) -> LayoutOutput {
// Clear cache and set zeroed-out layout for the node
tree.get_cache_mut(node).clear();
tree.set_unrounded_layout(node, &Layout::with_order(0));
Expand Down
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
//! - [custom_tree_owned_unsafe](https:/DioxusLabs/taffy/blob/main/examples/custom_tree_owned_unsafe.rs) which implements a custom Taffy tree using directly owned children with NodeId's being pointers.

#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code)]
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![warn(clippy::missing_docs_in_private_items)]

Expand Down
Loading

0 comments on commit dde8c6a

Please sign in to comment.