mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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
This commit is contained in:
parent
56989b8dec
commit
7368d42225
8 changed files with 201 additions and 312 deletions
|
@ -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 build_display_list(mut unsafe_flow: UnsafeFlow,
|
||||
proxy: &mut WorkerProxy<*const SharedLayoutContext,UnsafeFlow>) {
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
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),
|
||||
})
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue