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 /// Get this node's parent element from the perspective of a restyle
/// traversal. /// traversal.
fn traversal_parent(&self) -> Option<Self::ConcreteElement>; fn traversal_parent(&self) -> Option<Self::ConcreteElement>;
@ -398,18 +409,6 @@ pub trait TElement:
true 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 /// Get this node's parent element from the perspective of a restyle
/// traversal. /// traversal.
fn traversal_parent(&self) -> Option<Self> { fn traversal_parent(&self) -> Option<Self> {

View file

@ -46,16 +46,28 @@ fn report_statistics(stats: &PerThreadTraversalStatistics) {
gecko_stats.mStylesReused += stats.styles_reused; 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, work_unit_max: usize,
pool: Option<&rayon::ThreadPool>, pool: Option<&rayon::ThreadPool>,
closure: impl FnOnce(Option<&rayon::ScopeFifo<'scope>>) -> R, closure: impl FnOnce(Option<&rayon::ScopeFifo<'scope>>) + Send + 'scope,
) -> R { ) {
if work_unit_max == 0 || pool.is_none() { if work_unit_max == 0 || pool.is_none() {
closure(None) closure(None);
} else { } else {
pool.unwrap() let pool = pool.unwrap();
.in_place_scope_fifo(|scope| closure(Some(scope))) 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 // Process the nodes breadth-first. This helps keep similar traversal characteristics for the
// style sharing cache. // style sharing cache.
let work_unit_max = work_unit_max(); 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| { with_pool_in_place_scope(work_unit_max, pool, |maybe_scope| {
let mut tlc = scoped_tls.ensure(parallel::create_thread_local_context); let mut tlc = scoped_tls.ensure(parallel::create_thread_local_context);
let mut context = StyleContext { let mut context = StyleContext {
@ -115,22 +129,16 @@ where
thread_local: &mut tlc, 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); 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( parallel::style_trees(
&mut context, &mut context,
discovered, discovered,
root.as_node().opaque(), opaque_root,
work_unit_max, work_unit_max,
PerLevelTraversalData { PerLevelTraversalData { current_dom_depth },
current_dom_depth: root.depth(),
},
maybe_scope, maybe_scope,
traversal, traversal,
&scoped_tls, &scoped_tls,