mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Bug 1325734 - Pass the thread-local context into should_traverse_children. r=emilio
This commit is contained in:
parent
3060865577
commit
92b9d70c3a
4 changed files with 32 additions and 10 deletions
|
@ -16,6 +16,7 @@ use net_traits::image_cache_thread::{ImageOrMetadataAvailable, UsePlaceholder};
|
|||
use parking_lot::RwLock;
|
||||
use servo_config::opts;
|
||||
use servo_url::ServoUrl;
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
@ -37,6 +38,18 @@ impl<E: TElement> ScopedThreadLocalLayoutContext<E> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<E: TElement> Borrow<ThreadLocalStyleContext<E>> for ScopedThreadLocalLayoutContext<E> {
|
||||
fn borrow(&self) -> &ThreadLocalStyleContext<E> {
|
||||
&self.style_context
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: TElement> BorrowMut<ThreadLocalStyleContext<E>> for ScopedThreadLocalLayoutContext<E> {
|
||||
fn borrow_mut(&mut self) -> &mut ThreadLocalStyleContext<E> {
|
||||
&mut self.style_context
|
||||
}
|
||||
}
|
||||
|
||||
/// TLS data that persists across traversals.
|
||||
pub struct PersistentThreadLocalLayoutContext {
|
||||
// FontContext uses Rc all over the place and so isn't Send, which means we
|
||||
|
|
|
@ -112,7 +112,7 @@ fn top_down_dom<'a, 'scope, E, D>(nodes: &'a [SendNode<E::ConcreteNode>],
|
|||
let mut children_to_process = 0isize;
|
||||
traversal.process_preorder(&mut traversal_data, &mut *tlc, node);
|
||||
if let Some(el) = node.as_element() {
|
||||
D::traverse_children(el, |kid| {
|
||||
traversal.traverse_children(&mut *tlc, el, |_tlc, kid| {
|
||||
children_to_process += 1;
|
||||
discovered_child_nodes.push(unsafe { SendNode::new(kid) })
|
||||
});
|
||||
|
|
|
@ -29,7 +29,9 @@ pub fn traverse_dom<E, D>(traversal: &D,
|
|||
*depth += 1;
|
||||
}
|
||||
|
||||
D::traverse_children(el, |kid| doit(traversal, traversal_data, thread_local, kid));
|
||||
traversal.traverse_children(thread_local, el, |tlc, kid| {
|
||||
doit(traversal, traversal_data, tlc, kid)
|
||||
});
|
||||
|
||||
if let Some(ref mut depth) = traversal_data.current_dom_depth {
|
||||
*depth -= 1;
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
#![deny(missing_docs)]
|
||||
|
||||
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
||||
use context::{SharedStyleContext, StyleContext};
|
||||
use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
|
||||
use data::{ElementData, ElementStyles, StoredRestyleHint};
|
||||
use dom::{NodeInfo, TElement, TNode};
|
||||
use matching::{MatchMethods, StyleSharingResult};
|
||||
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
|
||||
use selector_parser::RestyleDamage;
|
||||
use servo_config::opts;
|
||||
use std::borrow::BorrowMut;
|
||||
use std::mem;
|
||||
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||
use stylist::Stylist;
|
||||
|
@ -75,7 +76,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
/// The thread-local context, used to store non-thread-safe stuff that needs
|
||||
/// to be used in the traversal, and of which we use one per worker, like
|
||||
/// the bloom filter, for example.
|
||||
type ThreadLocalContext: Send;
|
||||
type ThreadLocalContext: Send + BorrowMut<ThreadLocalStyleContext<E>>;
|
||||
|
||||
/// Process `node` on the way down, before its children have been processed.
|
||||
fn process_preorder(&self, data: &mut PerLevelTraversalData,
|
||||
|
@ -193,7 +194,11 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
///
|
||||
/// This may be called multiple times when processing an element, so we pass
|
||||
/// a parameter to keep the logs tidy.
|
||||
fn should_traverse_children(parent: E, parent_data: &ElementData, log: LogBehavior) -> bool
|
||||
fn should_traverse_children(&self,
|
||||
_thread_local: &mut ThreadLocalStyleContext<E>,
|
||||
parent: E,
|
||||
parent_data: &ElementData,
|
||||
log: LogBehavior) -> bool
|
||||
{
|
||||
// See the comment on `cascade_node` for why we allow this on Gecko.
|
||||
debug_assert!(cfg!(feature = "gecko") || parent_data.has_current_styles());
|
||||
|
@ -237,10 +242,12 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
|
||||
/// Helper for the traversal implementations to select the children that
|
||||
/// should be enqueued for processing.
|
||||
fn traverse_children<F: FnMut(E::ConcreteNode)>(parent: E, mut f: F)
|
||||
fn traverse_children<F>(&self, thread_local: &mut Self::ThreadLocalContext, parent: E, mut f: F)
|
||||
where F: FnMut(&mut Self::ThreadLocalContext, E::ConcreteNode)
|
||||
{
|
||||
// Check if we're allowed to traverse past this element.
|
||||
if !Self::should_traverse_children(parent, &parent.borrow_data().unwrap(), MayLog) {
|
||||
if !self.should_traverse_children(thread_local.borrow_mut(), parent,
|
||||
&parent.borrow_data().unwrap(), MayLog) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -252,7 +259,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
{
|
||||
unsafe { parent.set_dirty_descendants(); }
|
||||
}
|
||||
f(kid);
|
||||
f(thread_local, kid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -274,7 +281,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
|||
/// Return the shared style context common to all worker threads.
|
||||
fn shared_context(&self) -> &SharedStyleContext;
|
||||
|
||||
/// Create a thread-local context.
|
||||
/// Creates a thread-local context.
|
||||
fn create_thread_local_context(&self) -> Self::ThreadLocalContext;
|
||||
}
|
||||
|
||||
|
@ -397,7 +404,7 @@ pub fn recalc_style_at<E, D>(traversal: &D,
|
|||
trace!("propagated_hint={:?}, inherited_style_changed={:?}", propagated_hint, inherited_style_changed);
|
||||
|
||||
// Preprocess children, propagating restyle hints and handling sibling relationships.
|
||||
if D::should_traverse_children(element, &data, DontLog) &&
|
||||
if traversal.should_traverse_children(&mut context.thread_local, element, &data, DontLog) &&
|
||||
(element.has_dirty_descendants() || !propagated_hint.is_empty() || inherited_style_changed) {
|
||||
preprocess_children(traversal, element, propagated_hint, inherited_style_changed);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue