mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +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 parking_lot::RwLock;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
|
use std::borrow::{Borrow, BorrowMut};
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::hash::BuildHasherDefault;
|
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.
|
/// TLS data that persists across traversals.
|
||||||
pub struct PersistentThreadLocalLayoutContext {
|
pub struct PersistentThreadLocalLayoutContext {
|
||||||
// FontContext uses Rc all over the place and so isn't Send, which means we
|
// 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;
|
let mut children_to_process = 0isize;
|
||||||
traversal.process_preorder(&mut traversal_data, &mut *tlc, node);
|
traversal.process_preorder(&mut traversal_data, &mut *tlc, node);
|
||||||
if let Some(el) = node.as_element() {
|
if let Some(el) = node.as_element() {
|
||||||
D::traverse_children(el, |kid| {
|
traversal.traverse_children(&mut *tlc, el, |_tlc, kid| {
|
||||||
children_to_process += 1;
|
children_to_process += 1;
|
||||||
discovered_child_nodes.push(unsafe { SendNode::new(kid) })
|
discovered_child_nodes.push(unsafe { SendNode::new(kid) })
|
||||||
});
|
});
|
||||||
|
|
|
@ -29,7 +29,9 @@ pub fn traverse_dom<E, D>(traversal: &D,
|
||||||
*depth += 1;
|
*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 {
|
if let Some(ref mut depth) = traversal_data.current_dom_depth {
|
||||||
*depth -= 1;
|
*depth -= 1;
|
||||||
|
|
|
@ -7,13 +7,14 @@
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
||||||
use context::{SharedStyleContext, StyleContext};
|
use context::{SharedStyleContext, StyleContext, ThreadLocalStyleContext};
|
||||||
use data::{ElementData, ElementStyles, StoredRestyleHint};
|
use data::{ElementData, ElementStyles, StoredRestyleHint};
|
||||||
use dom::{NodeInfo, TElement, TNode};
|
use dom::{NodeInfo, TElement, TNode};
|
||||||
use matching::{MatchMethods, StyleSharingResult};
|
use matching::{MatchMethods, StyleSharingResult};
|
||||||
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
|
use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF};
|
||||||
use selector_parser::RestyleDamage;
|
use selector_parser::RestyleDamage;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
|
use std::borrow::BorrowMut;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||||
use stylist::Stylist;
|
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
|
/// 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
|
/// to be used in the traversal, and of which we use one per worker, like
|
||||||
/// the bloom filter, for example.
|
/// 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.
|
/// Process `node` on the way down, before its children have been processed.
|
||||||
fn process_preorder(&self, data: &mut PerLevelTraversalData,
|
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
|
/// This may be called multiple times when processing an element, so we pass
|
||||||
/// a parameter to keep the logs tidy.
|
/// 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.
|
// See the comment on `cascade_node` for why we allow this on Gecko.
|
||||||
debug_assert!(cfg!(feature = "gecko") || parent_data.has_current_styles());
|
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
|
/// Helper for the traversal implementations to select the children that
|
||||||
/// should be enqueued for processing.
|
/// 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.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +259,7 @@ pub trait DomTraversal<E: TElement> : Sync {
|
||||||
{
|
{
|
||||||
unsafe { parent.set_dirty_descendants(); }
|
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.
|
/// Return the shared style context common to all worker threads.
|
||||||
fn shared_context(&self) -> &SharedStyleContext;
|
fn shared_context(&self) -> &SharedStyleContext;
|
||||||
|
|
||||||
/// Create a thread-local context.
|
/// Creates a thread-local context.
|
||||||
fn create_thread_local_context(&self) -> Self::ThreadLocalContext;
|
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);
|
trace!("propagated_hint={:?}, inherited_style_changed={:?}", propagated_hint, inherited_style_changed);
|
||||||
|
|
||||||
// Preprocess children, propagating restyle hints and handling sibling relationships.
|
// 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) {
|
(element.has_dirty_descendants() || !propagated_hint.is_empty() || inherited_style_changed) {
|
||||||
preprocess_children(traversal, element, propagated_hint, inherited_style_changed);
|
preprocess_children(traversal, element, propagated_hint, inherited_style_changed);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue