Disable use of rayon with --layout-threads 1 instead of panicking

This commit is contained in:
Simon Sapin 2019-12-08 15:00:40 +01:00
parent aade603025
commit c895e3d236
6 changed files with 56 additions and 36 deletions

View file

@ -11,6 +11,7 @@ use style::context::SharedStyleContext;
pub struct LayoutContext<'a> { pub struct LayoutContext<'a> {
pub id: PipelineId, pub id: PipelineId,
pub use_rayon: bool,
pub style_context: SharedStyleContext<'a>, pub style_context: SharedStyleContext<'a>,
pub font_cache_thread: Mutex<FontCacheThread>, pub font_cache_thread: Mutex<FontCacheThread>,
} }

View file

@ -168,12 +168,11 @@ impl BlockContainer {
builder.end_ongoing_inline_formatting_context(); builder.end_ongoing_inline_formatting_context();
} }
type Intermediate<Node> = IntermediateBlockLevelBox<Node>; struct Accumulator {
struct Target {
contains_floats: ContainsFloats, contains_floats: ContainsFloats,
outer_content_sizes_of_children: ContentSizes, outer_content_sizes_of_children: ContentSizes,
} }
impl Default for Target { impl Default for Accumulator {
fn default() -> Self { fn default() -> Self {
Self { Self {
contains_floats: ContainsFloats::No, contains_floats: ContainsFloats::No,
@ -181,37 +180,46 @@ impl BlockContainer {
} }
} }
} }
let mut target = Target { let mut acc = Accumulator {
contains_floats: builder.contains_floats, contains_floats: builder.contains_floats,
outer_content_sizes_of_children: ContentSizes::zero(), outer_content_sizes_of_children: ContentSizes::zero(),
}; };
let iter = builder.block_level_boxes.into_par_iter(); let mapfold =
let iter = iter.mapfold_reduce_into( |acc: &mut Accumulator,
&mut target, (intermediate, box_slot): (IntermediateBlockLevelBox<_>, BoxSlot<'_>)| {
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
let (block_level_box, box_contains_floats) = intermediate.finish( let (block_level_box, box_contains_floats) = intermediate.finish(
context, context,
content_sizes content_sizes.if_requests_inline(|| &mut acc.outer_content_sizes_of_children),
.if_requests_inline(|| &mut target.outer_content_sizes_of_children),
); );
target.contains_floats |= box_contains_floats; acc.contains_floats |= box_contains_floats;
box_slot.set(LayoutBox::BlockLevel(block_level_box.clone())); box_slot.set(LayoutBox::BlockLevel(block_level_box.clone()));
block_level_box block_level_box
}, };
|left, right| { let block_level_boxes = if context.use_rayon {
left.contains_floats |= right.contains_floats; builder
if content_sizes.requests_inline() { .block_level_boxes
left.outer_content_sizes_of_children .into_par_iter()
.max_assign(&right.outer_content_sizes_of_children) .mapfold_reduce_into(&mut acc, mapfold, |left, right| {
} left.contains_floats |= right.contains_floats;
}, if content_sizes.requests_inline() {
); left.outer_content_sizes_of_children
let container = BlockContainer::BlockLevelBoxes(iter.collect()); .max_assign(&right.outer_content_sizes_of_children)
}
})
.collect()
} else {
builder
.block_level_boxes
.into_iter()
.map(|x| mapfold(&mut acc, x))
.collect()
};
let container = BlockContainer::BlockLevelBoxes(block_level_boxes);
let Target { let Accumulator {
contains_floats, contains_floats,
outer_content_sizes_of_children, outer_content_sizes_of_children,
} = target; } = acc;
let content_sizes = content_sizes.compute(|| outer_content_sizes_of_children); let content_sizes = content_sizes.compute(|| outer_content_sizes_of_children);
(container, contains_floats, content_sizes) (container, contains_floats, content_sizes)
} }

View file

@ -135,7 +135,7 @@ fn layout_block_level_children<'a>(
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
tree_rank: usize, tree_rank: usize,
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>, absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
float_context: Option<&mut FloatContext>, mut float_context: Option<&mut FloatContext>,
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
) -> FlowLayout { ) -> FlowLayout {
fn place_block_level_fragment(fragment: &mut Fragment, placement_state: &mut PlacementState) { fn place_block_level_fragment(fragment: &mut Fragment, placement_state: &mut PlacementState) {
@ -203,7 +203,7 @@ fn layout_block_level_children<'a>(
current_block_direction_position: Length::zero(), current_block_direction_position: Length::zero(),
}; };
let mut fragments: Vec<_>; let mut fragments: Vec<_>;
if let Some(float_context) = float_context { if float_context.is_some() || !layout_context.use_rayon {
// Because floats are involved, we do layout for this block formatting context // Because floats are involved, we do layout for this block formatting context
// in tree order without parallelism. This enables mutable access // in tree order without parallelism. This enables mutable access
// to a `FloatContext` that tracks every float encountered so far (again in tree order). // to a `FloatContext` that tracks every float encountered so far (again in tree order).
@ -216,7 +216,7 @@ fn layout_block_level_children<'a>(
containing_block, containing_block,
tree_rank, tree_rank,
absolutely_positioned_fragments, absolutely_positioned_fragments,
Some(float_context), float_context.as_mut().map(|c| &mut **c),
); );
place_block_level_fragment(&mut fragment, &mut placement_state); place_block_level_fragment(&mut fragment, &mut placement_state);
fragment fragment

View file

@ -12,7 +12,7 @@ use crate::formatting_contexts::IndependentFormattingContext;
use crate::fragments::Fragment; use crate::fragments::Fragment;
use crate::geom; use crate::geom;
use crate::geom::flow_relative::Vec2; use crate::geom::flow_relative::Vec2;
use crate::positioned::AbsolutelyPositionedBox; use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment};
use crate::replaced::ReplacedContent; use crate::replaced::ReplacedContent;
use crate::sizing::ContentSizesRequest; use crate::sizing::ContentSizesRequest;
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside}; use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside};
@ -118,11 +118,18 @@ impl BoxTreeRoot {
&mut absolutely_positioned_fragments, &mut absolutely_positioned_fragments,
); );
independent_layout.fragments.par_extend( let map =
absolutely_positioned_fragments |a: &AbsolutelyPositionedFragment| a.layout(layout_context, &initial_containing_block);
.par_iter() if layout_context.use_rayon {
.map(|a| a.layout(layout_context, &initial_containing_block)), independent_layout
); .fragments
.par_extend(absolutely_positioned_fragments.par_iter().map(map))
} else {
independent_layout
.fragments
.extend(absolutely_positioned_fragments.iter().map(map))
}
FragmentTreeRoot(independent_layout.fragments) FragmentTreeRoot(independent_layout.fragments)
} }
} }

View file

@ -139,11 +139,14 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
size: padding_rect.size.clone(), size: padding_rect.size.clone(),
style, style,
}; };
let map = |a: &AbsolutelyPositionedFragment| a.layout(layout_context, &containing_block);
let children = if layout_context.use_rayon {
absolute.par_iter().map(map).collect()
} else {
absolute.iter().map(map).collect()
};
fragments.push(Fragment::Anonymous(AnonymousFragment { fragments.push(Fragment::Anonymous(AnonymousFragment {
children: absolute children,
.par_iter()
.map(|a| a.layout(layout_context, &containing_block))
.collect(),
rect: padding_rect, rect: padding_rect,
mode: style.writing_mode, mode: style.writing_mode,
})) }))

View file

@ -568,6 +568,7 @@ impl LayoutThread {
snapshot_map: snapshot_map, snapshot_map: snapshot_map,
}, },
font_cache_thread: Mutex::new(self.font_cache_thread.clone()), font_cache_thread: Mutex::new(self.font_cache_thread.clone()),
use_rayon: STYLE_THREAD_POOL.pool().is_some(),
} }
} }