aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout/parallel.rs
diff options
context:
space:
mode:
authorClark Gaebel <cgaebel@mozilla.com>2014-10-13 00:07:03 -0400
committerClark Gaebel <cgaebel@mozilla.com>2014-10-14 16:28:29 -0700
commit7368d42225b94f3ac821058800350d7c541f1a3f (patch)
treee06ddd10a36d9946ea0aeb1396f9358e7a881beb /components/layout/parallel.rs
parent56989b8dec4aa95a3b484d45f15b23f9b3daaf13 (diff)
downloadservo-7368d42225b94f3ac821058800350d7c541f1a3f.tar.gz
servo-7368d42225b94f3ac821058800350d7c541f1a3f.zip
Removes duplicate CSS selector matching logic.
Now that DOM/Flow traversals have been refactored out, the `recalc_style_for_subtree` function in `css/matching.rs` can be removed, in lieu of just running the standard `recalc_style_for_node` and `construct_flows` traversals sequentially. Now we no longer have the maintenance headache of duplicating selector matching logic in two places! \o/ r? @pcwalton
Diffstat (limited to 'components/layout/parallel.rs')
-rw-r--r--components/layout/parallel.rs129
1 files changed, 49 insertions, 80 deletions
diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs
index fbb95ac8123..d55420d2f7e 100644
--- a/components/layout/parallel.rs
+++ b/components/layout/parallel.rs
@@ -11,7 +11,8 @@ use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal
use flow;
use flow_ref::FlowRef;
use traversal::{RecalcStyleForNode, ConstructFlows};
-use traversal::{AssignBSizesAndStoreOverflow, AssignISizes, BubbleISizes};
+use traversal::{BubbleISizes, AssignISizes, AssignBSizesAndStoreOverflow};
+use traversal::{ComputeAbsolutePositions, BuildDisplayList};
use url::Url;
use util::{LayoutDataAccess, LayoutDataWrapper};
use wrapper::{layout_node_to_unsafe_layout_node, layout_node_from_unsafe_layout_node, LayoutNode};
@@ -79,12 +80,12 @@ impl DomParallelInfo {
/// A parallel top-down DOM traversal.
pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
- fn run_parallel(&mut self,
+ fn run_parallel(&self,
node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>);
#[inline(always)]
- fn run_parallel_helper(&mut self,
+ fn run_parallel_helper(&self,
unsafe_node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>,
top_down_func: extern "Rust" fn(UnsafeFlow,
@@ -139,7 +140,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal {
///
/// The only communication between siblings is that they both
/// fetch-and-subtract the parent's children count.
- fn run_parallel(&mut self,
+ fn run_parallel(&self,
mut unsafe_node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeLayoutNode>) {
loop {
@@ -214,7 +215,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
///
/// The only communication between siblings is that they both
/// fetch-and-subtract the parent's children count.
- fn run_parallel(&mut self,
+ fn run_parallel(&self,
mut unsafe_flow: UnsafeFlow,
_: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
loop {
@@ -259,12 +260,12 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
/// A parallel top-down flow traversal.
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
- fn run_parallel(&mut self,
+ fn run_parallel(&self,
unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>);
#[inline(always)]
- fn run_parallel_helper(&mut self,
+ fn run_parallel_helper(&self,
unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>,
top_down_func: extern "Rust" fn(UnsafeFlow,
@@ -304,7 +305,7 @@ trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
impl<'a> ParallelPostorderFlowTraversal for BubbleISizes<'a> {}
impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
- fn run_parallel(&mut self,
+ fn run_parallel(&self,
unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
self.run_parallel_helper(unsafe_flow,
@@ -316,10 +317,23 @@ impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {}
+impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> {
+ fn run_parallel(&self,
+ unsafe_flow: UnsafeFlow,
+ proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
+ self.run_parallel_helper(unsafe_flow,
+ proxy,
+ compute_absolute_positions,
+ build_display_list)
+ }
+}
+
+impl<'a> ParallelPostorderFlowTraversal for BuildDisplayList<'a> {}
+
impl<'a> ParallelPostorderDomTraversal for ConstructFlows<'a> {}
impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> {
- fn run_parallel(&mut self,
+ fn run_parallel(&self,
unsafe_node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
self.run_parallel_helper(unsafe_node,
@@ -333,7 +347,7 @@ fn recalc_style(unsafe_node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
let shared_layout_context = unsafe { &**proxy.user_data() };
let layout_context = LayoutContext::new(shared_layout_context);
- let mut recalc_style_for_node_traversal = RecalcStyleForNode {
+ let recalc_style_for_node_traversal = RecalcStyleForNode {
layout_context: &layout_context,
};
recalc_style_for_node_traversal.run_parallel(unsafe_node, proxy)
@@ -343,7 +357,7 @@ fn construct_flows(unsafe_node: UnsafeLayoutNode,
proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeLayoutNode>) {
let shared_layout_context = unsafe { &**proxy.user_data() };
let layout_context = LayoutContext::new(shared_layout_context);
- let mut construct_flows_traversal = ConstructFlows {
+ let construct_flows_traversal = ConstructFlows {
layout_context: &layout_context,
};
construct_flows_traversal.run_parallel(unsafe_node, proxy)
@@ -353,91 +367,40 @@ fn assign_inline_sizes(unsafe_flow: UnsafeFlow,
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
let shared_layout_context = unsafe { &**proxy.user_data() };
let layout_context = LayoutContext::new(shared_layout_context);
- let mut assign_inline_sizes_traversal = AssignISizes {
+ let assign_inline_sizes_traversal = AssignISizes {
layout_context: &layout_context,
};
assign_inline_sizes_traversal.run_parallel(unsafe_flow, proxy)
}
fn assign_block_sizes_and_store_overflow(unsafe_flow: UnsafeFlow,
- proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
+ proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
let shared_layout_context = unsafe { &**proxy.user_data() };
let layout_context = LayoutContext::new(shared_layout_context);
- let mut assign_block_sizes_traversal = AssignBSizesAndStoreOverflow {
+ let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow {
layout_context: &layout_context,
};
assign_block_sizes_traversal.run_parallel(unsafe_flow, proxy)
}
-fn compute_absolute_position(unsafe_flow: UnsafeFlow,
- proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
- let mut had_descendants = false;
- unsafe {
- // Get a real flow.
- let flow: &mut FlowRef = mem::transmute(&unsafe_flow);
-
- // Compute the absolute position for the flow.
- flow.get_mut().compute_absolute_position();
-
- // Enqueue all children.
- for kid in flow::child_iter(flow.get_mut()) {
- had_descendants = true;
- proxy.push(WorkUnit {
- fun: compute_absolute_position,
- data: borrowed_flow_to_unsafe_flow(kid),
- });
- }
-
- // If there were no more descendants, start building the display list.
- if !had_descendants {
- build_display_list(mut_owned_flow_to_unsafe_flow(flow), proxy)
- }
- }
+fn compute_absolute_positions(unsafe_flow: UnsafeFlow,
+ proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
+ let shared_layout_context = unsafe { &**proxy.user_data() };
+ let layout_context = LayoutContext::new(shared_layout_context);
+ let compute_absolute_positions_traversal = ComputeAbsolutePositions {
+ layout_context: &layout_context,
+ };
+ compute_absolute_positions_traversal.run_parallel(unsafe_flow, proxy);
}
-fn build_display_list(mut unsafe_flow: UnsafeFlow,
- proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
+fn build_display_list(unsafe_flow: UnsafeFlow,
+ proxy: &mut WorkerProxy<*const SharedLayoutContext, UnsafeFlow>) {
let shared_layout_context = unsafe { &**proxy.user_data() };
let layout_context = LayoutContext::new(shared_layout_context);
-
- loop {
- unsafe {
- // Get a real flow.
- let flow: &mut FlowRef = mem::transmute(&unsafe_flow);
-
- // Build display lists.
- flow.get_mut().build_display_list(&layout_context);
-
- {
- let base = flow::mut_base(flow.get_mut());
-
- // Reset the count of children for the next layout traversal.
- base.parallel.children_count.store(base.children.len() as int, Relaxed);
- }
-
- // Possibly enqueue the parent.
- let unsafe_parent = flow::mut_base(flow.get_mut()).parallel.parent;
- if unsafe_parent == null_unsafe_flow() {
- // We're done!
- break
- }
-
- // No, we're not at the root yet. Then are we the last child
- // of our parent to finish processing? If so, we can continue
- // on with our parent; otherwise, we've gotta wait.
- let parent: &mut FlowRef = mem::transmute(&unsafe_parent);
- let parent_base = flow::mut_base(parent.get_mut());
- if parent_base.parallel
- .children_count
- .fetch_sub(1, SeqCst) == 1 {
- // We were the last child of our parent. Build display lists for our parent.
- unsafe_flow = unsafe_parent
- } else {
- // Stop.
- break
- }
- }
- }
+ let build_display_list_traversal = BuildDisplayList {
+ layout_context: &layout_context,
+ };
+ build_display_list_traversal.run_parallel(unsafe_flow, proxy);
}
pub fn traverse_dom_preorder(root: LayoutNode,
@@ -462,6 +425,12 @@ pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
time_profiler_chan: TimeProfilerChan,
shared_layout_context: &SharedLayoutContext,
queue: &mut WorkQueue<*const SharedLayoutContext,UnsafeFlow>) {
+ if shared_layout_context.opts.bubble_inline_sizes_separately {
+ let layout_context = LayoutContext::new(shared_layout_context);
+ let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
+ root.get_mut().traverse_postorder(&bubble_inline_sizes);
+ }
+
queue.data = shared_layout_context as *const _;
profile(time::LayoutParallelWarmupCategory, Some((url, iframe, first_reflow)), time_profiler_chan, || {
@@ -487,7 +456,7 @@ pub fn build_display_list_for_subtree(root: &mut FlowRef,
profile(time::LayoutParallelWarmupCategory, Some((url, iframe, first_reflow)), time_profiler_chan, || {
queue.push(WorkUnit {
- fun: compute_absolute_position,
+ fun: compute_absolute_positions,
data: mut_owned_flow_to_unsafe_flow(root),
})
});