From 436c1b308930e1c98b311df2fa107757de38026f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Fri, 5 Aug 2016 11:20:36 -0700 Subject: [PATCH] stylo: Allow bypassing the bottom-up traversal. --- components/style/parallel.rs | 28 ++++++++++++++++------------ components/style/sequential.rs | 4 +++- components/style/traversal.rs | 13 ++++++++++++- ports/geckolib/traversal.rs | 7 ++++++- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/components/style/parallel.rs b/components/style/parallel.rs index b82727657c3..8f9927d4992 100644 --- a/components/style/parallel.rs +++ b/components/style/parallel.rs @@ -86,18 +86,20 @@ fn top_down_dom(unsafe_nodes: UnsafeNodeList, } } - // Reset the count of children. - { - let data = node.mutate_data().unwrap(); - data.parallel.children_to_process - .store(children_to_process, - Ordering::Relaxed); - } + // 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 + .store(children_to_process, + Ordering::Relaxed); + } - - // If there were no more children, start walking back up. - if children_to_process == 0 { - bottom_up_dom::(unsafe_nodes.1, unsafe_node, proxy) + // If there were no more children, start walking back up. + if children_to_process == 0 { + bottom_up_dom::(unsafe_nodes.1, unsafe_node, proxy) + } } } @@ -123,7 +125,9 @@ fn top_down_dom(unsafe_nodes: UnsafeNodeList, fn bottom_up_dom(root: OpaqueNode, unsafe_node: UnsafeNode, proxy: &mut WorkerProxy) - where N: TNode, C: DomTraversalContext { + where N: TNode, + C: DomTraversalContext +{ let context = C::new(proxy.user_data(), root); // Get a real layout node. diff --git a/components/style/sequential.rs b/components/style/sequential.rs index 2ae7a18048b..ac431b80057 100644 --- a/components/style/sequential.rs +++ b/components/style/sequential.rs @@ -26,7 +26,9 @@ pub fn traverse_dom(root: N, } } - context.process_postorder(node); + if context.needs_postorder_traversal() { + context.process_postorder(node); + } } let context = C::new(shared, root.opaque()); diff --git a/components/style/traversal.rs b/components/style/traversal.rs index ded29719397..d154145bcd4 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -141,12 +141,23 @@ pub fn remove_from_bloom_filter<'a, N, C>(context: &C, root: OpaqueNode, node: N pub trait DomTraversalContext { 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). /// diff --git a/ports/geckolib/traversal.rs b/ports/geckolib/traversal.rs index 87b63e83e15..55fa99b6c69 100644 --- a/ports/geckolib/traversal.rs +++ b/ports/geckolib/traversal.rs @@ -35,5 +35,10 @@ impl<'lc, 'ln> DomTraversalContext> 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 } }