Bug 1885136 - Allow Servo to start the style traversal from outside the thread pool. r=firefox-style-system-reviewers,zrhoffman

This should be flexible enough. In the future Servo might want to make
more guarantees about what threads the style thread pool contains.

Differential Revision: https://phabricator.services.mozilla.com/D204506
This commit is contained in:
Emilio Cobos Álvarez 2024-03-14 10:19:59 +00:00
parent 3c9d46e8f2
commit 900ade994d
2 changed files with 36 additions and 29 deletions

View file

@ -207,6 +207,17 @@ pub trait TNode: Sized + Copy + Clone + Debug + NodeInfo + PartialEq {
}
}
/// Returns the depth of this node in the DOM.
fn depth(&self) -> usize {
let mut depth = 0;
let mut curr = *self;
while let Some(parent) = curr.traversal_parent() {
depth += 1;
curr = parent.as_node();
}
depth
}
/// Get this node's parent element from the perspective of a restyle
/// traversal.
fn traversal_parent(&self) -> Option<Self::ConcreteElement>;
@ -398,18 +409,6 @@ pub trait TElement:
true
}
/// Returns the depth of this element in the DOM.
fn depth(&self) -> usize {
let mut depth = 0;
let mut curr = *self;
while let Some(parent) = curr.traversal_parent() {
depth += 1;
curr = parent;
}
depth
}
/// Get this node's parent element from the perspective of a restyle
/// traversal.
fn traversal_parent(&self) -> Option<Self> {

View file

@ -46,16 +46,28 @@ fn report_statistics(stats: &PerThreadTraversalStatistics) {
gecko_stats.mStylesReused += stats.styles_reused;
}
fn with_pool_in_place_scope<'scope, R>(
fn with_pool_in_place_scope<'scope>(
work_unit_max: usize,
pool: Option<&rayon::ThreadPool>,
closure: impl FnOnce(Option<&rayon::ScopeFifo<'scope>>) -> R,
) -> R {
closure: impl FnOnce(Option<&rayon::ScopeFifo<'scope>>) + Send + 'scope,
) {
if work_unit_max == 0 || pool.is_none() {
closure(None)
closure(None);
} else {
pool.unwrap()
.in_place_scope_fifo(|scope| closure(Some(scope)))
let pool = pool.unwrap();
pool.in_place_scope_fifo(|scope| {
#[cfg(feature = "gecko")]
debug_assert_eq!(
pool.current_thread_index(),
Some(0),
"Main thread should be the first thread"
);
if cfg!(feature = "gecko") || pool.current_thread_index().is_some() {
closure(Some(scope));
} else {
scope.spawn_fifo(|scope| closure(Some(scope)));
}
});
}
}
@ -108,6 +120,8 @@ where
// Process the nodes breadth-first. This helps keep similar traversal characteristics for the
// style sharing cache.
let work_unit_max = work_unit_max();
let send_root = unsafe { SendNode::new(root.as_node()) };
with_pool_in_place_scope(work_unit_max, pool, |maybe_scope| {
let mut tlc = scoped_tls.ensure(parallel::create_thread_local_context);
let mut context = StyleContext {
@ -115,22 +129,16 @@ where
thread_local: &mut tlc,
};
debug_assert_eq!(
scoped_tls.current_thread_index(),
0,
"Main thread should be the first thread"
);
let mut discovered = VecDeque::with_capacity(work_unit_max * 2);
discovered.push_back(unsafe { SendNode::new(root.as_node()) });
let current_dom_depth = send_root.depth();
let opaque_root = send_root.opaque();
discovered.push_back(send_root);
parallel::style_trees(
&mut context,
discovered,
root.as_node().opaque(),
opaque_root,
work_unit_max,
PerLevelTraversalData {
current_dom_depth: root.depth(),
},
PerLevelTraversalData { current_dom_depth },
maybe_scope,
traversal,
&scoped_tls,