stylo: Allow bypassing the bottom-up traversal.

This commit is contained in:
Emilio Cobos Álvarez 2016-08-05 11:20:36 -07:00
parent 40df81d537
commit 436c1b3089
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
4 changed files with 37 additions and 15 deletions

View file

@ -86,7 +86,9 @@ fn top_down_dom<N, C>(unsafe_nodes: UnsafeNodeList,
}
}
// Reset the count of children.
// Reset the count of children if we need to do a bottom-up traversal
// after the top up.
if context.needs_postorder_traversal() {
{
let data = node.mutate_data().unwrap();
data.parallel.children_to_process
@ -94,12 +96,12 @@ fn top_down_dom<N, C>(unsafe_nodes: UnsafeNodeList,
Ordering::Relaxed);
}
// If there were no more children, start walking back up.
if children_to_process == 0 {
bottom_up_dom::<N, C>(unsafe_nodes.1, unsafe_node, proxy)
}
}
}
for chunk in discovered_child_nodes.chunks(CHUNK_SIZE) {
proxy.push(WorkUnit {
@ -123,7 +125,9 @@ fn top_down_dom<N, C>(unsafe_nodes: UnsafeNodeList,
fn bottom_up_dom<N, C>(root: OpaqueNode,
unsafe_node: UnsafeNode,
proxy: &mut WorkerProxy<C::SharedContext, UnsafeNodeList>)
where N: TNode, C: DomTraversalContext<N> {
where N: TNode,
C: DomTraversalContext<N>
{
let context = C::new(proxy.user_data(), root);
// Get a real layout node.

View file

@ -26,8 +26,10 @@ pub fn traverse_dom<N, C>(root: N,
}
}
if context.needs_postorder_traversal() {
context.process_postorder(node);
}
}
let context = C::new(shared, root.opaque());
if context.should_process(root) {

View file

@ -141,12 +141,23 @@ pub fn remove_from_bloom_filter<'a, N, C>(context: &C, root: OpaqueNode, node: N
pub trait DomTraversalContext<N: TNode> {
type SharedContext: Sync + 'static;
fn new<'a>(&'a Self::SharedContext, OpaqueNode) -> Self;
/// Process `node` on the way down, before its children have been processed.
fn process_preorder(&self, node: N);
fn process_preorder(&self, node: N) -> ForceTraversalStop;
/// Process `node` on the way up, after its children have been processed.
///
/// This is only executed if `needs_postorder_traversal` returns true.
fn process_postorder(&self, node: N);
/// Boolean that specifies whether a bottom up traversal should be
/// performed.
///
/// If it's false, then process_postorder has no effect at all.
fn needs_postorder_traversal(&self) -> bool { true }
/// Returns if the node should be processed by the preorder traversal (and
/// then by the post-order one).
///

View file

@ -35,5 +35,10 @@ impl<'lc, 'ln> DomTraversalContext<GeckoNode<'ln>> for RecalcStyleOnly<'lc> {
recalc_style_at(&self.context, self.root, node);
}
fn process_postorder(&self, _: GeckoNode<'ln>) {}
fn process_postorder(&self, _: GeckoNode<'ln>) {
unreachable!();
}
/// We don't use the post-order traversal for anything.
fn needs_postorder_traversal(&self) -> bool { false }
}