mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Remove rayon_croissant and clean up contains_floats
(#29960)
Remove rayon_croissant and refactor the way that information about floats in flows bubbles up. This simplifies the code a good deal and lets us take advantage of some more optimized functions provided by rayon. This removes 2 crates from the dependency tree. In addition, this allows avoiding passing `contains_floats` up from every box tree construction function. This makes things simpler, but also opens up the possibility of passing more of these flags up in the future (such as `contains_counters`).
This commit is contained in:
parent
9c333ab1ee
commit
4f4c2a5922
7 changed files with 108 additions and 144 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -3051,7 +3051,6 @@ dependencies = [
|
||||||
"quickcheck",
|
"quickcheck",
|
||||||
"range",
|
"range",
|
||||||
"rayon",
|
"rayon",
|
||||||
"rayon_croissant",
|
|
||||||
"script_layout_interface",
|
"script_layout_interface",
|
||||||
"script_traits",
|
"script_traits",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -3688,12 +3687,6 @@ version = "1.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f"
|
checksum = "9de3eca27871df31c33b807f834b94ef7d000956f57aa25c5aed9c5f0aae8f6f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "moite_moite"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eeb5a94c61e12e2cfc16ee3e2b6eca8f126a43c888586626337544a7e824a1af"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mozangle"
|
name = "mozangle"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -4814,16 +4807,6 @@ dependencies = [
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rayon_croissant"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3e4aafda434bd10fec689858e2b1d713d0b784b1e60df3761ac8fa727d7e8e27"
|
|
||||||
dependencies = [
|
|
||||||
"moite_moite",
|
|
||||||
"rayon",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.2.13"
|
version = "0.2.13"
|
||||||
|
|
|
@ -34,7 +34,6 @@ net_traits = { path = "../net_traits" }
|
||||||
parking_lot = { workspace = true }
|
parking_lot = { workspace = true }
|
||||||
range = { path = "../range" }
|
range = { path = "../range" }
|
||||||
rayon = { workspace = true }
|
rayon = { workspace = true }
|
||||||
rayon_croissant = "0.2.0"
|
|
||||||
script_layout_interface = { path = "../script_layout_interface" }
|
script_layout_interface = { path = "../script_layout_interface" }
|
||||||
script_traits = { path = "../script_traits" }
|
script_traits = { path = "../script_traits" }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
|
|
|
@ -13,7 +13,6 @@ use crate::formatting_contexts::IndependentFormattingContext;
|
||||||
use crate::positioned::AbsolutelyPositionedBox;
|
use crate::positioned::AbsolutelyPositionedBox;
|
||||||
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
use crate::style_ext::{ComputedValuesExt, DisplayGeneratingBox, DisplayInside, DisplayOutside};
|
||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use rayon_croissant::ParallelIteratorExt;
|
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
|
@ -34,18 +33,19 @@ impl BlockFormattingContext {
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
let (contents, contains_floats) = BlockContainer::construct(
|
let contents = BlockContainer::construct(
|
||||||
context,
|
context,
|
||||||
info,
|
info,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_text_decoration_line,
|
||||||
is_list_item,
|
is_list_item,
|
||||||
);
|
);
|
||||||
let bfc = Self {
|
let contains_floats = contents.contains_floats();
|
||||||
|
|
||||||
|
Self {
|
||||||
contents,
|
contents,
|
||||||
contains_floats: contains_floats == ContainsFloats::Yes,
|
contains_floats,
|
||||||
};
|
}
|
||||||
bfc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn construct_for_text_runs<'dom>(
|
pub fn construct_for_text_runs<'dom>(
|
||||||
|
@ -61,6 +61,7 @@ impl BlockFormattingContext {
|
||||||
inline_level_boxes,
|
inline_level_boxes,
|
||||||
text_decoration_line,
|
text_decoration_line,
|
||||||
has_first_formatted_line: true,
|
has_first_formatted_line: true,
|
||||||
|
contains_floats: false,
|
||||||
};
|
};
|
||||||
let contents = BlockContainer::InlineFormattingContext(ifc);
|
let contents = BlockContainer::InlineFormattingContext(ifc);
|
||||||
let bfc = Self {
|
let bfc = Self {
|
||||||
|
@ -163,9 +164,6 @@ struct BlockContainerBuilder<'dom, 'style, Node> {
|
||||||
/// The style of the anonymous block boxes pushed to the list of block-level
|
/// The style of the anonymous block boxes pushed to the list of block-level
|
||||||
/// boxes, if any (see `end_ongoing_inline_formatting_context`).
|
/// boxes, if any (see `end_ongoing_inline_formatting_context`).
|
||||||
anonymous_style: Option<Arc<ComputedValues>>,
|
anonymous_style: Option<Arc<ComputedValues>>,
|
||||||
|
|
||||||
/// Whether the resulting block container contains any float box.
|
|
||||||
contains_floats: ContainsFloats,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockContainer {
|
impl BlockContainer {
|
||||||
|
@ -175,7 +173,7 @@ impl BlockContainer {
|
||||||
contents: NonReplacedContents,
|
contents: NonReplacedContents,
|
||||||
propagated_text_decoration_line: TextDecorationLine,
|
propagated_text_decoration_line: TextDecorationLine,
|
||||||
is_list_item: bool,
|
is_list_item: bool,
|
||||||
) -> (BlockContainer, ContainsFloats)
|
) -> BlockContainer
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
|
@ -191,7 +189,6 @@ impl BlockContainer {
|
||||||
),
|
),
|
||||||
ongoing_inline_boxes_stack: Vec::new(),
|
ongoing_inline_boxes_stack: Vec::new(),
|
||||||
anonymous_style: None,
|
anonymous_style: None,
|
||||||
contains_floats: ContainsFloats::No,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if is_list_item {
|
if is_list_item {
|
||||||
|
@ -222,43 +219,28 @@ impl BlockContainer {
|
||||||
.is_empty()
|
.is_empty()
|
||||||
{
|
{
|
||||||
if builder.block_level_boxes.is_empty() {
|
if builder.block_level_boxes.is_empty() {
|
||||||
let container = BlockContainer::InlineFormattingContext(
|
return BlockContainer::InlineFormattingContext(
|
||||||
builder.ongoing_inline_formatting_context,
|
builder.ongoing_inline_formatting_context,
|
||||||
);
|
);
|
||||||
return (container, builder.contains_floats);
|
|
||||||
}
|
}
|
||||||
builder.end_ongoing_inline_formatting_context();
|
builder.end_ongoing_inline_formatting_context();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut contains_floats = builder.contains_floats;
|
|
||||||
let mapfold = |contains_floats: &mut ContainsFloats, creator: BlockLevelJob<'dom, _>| {
|
|
||||||
let (block_level_box, box_contains_floats) = creator.finish(context);
|
|
||||||
*contains_floats |= box_contains_floats;
|
|
||||||
block_level_box
|
|
||||||
};
|
|
||||||
let block_level_boxes = if context.use_rayon {
|
let block_level_boxes = if context.use_rayon {
|
||||||
builder
|
builder
|
||||||
.block_level_boxes
|
.block_level_boxes
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.mapfold_reduce_into(
|
.map(|block_level_job| block_level_job.finish(context))
|
||||||
&mut contains_floats,
|
|
||||||
mapfold,
|
|
||||||
|| ContainsFloats::No,
|
|
||||||
|left, right| {
|
|
||||||
*left |= right;
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
.collect()
|
||||||
} else {
|
} else {
|
||||||
builder
|
builder
|
||||||
.block_level_boxes
|
.block_level_boxes
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| mapfold(&mut contains_floats, x))
|
.map(|block_level_job| block_level_job.finish(context))
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
let container = BlockContainer::BlockLevelBoxes(block_level_boxes);
|
|
||||||
|
|
||||||
(container, contains_floats)
|
BlockContainer::BlockLevelBoxes(block_level_boxes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,8 +644,6 @@ where
|
||||||
contents: Contents,
|
contents: Contents,
|
||||||
box_slot: BoxSlot<'dom>,
|
box_slot: BoxSlot<'dom>,
|
||||||
) {
|
) {
|
||||||
self.contains_floats = ContainsFloats::Yes;
|
|
||||||
|
|
||||||
if !self.has_ongoing_inline_formatting_context() {
|
if !self.has_ongoing_inline_formatting_context() {
|
||||||
let kind = BlockLevelCreator::OutOfFlowFloatBox {
|
let kind = BlockLevelCreator::OutOfFlowFloatBox {
|
||||||
contents,
|
contents,
|
||||||
|
@ -681,6 +661,7 @@ where
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
)));
|
)));
|
||||||
|
self.ongoing_inline_formatting_context.contains_floats = true;
|
||||||
self.current_inline_level_boxes().push(box_.clone());
|
self.current_inline_level_boxes().push(box_.clone());
|
||||||
box_slot.set(LayoutBox::InlineLevel(box_))
|
box_slot.set(LayoutBox::InlineLevel(box_))
|
||||||
}
|
}
|
||||||
|
@ -748,17 +729,18 @@ impl<'dom, Node> BlockLevelJob<'dom, Node>
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
fn finish(self, context: &LayoutContext) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) {
|
fn finish(self, context: &LayoutContext) -> ArcRefCell<BlockLevelBox> {
|
||||||
let info = &self.info;
|
let info = &self.info;
|
||||||
let (block_level_box, contains_floats) = match self.kind {
|
let block_level_box = match self.kind {
|
||||||
BlockLevelCreator::SameFormattingContextBlock(contents) => {
|
BlockLevelCreator::SameFormattingContextBlock(intermediate_block_container) => {
|
||||||
let (contents, contains_floats) = contents.finish(context, info);
|
let contents = intermediate_block_container.finish(context, info);
|
||||||
let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
|
let contains_floats = contents.contains_floats();
|
||||||
|
ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
|
||||||
base_fragment_info: info.into(),
|
base_fragment_info: info.into(),
|
||||||
contents,
|
contents,
|
||||||
style: Arc::clone(&info.style),
|
style: Arc::clone(&info.style),
|
||||||
});
|
contains_floats,
|
||||||
(block_level_box, contains_floats)
|
})
|
||||||
},
|
},
|
||||||
BlockLevelCreator::Independent {
|
BlockLevelCreator::Independent {
|
||||||
display_inside,
|
display_inside,
|
||||||
|
@ -772,35 +754,32 @@ where
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_text_decoration_line,
|
||||||
);
|
);
|
||||||
(
|
ArcRefCell::new(BlockLevelBox::Independent(context))
|
||||||
ArcRefCell::new(BlockLevelBox::Independent(context)),
|
|
||||||
ContainsFloats::No,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
BlockLevelCreator::OutOfFlowAbsolutelyPositionedBox {
|
BlockLevelCreator::OutOfFlowAbsolutelyPositionedBox {
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
} => {
|
} => ArcRefCell::new(BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(
|
||||||
let block_level_box = ArcRefCell::new(
|
ArcRefCell::new(AbsolutelyPositionedBox::construct(
|
||||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
|
context,
|
||||||
AbsolutelyPositionedBox::construct(context, info, display_inside, contents),
|
info,
|
||||||
|
display_inside,
|
||||||
|
contents,
|
||||||
|
)),
|
||||||
)),
|
)),
|
||||||
);
|
|
||||||
(block_level_box, ContainsFloats::No)
|
|
||||||
},
|
|
||||||
BlockLevelCreator::OutOfFlowFloatBox {
|
BlockLevelCreator::OutOfFlowFloatBox {
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
} => {
|
} => ArcRefCell::new(BlockLevelBox::OutOfFlowFloatBox(FloatBox::construct(
|
||||||
let block_level_box = ArcRefCell::new(BlockLevelBox::OutOfFlowFloatBox(
|
context,
|
||||||
FloatBox::construct(context, info, display_inside, contents),
|
info,
|
||||||
));
|
display_inside,
|
||||||
(block_level_box, ContainsFloats::Yes)
|
contents,
|
||||||
},
|
))),
|
||||||
};
|
};
|
||||||
self.box_slot
|
self.box_slot
|
||||||
.set(LayoutBox::BlockLevel(block_level_box.clone()));
|
.set(LayoutBox::BlockLevel(block_level_box.clone()));
|
||||||
(block_level_box, contains_floats)
|
block_level_box
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -809,7 +788,7 @@ impl IntermediateBlockContainer {
|
||||||
self,
|
self,
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
info: &NodeAndStyleInfo<Node>,
|
info: &NodeAndStyleInfo<Node>,
|
||||||
) -> (BlockContainer, ContainsFloats)
|
) -> BlockContainer
|
||||||
where
|
where
|
||||||
Node: NodeExt<'dom>,
|
Node: NodeExt<'dom>,
|
||||||
{
|
{
|
||||||
|
@ -826,28 +805,8 @@ impl IntermediateBlockContainer {
|
||||||
is_list_item,
|
is_list_item,
|
||||||
),
|
),
|
||||||
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
IntermediateBlockContainer::InlineFormattingContext(ifc) => {
|
||||||
// If that inline formatting context contained any float, those
|
BlockContainer::InlineFormattingContext(ifc)
|
||||||
// were already taken into account during the first phase of
|
|
||||||
// box construction.
|
|
||||||
(
|
|
||||||
BlockContainer::InlineFormattingContext(ifc),
|
|
||||||
ContainsFloats::No,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
||||||
pub(crate) enum ContainsFloats {
|
|
||||||
No,
|
|
||||||
Yes,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl std::ops::BitOrAssign for ContainsFloats {
|
|
||||||
fn bitor_assign(&mut self, other: Self) {
|
|
||||||
if other == ContainsFloats::Yes {
|
|
||||||
*self = ContainsFloats::Yes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ pub(crate) struct InlineFormattingContext {
|
||||||
// Whether this IFC contains the 1st formatted line of an element
|
// Whether this IFC contains the 1st formatted line of an element
|
||||||
// https://www.w3.org/TR/css-pseudo-4/#first-formatted-line
|
// https://www.w3.org/TR/css-pseudo-4/#first-formatted-line
|
||||||
pub(super) has_first_formatted_line: bool,
|
pub(super) has_first_formatted_line: bool,
|
||||||
|
pub(super) contains_floats: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
@ -172,6 +173,7 @@ impl InlineFormattingContext {
|
||||||
inline_level_boxes: Default::default(),
|
inline_level_boxes: Default::default(),
|
||||||
text_decoration_line,
|
text_decoration_line,
|
||||||
has_first_formatted_line,
|
has_first_formatted_line,
|
||||||
|
contains_floats: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,17 @@ pub(crate) enum BlockContainer {
|
||||||
InlineFormattingContext(InlineFormattingContext),
|
InlineFormattingContext(InlineFormattingContext),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BlockContainer {
|
||||||
|
fn contains_floats(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
BlockContainer::BlockLevelBoxes(boxes) => boxes
|
||||||
|
.iter()
|
||||||
|
.any(|block_level_box| block_level_box.borrow().contains_floats()),
|
||||||
|
BlockContainer::InlineFormattingContext { .. } => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
pub(crate) enum BlockLevelBox {
|
pub(crate) enum BlockLevelBox {
|
||||||
SameFormattingContextBlock {
|
SameFormattingContextBlock {
|
||||||
|
@ -56,6 +67,7 @@ pub(crate) enum BlockLevelBox {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
style: Arc<ComputedValues>,
|
style: Arc<ComputedValues>,
|
||||||
contents: BlockContainer,
|
contents: BlockContainer,
|
||||||
|
contains_floats: bool,
|
||||||
},
|
},
|
||||||
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
|
OutOfFlowAbsolutelyPositionedBox(ArcRefCell<AbsolutelyPositionedBox>),
|
||||||
OutOfFlowFloatBox(FloatBox),
|
OutOfFlowFloatBox(FloatBox),
|
||||||
|
@ -63,6 +75,16 @@ pub(crate) enum BlockLevelBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockLevelBox {
|
impl BlockLevelBox {
|
||||||
|
fn contains_floats(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
BlockLevelBox::SameFormattingContextBlock {
|
||||||
|
contains_floats, ..
|
||||||
|
} => *contains_floats,
|
||||||
|
BlockLevelBox::OutOfFlowFloatBox { .. } => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn find_block_margin_collapsing_with_parent(
|
fn find_block_margin_collapsing_with_parent(
|
||||||
&self,
|
&self,
|
||||||
collected_margin: &mut CollapsedMargin,
|
collected_margin: &mut CollapsedMargin,
|
||||||
|
@ -496,6 +518,7 @@ impl BlockLevelBox {
|
||||||
base_fragment_info: tag,
|
base_fragment_info: tag,
|
||||||
style,
|
style,
|
||||||
contents,
|
contents,
|
||||||
|
..
|
||||||
} => Fragment::Box(positioning_context.layout_maybe_position_relative_fragment(
|
} => Fragment::Box(positioning_context.layout_maybe_position_relative_fragment(
|
||||||
layout_context,
|
layout_context,
|
||||||
containing_block,
|
containing_block,
|
||||||
|
|
|
@ -7,7 +7,6 @@ use crate::context::LayoutContext;
|
||||||
use crate::dom::{LayoutBox, NodeExt};
|
use crate::dom::{LayoutBox, NodeExt};
|
||||||
use crate::dom_traversal::{iter_child_nodes, Contents, NodeAndStyleInfo};
|
use crate::dom_traversal::{iter_child_nodes, Contents, NodeAndStyleInfo};
|
||||||
use crate::flexbox::FlexLevelBox;
|
use crate::flexbox::FlexLevelBox;
|
||||||
use crate::flow::construct::ContainsFloats;
|
|
||||||
use crate::flow::float::FloatBox;
|
use crate::flow::float::FloatBox;
|
||||||
use crate::flow::inline::InlineLevelBox;
|
use crate::flow::inline::InlineLevelBox;
|
||||||
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
use crate::flow::{BlockContainer, BlockFormattingContext, BlockLevelBox};
|
||||||
|
@ -45,15 +44,17 @@ impl BoxTree {
|
||||||
where
|
where
|
||||||
Node: 'dom + Copy + LayoutNode<'dom> + Send + Sync,
|
Node: 'dom + Copy + LayoutNode<'dom> + Send + Sync,
|
||||||
{
|
{
|
||||||
let (contains_floats, boxes) = construct_for_root_element(&context, root_element);
|
let boxes = construct_for_root_element(&context, root_element);
|
||||||
|
|
||||||
// Zero box for `:root { display: none }`, one for the root element otherwise.
|
// Zero box for `:root { display: none }`, one for the root element otherwise.
|
||||||
assert!(boxes.len() <= 1);
|
assert!(boxes.len() <= 1);
|
||||||
|
|
||||||
|
let contents = BlockContainer::BlockLevelBoxes(boxes);
|
||||||
|
let contains_floats = contents.contains_floats();
|
||||||
Self {
|
Self {
|
||||||
root: BlockFormattingContext {
|
root: BlockFormattingContext {
|
||||||
contains_floats: contains_floats == ContainsFloats::Yes,
|
contents,
|
||||||
contents: BlockContainer::BlockLevelBoxes(boxes),
|
contains_floats,
|
||||||
},
|
},
|
||||||
canvas_background: CanvasBackground::for_root_element(context, root_element),
|
canvas_background: CanvasBackground::for_root_element(context, root_element),
|
||||||
}
|
}
|
||||||
|
@ -209,14 +210,14 @@ impl BoxTree {
|
||||||
fn construct_for_root_element<'dom>(
|
fn construct_for_root_element<'dom>(
|
||||||
context: &LayoutContext,
|
context: &LayoutContext,
|
||||||
root_element: impl NodeExt<'dom>,
|
root_element: impl NodeExt<'dom>,
|
||||||
) -> (ContainsFloats, Vec<ArcRefCell<BlockLevelBox>>) {
|
) -> Vec<ArcRefCell<BlockLevelBox>> {
|
||||||
let info = NodeAndStyleInfo::new(root_element, root_element.style(context));
|
let info = NodeAndStyleInfo::new(root_element, root_element.style(context));
|
||||||
let box_style = info.style.get_box();
|
let box_style = info.style.get_box();
|
||||||
|
|
||||||
let display_inside = match Display::from(box_style.display) {
|
let display_inside = match Display::from(box_style.display) {
|
||||||
Display::None => {
|
Display::None => {
|
||||||
root_element.unset_all_boxes();
|
root_element.unset_all_boxes();
|
||||||
return (ContainsFloats::No, Vec::new());
|
return Vec::new();
|
||||||
},
|
},
|
||||||
Display::Contents => {
|
Display::Contents => {
|
||||||
// Unreachable because the style crate adjusts the computed values:
|
// Unreachable because the style crate adjusts the computed values:
|
||||||
|
@ -230,41 +231,32 @@ fn construct_for_root_element<'dom>(
|
||||||
|
|
||||||
let contents =
|
let contents =
|
||||||
ReplacedContent::for_element(root_element).map_or(Contents::OfElement, Contents::Replaced);
|
ReplacedContent::for_element(root_element).map_or(Contents::OfElement, Contents::Replaced);
|
||||||
let (contains_floats, root_box) = if box_style.position.is_absolutely_positioned() {
|
let root_box = if box_style.position.is_absolutely_positioned() {
|
||||||
(
|
|
||||||
ContainsFloats::No,
|
|
||||||
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
|
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
|
||||||
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
|
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
|
||||||
)),
|
))
|
||||||
)
|
|
||||||
} else if box_style.float.is_floating() {
|
} else if box_style.float.is_floating() {
|
||||||
(
|
|
||||||
ContainsFloats::Yes,
|
|
||||||
BlockLevelBox::OutOfFlowFloatBox(FloatBox::construct(
|
BlockLevelBox::OutOfFlowFloatBox(FloatBox::construct(
|
||||||
context,
|
context,
|
||||||
&info,
|
&info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
)),
|
))
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
let propagated_text_decoration_line = info.style.clone_text_decoration_line();
|
let propagated_text_decoration_line = info.style.clone_text_decoration_line();
|
||||||
(
|
|
||||||
ContainsFloats::No,
|
|
||||||
BlockLevelBox::Independent(IndependentFormattingContext::construct(
|
BlockLevelBox::Independent(IndependentFormattingContext::construct(
|
||||||
context,
|
context,
|
||||||
&info,
|
&info,
|
||||||
display_inside,
|
display_inside,
|
||||||
contents,
|
contents,
|
||||||
propagated_text_decoration_line,
|
propagated_text_decoration_line,
|
||||||
)),
|
))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
let root_box = ArcRefCell::new(root_box);
|
let root_box = ArcRefCell::new(root_box);
|
||||||
root_element
|
root_element
|
||||||
.element_box_slot()
|
.element_box_slot()
|
||||||
.set(LayoutBox::BlockLevel(root_box.clone()));
|
.set(LayoutBox::BlockLevel(root_box.clone()));
|
||||||
(contains_floats, vec![root_box])
|
vec![root_box]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoxTree {
|
impl BoxTree {
|
||||||
|
|
|
@ -14,8 +14,8 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2};
|
||||||
use crate::geom::{LengthOrAuto, LengthPercentageOrAuto};
|
use crate::geom::{LengthOrAuto, LengthPercentageOrAuto};
|
||||||
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
use crate::style_ext::{ComputedValuesExt, DisplayInside};
|
||||||
use crate::{ContainingBlock, DefiniteContainingBlock};
|
use crate::{ContainingBlock, DefiniteContainingBlock};
|
||||||
use rayon::iter::{IntoParallelRefMutIterator, ParallelExtend};
|
use rayon::iter::IntoParallelRefMutIterator;
|
||||||
use rayon_croissant::ParallelIteratorExt;
|
use rayon::prelude::{IndexedParallelIterator, ParallelIterator};
|
||||||
use style::computed_values::position::T as Position;
|
use style::computed_values::position::T as Position;
|
||||||
use style::properties::ComputedValues;
|
use style::properties::ComputedValues;
|
||||||
use style::values::computed::{CSSPixelLength, Length};
|
use style::values::computed::{CSSPixelLength, Length};
|
||||||
|
@ -354,21 +354,27 @@ impl HoistedAbsolutelyPositionedBox {
|
||||||
containing_block: &DefiniteContainingBlock,
|
containing_block: &DefiniteContainingBlock,
|
||||||
) {
|
) {
|
||||||
if layout_context.use_rayon {
|
if layout_context.use_rayon {
|
||||||
fragments.par_extend(boxes.par_iter_mut().mapfold_reduce_into(
|
let mut new_fragments = Vec::new();
|
||||||
for_nearest_containing_block_for_all_descendants,
|
let mut new_hoisted_boxes = Vec::new();
|
||||||
|for_nearest_containing_block_for_all_descendants, box_| {
|
|
||||||
let new_fragment = ArcRefCell::new(Fragment::Box(box_.layout(
|
boxes
|
||||||
|
.par_iter_mut()
|
||||||
|
.map(|hoisted_box| {
|
||||||
|
let mut new_hoisted_boxes: Vec<HoistedAbsolutelyPositionedBox> = Vec::new();
|
||||||
|
let new_fragment = ArcRefCell::new(Fragment::Box(hoisted_box.layout(
|
||||||
layout_context,
|
layout_context,
|
||||||
for_nearest_containing_block_for_all_descendants,
|
&mut new_hoisted_boxes,
|
||||||
containing_block,
|
containing_block,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
box_.fragment.borrow_mut().fragment = Some(new_fragment.clone());
|
hoisted_box.fragment.borrow_mut().fragment = Some(new_fragment.clone());
|
||||||
new_fragment
|
(new_fragment, new_hoisted_boxes)
|
||||||
},
|
})
|
||||||
Vec::new,
|
.unzip_into_vecs(&mut new_fragments, &mut new_hoisted_boxes);
|
||||||
vec_append_owned,
|
|
||||||
))
|
fragments.extend(new_fragments);
|
||||||
|
for_nearest_containing_block_for_all_descendants
|
||||||
|
.extend(new_hoisted_boxes.into_iter().flatten());
|
||||||
} else {
|
} else {
|
||||||
fragments.extend(boxes.iter_mut().map(|box_| {
|
fragments.extend(boxes.iter_mut().map(|box_| {
|
||||||
let new_fragment = ArcRefCell::new(Fragment::Box(box_.layout(
|
let new_fragment = ArcRefCell::new(Fragment::Box(box_.layout(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue