mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
layout: Stop using Rayon in single-threaded mode (#37832)
In layout, some parts of the code were still using parallel iterators from Rayon even when single-thread layout was activated. This change modifies those parts to use non-parallel iterators when `LayoutContext::use_rayon` is not active. Testing: It's very hard to make an automated test for this, but I've manually verified this by building with tracing and observing that layout runs only on a single thread now when loading https://servo.org. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
da364f7a61
commit
647122d0f6
3 changed files with 197 additions and 144 deletions
|
@ -44,6 +44,90 @@ enum ModernContainerJob<'dom> {
|
|||
TextRuns(Vec<ModernContainerTextRun<'dom>>),
|
||||
}
|
||||
|
||||
impl<'dom> ModernContainerJob<'dom> {
|
||||
fn finish(
|
||||
self,
|
||||
builder: &ModernContainerBuilder,
|
||||
anonymous_info: &LazyLock<NodeAndStyleInfo<'dom>, impl FnOnce() -> NodeAndStyleInfo<'dom>>,
|
||||
) -> Option<ModernItem<'dom>> {
|
||||
match self {
|
||||
ModernContainerJob::TextRuns(runs) => {
|
||||
let mut inline_formatting_context_builder =
|
||||
InlineFormattingContextBuilder::new(builder.info);
|
||||
for flex_text_run in runs.into_iter() {
|
||||
inline_formatting_context_builder
|
||||
.push_text(flex_text_run.text, &flex_text_run.info);
|
||||
}
|
||||
|
||||
let inline_formatting_context = inline_formatting_context_builder.finish(
|
||||
builder.context,
|
||||
true, /* has_first_formatted_line */
|
||||
false, /* is_single_line_text_box */
|
||||
builder.info.style.to_bidi_level(),
|
||||
)?;
|
||||
|
||||
let block_formatting_context = BlockFormattingContext::from_block_container(
|
||||
BlockContainer::InlineFormattingContext(inline_formatting_context),
|
||||
);
|
||||
let info: &NodeAndStyleInfo = anonymous_info;
|
||||
let formatting_context = IndependentFormattingContext {
|
||||
base: LayoutBoxBase::new(info.into(), info.style.clone()),
|
||||
contents: IndependentFormattingContextContents::NonReplaced(
|
||||
IndependentNonReplacedContents::Flow(block_formatting_context),
|
||||
),
|
||||
};
|
||||
|
||||
Some(ModernItem {
|
||||
kind: ModernItemKind::InFlow,
|
||||
order: 0,
|
||||
box_slot: None,
|
||||
formatting_context,
|
||||
})
|
||||
},
|
||||
ModernContainerJob::ElementOrPseudoElement {
|
||||
info,
|
||||
display,
|
||||
contents,
|
||||
box_slot,
|
||||
} => {
|
||||
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
||||
|
||||
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
||||
// absolutes don't affect the size of ancestors so it is fine to allow descendent
|
||||
// tables to resolve percentage columns.
|
||||
let propagated_data = match is_abspos {
|
||||
false => builder.propagated_data,
|
||||
true => PropagatedBoxTreeData::default(),
|
||||
};
|
||||
|
||||
let formatting_context = IndependentFormattingContext::construct(
|
||||
builder.context,
|
||||
&info,
|
||||
display.display_inside(),
|
||||
contents,
|
||||
propagated_data,
|
||||
);
|
||||
|
||||
if is_abspos {
|
||||
Some(ModernItem {
|
||||
kind: ModernItemKind::OutOfFlow,
|
||||
order: 0,
|
||||
box_slot: Some(box_slot),
|
||||
formatting_context,
|
||||
})
|
||||
} else {
|
||||
Some(ModernItem {
|
||||
kind: ModernItemKind::InFlow,
|
||||
order: info.style.clone_order(),
|
||||
box_slot: Some(box_slot),
|
||||
formatting_context,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ModernContainerTextRun<'dom> {
|
||||
info: NodeAndStyleInfo<'dom>,
|
||||
text: Cow<'dom, str>,
|
||||
|
@ -137,84 +221,17 @@ impl<'a, 'dom> ModernContainerBuilder<'a, 'dom> {
|
|||
.pseudo(self.context, PseudoElement::ServoAnonymousBox)
|
||||
.expect("Should always be able to construct info for anonymous boxes.")
|
||||
});
|
||||
let mut children: Vec<ModernItem> = std::mem::take(&mut self.jobs)
|
||||
.into_par_iter()
|
||||
.filter_map(|job| match job {
|
||||
ModernContainerJob::TextRuns(runs) => {
|
||||
let mut inline_formatting_context_builder =
|
||||
InlineFormattingContextBuilder::new(self.info);
|
||||
for flex_text_run in runs.into_iter() {
|
||||
inline_formatting_context_builder
|
||||
.push_text(flex_text_run.text, &flex_text_run.info);
|
||||
}
|
||||
|
||||
let inline_formatting_context = inline_formatting_context_builder.finish(
|
||||
self.context,
|
||||
true, /* has_first_formatted_line */
|
||||
false, /* is_single_line_text_box */
|
||||
self.info.style.to_bidi_level(),
|
||||
)?;
|
||||
|
||||
let block_formatting_context = BlockFormattingContext::from_block_container(
|
||||
BlockContainer::InlineFormattingContext(inline_formatting_context),
|
||||
);
|
||||
let info: &NodeAndStyleInfo = &anonymous_info;
|
||||
let formatting_context = IndependentFormattingContext {
|
||||
base: LayoutBoxBase::new(info.into(), info.style.clone()),
|
||||
contents: IndependentFormattingContextContents::NonReplaced(
|
||||
IndependentNonReplacedContents::Flow(block_formatting_context),
|
||||
),
|
||||
};
|
||||
|
||||
Some(ModernItem {
|
||||
kind: ModernItemKind::InFlow,
|
||||
order: 0,
|
||||
box_slot: None,
|
||||
formatting_context,
|
||||
})
|
||||
},
|
||||
ModernContainerJob::ElementOrPseudoElement {
|
||||
info,
|
||||
display,
|
||||
contents,
|
||||
box_slot,
|
||||
} => {
|
||||
let is_abspos = info.style.get_box().position.is_absolutely_positioned();
|
||||
|
||||
// Text decorations are not propagated to any out-of-flow descendants. In addition,
|
||||
// absolutes don't affect the size of ancestors so it is fine to allow descendent
|
||||
// tables to resolve percentage columns.
|
||||
let propagated_data = match is_abspos {
|
||||
false => self.propagated_data,
|
||||
true => PropagatedBoxTreeData::default(),
|
||||
};
|
||||
|
||||
let formatting_context = IndependentFormattingContext::construct(
|
||||
self.context,
|
||||
&info,
|
||||
display.display_inside(),
|
||||
contents,
|
||||
propagated_data,
|
||||
);
|
||||
|
||||
if is_abspos {
|
||||
Some(ModernItem {
|
||||
kind: ModernItemKind::OutOfFlow,
|
||||
order: 0,
|
||||
box_slot: Some(box_slot),
|
||||
formatting_context,
|
||||
})
|
||||
} else {
|
||||
Some(ModernItem {
|
||||
kind: ModernItemKind::InFlow,
|
||||
order: info.style.clone_order(),
|
||||
box_slot: Some(box_slot),
|
||||
formatting_context,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let jobs = std::mem::take(&mut self.jobs);
|
||||
let mut children: Vec<_> = if self.context.use_rayon {
|
||||
jobs.into_par_iter()
|
||||
.filter_map(|job| job.finish(&self, &anonymous_info))
|
||||
.collect()
|
||||
} else {
|
||||
jobs.into_iter()
|
||||
.filter_map(|job| job.finish(&self, &anonymous_info))
|
||||
.collect()
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/css-flexbox/#order-modified-document-order
|
||||
children.sort_by_key(|child| child.order);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue