mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #25230 - servo:sequential, r=nox
Fix `--layout-threads 1` in layout 2020
This commit is contained in:
commit
b98a8fc576
7 changed files with 72 additions and 43 deletions
|
@ -11,6 +11,7 @@ use style::context::SharedStyleContext;
|
|||
|
||||
pub struct LayoutContext<'a> {
|
||||
pub id: PipelineId,
|
||||
pub use_rayon: bool,
|
||||
pub style_context: SharedStyleContext<'a>,
|
||||
pub font_cache_thread: Mutex<FontCacheThread>,
|
||||
}
|
||||
|
|
|
@ -168,12 +168,11 @@ impl BlockContainer {
|
|||
builder.end_ongoing_inline_formatting_context();
|
||||
}
|
||||
|
||||
type Intermediate<Node> = IntermediateBlockLevelBox<Node>;
|
||||
struct Target {
|
||||
struct Accumulator {
|
||||
contains_floats: ContainsFloats,
|
||||
outer_content_sizes_of_children: ContentSizes,
|
||||
}
|
||||
impl Default for Target {
|
||||
impl Default for Accumulator {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
contains_floats: ContainsFloats::No,
|
||||
|
@ -181,37 +180,46 @@ impl BlockContainer {
|
|||
}
|
||||
}
|
||||
}
|
||||
let mut target = Target {
|
||||
let mut acc = Accumulator {
|
||||
contains_floats: builder.contains_floats,
|
||||
outer_content_sizes_of_children: ContentSizes::zero(),
|
||||
};
|
||||
let iter = builder.block_level_boxes.into_par_iter();
|
||||
let iter = iter.mapfold_reduce_into(
|
||||
&mut target,
|
||||
|target, (intermediate, box_slot): (Intermediate<_>, BoxSlot<'_>)| {
|
||||
let mapfold =
|
||||
|acc: &mut Accumulator,
|
||||
(intermediate, box_slot): (IntermediateBlockLevelBox<_>, BoxSlot<'_>)| {
|
||||
let (block_level_box, box_contains_floats) = intermediate.finish(
|
||||
context,
|
||||
content_sizes
|
||||
.if_requests_inline(|| &mut target.outer_content_sizes_of_children),
|
||||
content_sizes.if_requests_inline(|| &mut acc.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()));
|
||||
block_level_box
|
||||
},
|
||||
|left, right| {
|
||||
left.contains_floats |= right.contains_floats;
|
||||
if content_sizes.requests_inline() {
|
||||
left.outer_content_sizes_of_children
|
||||
.max_assign(&right.outer_content_sizes_of_children)
|
||||
}
|
||||
},
|
||||
);
|
||||
let container = BlockContainer::BlockLevelBoxes(iter.collect());
|
||||
};
|
||||
let block_level_boxes = if context.use_rayon {
|
||||
builder
|
||||
.block_level_boxes
|
||||
.into_par_iter()
|
||||
.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
|
||||
.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,
|
||||
outer_content_sizes_of_children,
|
||||
} = target;
|
||||
} = acc;
|
||||
let content_sizes = content_sizes.compute(|| outer_content_sizes_of_children);
|
||||
(container, contains_floats, content_sizes)
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ fn layout_block_level_children<'a>(
|
|||
containing_block: &ContainingBlock,
|
||||
tree_rank: usize,
|
||||
absolutely_positioned_fragments: &mut Vec<AbsolutelyPositionedFragment<'a>>,
|
||||
float_context: Option<&mut FloatContext>,
|
||||
mut float_context: Option<&mut FloatContext>,
|
||||
collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin,
|
||||
) -> FlowLayout {
|
||||
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(),
|
||||
};
|
||||
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
|
||||
// in tree order without parallelism. This enables mutable access
|
||||
// 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,
|
||||
tree_rank,
|
||||
absolutely_positioned_fragments,
|
||||
Some(float_context),
|
||||
float_context.as_mut().map(|c| &mut **c),
|
||||
);
|
||||
place_block_level_fragment(&mut fragment, &mut placement_state);
|
||||
fragment
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::formatting_contexts::IndependentFormattingContext;
|
|||
use crate::fragments::Fragment;
|
||||
use crate::geom;
|
||||
use crate::geom::flow_relative::Vec2;
|
||||
use crate::positioned::AbsolutelyPositionedBox;
|
||||
use crate::positioned::{AbsolutelyPositionedBox, AbsolutelyPositionedFragment};
|
||||
use crate::replaced::ReplacedContent;
|
||||
use crate::sizing::ContentSizesRequest;
|
||||
use crate::style_ext::{Display, DisplayGeneratingBox, DisplayInside};
|
||||
|
@ -118,11 +118,18 @@ impl BoxTreeRoot {
|
|||
&mut absolutely_positioned_fragments,
|
||||
);
|
||||
|
||||
independent_layout.fragments.par_extend(
|
||||
absolutely_positioned_fragments
|
||||
.par_iter()
|
||||
.map(|a| a.layout(layout_context, &initial_containing_block)),
|
||||
);
|
||||
let map =
|
||||
|a: &AbsolutelyPositionedFragment| a.layout(layout_context, &initial_containing_block);
|
||||
if layout_context.use_rayon {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,11 +139,14 @@ impl<'a> AbsolutelyPositionedFragment<'a> {
|
|||
size: padding_rect.size.clone(),
|
||||
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 {
|
||||
children: absolute
|
||||
.par_iter()
|
||||
.map(|a| a.layout(layout_context, &containing_block))
|
||||
.collect(),
|
||||
children,
|
||||
rect: padding_rect,
|
||||
mode: style.writing_mode,
|
||||
}))
|
||||
|
|
|
@ -568,6 +568,7 @@ impl LayoutThread {
|
|||
snapshot_map: snapshot_map,
|
||||
},
|
||||
font_cache_thread: Mutex::new(self.font_cache_thread.clone()),
|
||||
use_rayon: STYLE_THREAD_POOL.pool().is_some(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1076,14 +1077,18 @@ impl LayoutThread {
|
|||
};
|
||||
|
||||
let rayon_pool = STYLE_THREAD_POOL.pool();
|
||||
let rayon_pool = rayon_pool.as_ref().unwrap();
|
||||
let rayon_pool = rayon_pool.as_ref();
|
||||
|
||||
let box_tree = if token.should_traverse() {
|
||||
driver::traverse_dom(&traversal, token, Some(rayon_pool));
|
||||
driver::traverse_dom(&traversal, token, rayon_pool);
|
||||
|
||||
let root_node = document.root_element().unwrap().as_node();
|
||||
let box_tree =
|
||||
rayon_pool.install(|| BoxTreeRoot::construct(traversal.context(), root_node));
|
||||
let build_box_tree = || BoxTreeRoot::construct(traversal.context(), root_node);
|
||||
let box_tree = if let Some(pool) = rayon_pool {
|
||||
pool.install(build_box_tree)
|
||||
} else {
|
||||
build_box_tree()
|
||||
};
|
||||
Some(box_tree)
|
||||
} else {
|
||||
None
|
||||
|
@ -1096,8 +1101,12 @@ impl LayoutThread {
|
|||
self.viewport_size.width.to_f32_px(),
|
||||
self.viewport_size.height.to_f32_px(),
|
||||
);
|
||||
let fragment_tree =
|
||||
rayon_pool.install(|| box_tree.layout(&layout_context, viewport_size));
|
||||
let run_layout = || box_tree.layout(&layout_context, viewport_size);
|
||||
let fragment_tree = if let Some(pool) = rayon_pool {
|
||||
pool.install(run_layout)
|
||||
} else {
|
||||
run_layout()
|
||||
};
|
||||
*self.box_tree_root.borrow_mut() = Some(box_tree);
|
||||
*self.fragment_tree_root.borrow_mut() = Some(fragment_tree);
|
||||
}
|
||||
|
|
|
@ -454,10 +454,11 @@ impl ToCss for Display {
|
|||
where
|
||||
W: fmt::Write,
|
||||
{
|
||||
#[cfg(any(feature = "servo-layout-2013", feature = "gecko"))]
|
||||
debug_assert_ne!(
|
||||
self.inside(),
|
||||
DisplayInside::Flow,
|
||||
"`flow` never appears in `display` computed value"
|
||||
"`flow` fears in `display` computed value"
|
||||
);
|
||||
let outside = self.outside();
|
||||
let inside = match self.inside() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue