mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Make parallel DOM traversal and style calculation operate on TNode instead of LayoutNode.
This commit is contained in:
parent
238a8786de
commit
ebc5eb1b98
4 changed files with 30 additions and 12 deletions
|
@ -15,14 +15,13 @@ use gfx::display_list::OpaqueNode;
|
||||||
use profile_traits::time::{self, TimerMetadata, profile};
|
use profile_traits::time::{self, TimerMetadata, profile};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::atomic::{AtomicIsize, Ordering};
|
use std::sync::atomic::{AtomicIsize, Ordering};
|
||||||
use style::dom::UnsafeNode;
|
use style::dom::{TNode, UnsafeNode};
|
||||||
use traversal::PostorderNodeMutTraversal;
|
use traversal::PostorderNodeMutTraversal;
|
||||||
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes, BubbleISizes};
|
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes, BubbleISizes};
|
||||||
use traversal::{BuildDisplayList, ComputeAbsolutePositions};
|
use traversal::{BuildDisplayList, ComputeAbsolutePositions};
|
||||||
use traversal::{DomTraversal, DomTraversalContext};
|
use traversal::{DomTraversal, DomTraversalContext};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
|
use util::workqueue::{WorkQueue, WorkUnit, WorkerProxy};
|
||||||
use wrapper::LayoutNode;
|
|
||||||
|
|
||||||
const CHUNK_SIZE: usize = 64;
|
const CHUNK_SIZE: usize = 64;
|
||||||
|
|
||||||
|
@ -236,7 +235,7 @@ impl<'a> ParallelPostorderFlowTraversal for BuildDisplayList<'a> {}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn top_down_dom<'ln, N, T>(unsafe_nodes: UnsafeNodeList,
|
fn top_down_dom<'ln, N, T>(unsafe_nodes: UnsafeNodeList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeNodeList>)
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeNodeList>)
|
||||||
where N: LayoutNode<'ln>, T: DomTraversal<'ln, N> {
|
where N: TNode<'ln>, T: DomTraversal<'ln, N> {
|
||||||
let shared_layout_context = proxy.user_data();
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let traversal_context = DomTraversalContext {
|
let traversal_context = DomTraversalContext {
|
||||||
|
@ -294,7 +293,7 @@ fn top_down_dom<'ln, N, T>(unsafe_nodes: UnsafeNodeList,
|
||||||
fn bottom_up_dom<'ln, N, T>(root: OpaqueNode,
|
fn bottom_up_dom<'ln, N, T>(root: OpaqueNode,
|
||||||
unsafe_node: UnsafeNode,
|
unsafe_node: UnsafeNode,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeNodeList>)
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeNodeList>)
|
||||||
where N: LayoutNode<'ln>, T: DomTraversal<'ln, N> {
|
where N: TNode<'ln>, T: DomTraversal<'ln, N> {
|
||||||
let shared_layout_context = proxy.user_data();
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let traversal_context = DomTraversalContext {
|
let traversal_context = DomTraversalContext {
|
||||||
|
@ -388,7 +387,7 @@ pub fn traverse_dom_preorder<'ln, N, T>(
|
||||||
root: N,
|
root: N,
|
||||||
shared_layout_context: &SharedLayoutContext,
|
shared_layout_context: &SharedLayoutContext,
|
||||||
queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>)
|
queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>)
|
||||||
where N: LayoutNode<'ln>, T: DomTraversal<'ln, N> {
|
where N: TNode<'ln>, T: DomTraversal<'ln, N> {
|
||||||
run_queue_with_custom_work_data_type(queue, |queue| {
|
run_queue_with_custom_work_data_type(queue, |queue| {
|
||||||
queue.push(WorkUnit {
|
queue.push(WorkUnit {
|
||||||
fun: top_down_dom::<N, T>,
|
fun: top_down_dom::<N, T>,
|
||||||
|
|
|
@ -15,7 +15,7 @@ use selectors::bloom::BloomFilter;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use style::context::StyleContext;
|
use style::context::StyleContext;
|
||||||
use style::dom::{TRestyleDamage, UnsafeNode};
|
use style::dom::{TNode, TRestyleDamage, UnsafeNode};
|
||||||
use style::matching::{ApplicableDeclarations, ElementMatchMethods, MatchMethods, StyleSharingResult};
|
use style::matching::{ApplicableDeclarations, ElementMatchMethods, MatchMethods, StyleSharingResult};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::tid::tid;
|
use util::tid::tid;
|
||||||
|
@ -56,7 +56,7 @@ fn take_task_local_bloom_filter<'ln, N>(parent_node: Option<N>,
|
||||||
root: OpaqueNode,
|
root: OpaqueNode,
|
||||||
layout_context: &LayoutContext)
|
layout_context: &LayoutContext)
|
||||||
-> Box<BloomFilter>
|
-> Box<BloomFilter>
|
||||||
where N: LayoutNode<'ln> {
|
where N: TNode<'ln> {
|
||||||
STYLE_BLOOM.with(|style_bloom| {
|
STYLE_BLOOM.with(|style_bloom| {
|
||||||
match (parent_node, style_bloom.borrow_mut().take()) {
|
match (parent_node, style_bloom.borrow_mut().take()) {
|
||||||
// Root node. Needs new bloom filter.
|
// Root node. Needs new bloom filter.
|
||||||
|
@ -102,7 +102,7 @@ fn put_task_local_bloom_filter(bf: Box<BloomFilter>,
|
||||||
fn insert_ancestors_into_bloom_filter<'ln, N>(bf: &mut Box<BloomFilter>,
|
fn insert_ancestors_into_bloom_filter<'ln, N>(bf: &mut Box<BloomFilter>,
|
||||||
mut n: N,
|
mut n: N,
|
||||||
root: OpaqueNode)
|
root: OpaqueNode)
|
||||||
where N: LayoutNode<'ln> {
|
where N: TNode<'ln> {
|
||||||
debug!("[{}] Inserting ancestors.", tid());
|
debug!("[{}] Inserting ancestors.", tid());
|
||||||
let mut ancestors = 0;
|
let mut ancestors = 0;
|
||||||
loop {
|
loop {
|
||||||
|
@ -123,7 +123,7 @@ pub struct DomTraversalContext<'a> {
|
||||||
pub root: OpaqueNode,
|
pub root: OpaqueNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DomTraversal<'ln, N: LayoutNode<'ln>> {
|
pub trait DomTraversal<'ln, N: TNode<'ln>> {
|
||||||
fn process_preorder<'a>(context: &'a DomTraversalContext<'a>, node: N);
|
fn process_preorder<'a>(context: &'a DomTraversalContext<'a>, node: N);
|
||||||
fn process_postorder<'a>(context: &'a DomTraversalContext<'a>, node: N);
|
fn process_postorder<'a>(context: &'a DomTraversalContext<'a>, node: N);
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ pub trait DomTraversal<'ln, N: LayoutNode<'ln>> {
|
||||||
/// This is currently unused, but will be used shortly.
|
/// This is currently unused, but will be used shortly.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct RecalcStyleOnly;
|
pub struct RecalcStyleOnly;
|
||||||
impl<'ln, N: LayoutNode<'ln>> DomTraversal<'ln, N> for RecalcStyleOnly {
|
impl<'ln, N: TNode<'ln>> DomTraversal<'ln, N> for RecalcStyleOnly {
|
||||||
fn process_preorder<'a>(context: &'a DomTraversalContext<'a>, node: N) { recalc_style_at(context, node); }
|
fn process_preorder<'a>(context: &'a DomTraversalContext<'a>, node: N) { recalc_style_at(context, node); }
|
||||||
fn process_postorder<'a>(_: &'a DomTraversalContext<'a>, _: N) {}
|
fn process_postorder<'a>(_: &'a DomTraversalContext<'a>, _: N) {}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ pub trait PostorderNodeMutTraversal<'ln, ConcreteThreadSafeLayoutNode: ThreadSaf
|
||||||
/// layout computation. This computes the styles applied to each node.
|
/// layout computation. This computes the styles applied to each node.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn recalc_style_at<'a, 'ln, N: LayoutNode<'ln>> (context: &'a DomTraversalContext<'a>, node: N) {
|
fn recalc_style_at<'a, 'ln, N: TNode<'ln>> (context: &'a DomTraversalContext<'a>, node: N) {
|
||||||
// Initialize layout data.
|
// Initialize layout data.
|
||||||
//
|
//
|
||||||
// FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
|
// FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
|
||||||
|
@ -171,7 +171,6 @@ fn recalc_style_at<'a, 'ln, N: LayoutNode<'ln>> (context: &'a DomTraversalContex
|
||||||
// Remove existing CSS styles from nodes whose content has changed (e.g. text changed),
|
// Remove existing CSS styles from nodes whose content has changed (e.g. text changed),
|
||||||
// to force non-incremental reflow.
|
// to force non-incremental reflow.
|
||||||
if node.has_changed() {
|
if node.has_changed() {
|
||||||
let node = node.to_threadsafe();
|
|
||||||
node.unstyle();
|
node.unstyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,14 @@ impl<'ln> TNode<'ln> for ServoLayoutNode<'ln> {
|
||||||
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn style(&self) -> Ref<Arc<ComputedValues>> {
|
||||||
|
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unstyle(self) {
|
||||||
|
self.mutate_data().unwrap().style = None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
|
impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
|
||||||
|
@ -696,6 +704,8 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
|
||||||
|
|
||||||
/// Returns the style results for the given node. If CSS selector matching
|
/// Returns the style results for the given node. If CSS selector matching
|
||||||
/// has not yet been performed, fails.
|
/// has not yet been performed, fails.
|
||||||
|
///
|
||||||
|
/// Unlike the version on TNode, this handles pseudo-elements.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn style(&self) -> Ref<Arc<ComputedValues>> {
|
fn style(&self) -> Ref<Arc<ComputedValues>> {
|
||||||
Ref::map(self.borrow_layout_data().unwrap(), |data| {
|
Ref::map(self.borrow_layout_data().unwrap(), |data| {
|
||||||
|
@ -709,6 +719,8 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the style from this node.
|
/// Removes the style from this node.
|
||||||
|
///
|
||||||
|
/// Unlike the version on TNode, this handles pseudo-elements.
|
||||||
fn unstyle(self) {
|
fn unstyle(self) {
|
||||||
let mut data = self.mutate_layout_data().unwrap();
|
let mut data = self.mutate_layout_data().unwrap();
|
||||||
let style =
|
let style =
|
||||||
|
|
|
@ -156,6 +156,14 @@ pub trait TNode<'ln> : Sized + Copy + Clone {
|
||||||
fn prev_sibling(&self) -> Option<Self>;
|
fn prev_sibling(&self) -> Option<Self>;
|
||||||
|
|
||||||
fn next_sibling(&self) -> Option<Self>;
|
fn next_sibling(&self) -> Option<Self>;
|
||||||
|
|
||||||
|
|
||||||
|
/// Returns the style results for the given node. If CSS selector matching
|
||||||
|
/// has not yet been performed, fails.
|
||||||
|
fn style(&self) -> Ref<Arc<ComputedValues>>;
|
||||||
|
|
||||||
|
/// Removes the style from this node.
|
||||||
|
fn unstyle(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TDocument<'ld> : Sized + Copy + Clone {
|
pub trait TDocument<'ld> : Sized + Copy + Clone {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue