forked from mirrors/gecko-dev
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:
parent
3c9d46e8f2
commit
900ade994d
2 changed files with 36 additions and 29 deletions
|
|
@ -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> {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue