mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Stop using UnsafeNode in the StyleSharingCandidateCache.
This commit is contained in:
parent
c5f01fe3b8
commit
946e7fb7c3
7 changed files with 63 additions and 67 deletions
|
@ -25,13 +25,14 @@ use std::hash::BuildHasherDefault;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use style::context::{SharedStyleContext, ThreadLocalStyleContext};
|
use style::context::{SharedStyleContext, ThreadLocalStyleContext};
|
||||||
|
use style::dom::TElement;
|
||||||
|
|
||||||
/// TLS data scoped to the traversal.
|
/// TLS data scoped to the traversal.
|
||||||
pub struct ScopedThreadLocalLayoutContext {
|
pub struct ScopedThreadLocalLayoutContext<E: TElement> {
|
||||||
pub style_context: ThreadLocalStyleContext,
|
pub style_context: ThreadLocalStyleContext<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScopedThreadLocalLayoutContext {
|
impl<E: TElement> ScopedThreadLocalLayoutContext<E> {
|
||||||
pub fn new(shared: &SharedLayoutContext) -> Self {
|
pub fn new(shared: &SharedLayoutContext) -> Self {
|
||||||
ScopedThreadLocalLayoutContext {
|
ScopedThreadLocalLayoutContext {
|
||||||
style_context: ThreadLocalStyleContext::new(&shared.style_context),
|
style_context: ThreadLocalStyleContext::new(&shared.style_context),
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl<N> DomTraversal<N> for RecalcStyleAndConstructFlows
|
||||||
where N: LayoutNode + TNode,
|
where N: LayoutNode + TNode,
|
||||||
N::ConcreteElement: TElement
|
N::ConcreteElement: TElement
|
||||||
{
|
{
|
||||||
type ThreadLocalContext = ScopedThreadLocalLayoutContext;
|
type ThreadLocalContext = ScopedThreadLocalLayoutContext<N::ConcreteElement>;
|
||||||
|
|
||||||
fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData,
|
fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData,
|
||||||
thread_local: &mut Self::ThreadLocalContext, node: N) {
|
thread_local: &mut Self::ThreadLocalContext, node: N) {
|
||||||
|
@ -115,7 +115,7 @@ pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayo
|
||||||
#[inline]
|
#[inline]
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn construct_flows_at<'a, N>(context: &LayoutContext<'a>,
|
fn construct_flows_at<'a, N>(context: &LayoutContext<'a>,
|
||||||
_thread_local: &ScopedThreadLocalLayoutContext,
|
_thread_local: &ScopedThreadLocalLayoutContext<N::ConcreteElement>,
|
||||||
root: OpaqueNode, node: N)
|
root: OpaqueNode, node: N)
|
||||||
where N: LayoutNode,
|
where N: LayoutNode,
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
|
|
||||||
use animation::Animation;
|
use animation::Animation;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use dom::OpaqueNode;
|
use dom::{OpaqueNode, TElement};
|
||||||
use error_reporting::ParseErrorReporter;
|
use error_reporting::ParseErrorReporter;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use matching::StyleSharingCandidateCache;
|
use matching::StyleSharingCandidateCache;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
|
@ -76,25 +75,25 @@ pub struct SharedStyleContext {
|
||||||
pub quirks_mode: QuirksMode,
|
pub quirks_mode: QuirksMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ThreadLocalStyleContext {
|
pub struct ThreadLocalStyleContext<E: TElement> {
|
||||||
pub style_sharing_candidate_cache: RefCell<StyleSharingCandidateCache>,
|
pub style_sharing_candidate_cache: StyleSharingCandidateCache<E>,
|
||||||
/// A channel on which new animations that have been triggered by style
|
/// A channel on which new animations that have been triggered by style
|
||||||
/// recalculation can be sent.
|
/// recalculation can be sent.
|
||||||
pub new_animations_sender: Sender<Animation>,
|
pub new_animations_sender: Sender<Animation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ThreadLocalStyleContext {
|
impl<E: TElement> ThreadLocalStyleContext<E> {
|
||||||
pub fn new(shared: &SharedStyleContext) -> Self {
|
pub fn new(shared: &SharedStyleContext) -> Self {
|
||||||
ThreadLocalStyleContext {
|
ThreadLocalStyleContext {
|
||||||
style_sharing_candidate_cache: RefCell::new(StyleSharingCandidateCache::new()),
|
style_sharing_candidate_cache: StyleSharingCandidateCache::new(),
|
||||||
new_animations_sender: shared.local_context_creation_data.lock().unwrap().new_animations_sender.clone(),
|
new_animations_sender: shared.local_context_creation_data.lock().unwrap().new_animations_sender.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StyleContext<'a> {
|
pub struct StyleContext<'a, E: TElement + 'a> {
|
||||||
pub shared: &'a SharedStyleContext,
|
pub shared: &'a SharedStyleContext,
|
||||||
pub thread_local: &'a ThreadLocalStyleContext,
|
pub thread_local: &'a mut ThreadLocalStyleContext<E>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Why we're doing reflow.
|
/// Why we're doing reflow.
|
||||||
|
|
|
@ -22,10 +22,10 @@ impl RecalcStyleOnly {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ln> DomTraversal<GeckoNode<'ln>> for RecalcStyleOnly {
|
impl<'ln> DomTraversal<GeckoNode<'ln>> for RecalcStyleOnly {
|
||||||
type ThreadLocalContext = ThreadLocalStyleContext;
|
type ThreadLocalContext = ThreadLocalStyleContext<GeckoElement<'ln>>;
|
||||||
|
|
||||||
fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData,
|
fn process_preorder(&self, traversal_data: &mut PerLevelTraversalData,
|
||||||
thread_local: &mut ThreadLocalStyleContext,
|
thread_local: &mut Self::ThreadLocalContext,
|
||||||
node: GeckoNode<'ln>)
|
node: GeckoNode<'ln>)
|
||||||
{
|
{
|
||||||
if node.is_element() {
|
if node.is_element() {
|
||||||
|
@ -39,7 +39,7 @@ impl<'ln> DomTraversal<GeckoNode<'ln>> for RecalcStyleOnly {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_postorder(&self, _: &mut ThreadLocalStyleContext, _: GeckoNode<'ln>) {
|
fn process_postorder(&self, _: &mut Self::ThreadLocalContext, _: GeckoNode<'ln>) {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ impl<'ln> DomTraversal<GeckoNode<'ln>> for RecalcStyleOnly {
|
||||||
&self.shared
|
&self.shared
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_thread_local_context(&self) -> ThreadLocalStyleContext {
|
fn create_thread_local_context(&self) -> Self::ThreadLocalContext {
|
||||||
ThreadLocalStyleContext::new(&self.shared)
|
ThreadLocalStyleContext::new(&self.shared)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use cache::LRUCache;
|
||||||
use cascade_info::CascadeInfo;
|
use cascade_info::CascadeInfo;
|
||||||
use context::{SharedStyleContext, StyleContext};
|
use context::{SharedStyleContext, StyleContext};
|
||||||
use data::{ComputedStyle, ElementData, ElementStyles, PseudoStyles};
|
use data::{ComputedStyle, ElementData, ElementStyles, PseudoStyles};
|
||||||
use dom::{TElement, TNode, UnsafeNode};
|
use dom::{TElement, TNode};
|
||||||
use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
|
use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
|
||||||
use properties::longhands::display::computed_value as display;
|
use properties::longhands::display::computed_value as display;
|
||||||
use rule_tree::StrongRuleNode;
|
use rule_tree::StrongRuleNode;
|
||||||
|
@ -65,22 +65,29 @@ impl MatchResults {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TElement isn't Send because we want to be careful and explicit about our
|
||||||
|
// parallel traversal, but we need the candidates to be Send so that we can stick
|
||||||
|
// them in ScopedTLS.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct SendElement<E: TElement>(pub E);
|
||||||
|
unsafe impl<E: TElement> Send for SendElement<E> {}
|
||||||
|
|
||||||
/// Information regarding a candidate.
|
/// Information regarding a candidate.
|
||||||
///
|
///
|
||||||
/// TODO: We can stick a lot more info here.
|
/// TODO: We can stick a lot more info here.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct StyleSharingCandidate {
|
struct StyleSharingCandidate<E: TElement> {
|
||||||
/// The node, guaranteed to be an element.
|
/// The element.
|
||||||
node: UnsafeNode,
|
element: SendElement<E>,
|
||||||
/// The cached common style affecting attribute info.
|
/// The cached common style affecting attribute info.
|
||||||
common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>,
|
common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>,
|
||||||
/// the cached class names.
|
/// the cached class names.
|
||||||
class_attributes: Option<Vec<Atom>>,
|
class_attributes: Option<Vec<Atom>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq<StyleSharingCandidate> for StyleSharingCandidate {
|
impl<E: TElement> PartialEq<StyleSharingCandidate<E>> for StyleSharingCandidate<E> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.node == other.node &&
|
self.element == other.element &&
|
||||||
self.common_style_affecting_attributes == other.common_style_affecting_attributes
|
self.common_style_affecting_attributes == other.common_style_affecting_attributes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,13 +97,8 @@ impl PartialEq<StyleSharingCandidate> for StyleSharingCandidate {
|
||||||
///
|
///
|
||||||
/// Note that this cache is flushed every time we steal work from the queue, so
|
/// Note that this cache is flushed every time we steal work from the queue, so
|
||||||
/// storing nodes here temporarily is safe.
|
/// storing nodes here temporarily is safe.
|
||||||
///
|
pub struct StyleSharingCandidateCache<E: TElement> {
|
||||||
/// NB: We store UnsafeNode's, but this is not unsafe. It's a shame being
|
cache: LRUCache<StyleSharingCandidate<E>, ()>,
|
||||||
/// generic over elements is unfeasible (you can make compile style without much
|
|
||||||
/// difficulty, but good luck with layout and all the types with assoc.
|
|
||||||
/// lifetimes).
|
|
||||||
pub struct StyleSharingCandidateCache {
|
|
||||||
cache: LRUCache<StyleSharingCandidate, ()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -117,7 +119,7 @@ pub enum CacheMiss {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn element_matches_candidate<E: TElement>(element: &E,
|
fn element_matches_candidate<E: TElement>(element: &E,
|
||||||
candidate: &mut StyleSharingCandidate,
|
candidate: &mut StyleSharingCandidate<E>,
|
||||||
candidate_element: &E,
|
candidate_element: &E,
|
||||||
shared_context: &SharedStyleContext)
|
shared_context: &SharedStyleContext)
|
||||||
-> Result<ComputedStyle, CacheMiss> {
|
-> Result<ComputedStyle, CacheMiss> {
|
||||||
|
@ -193,7 +195,7 @@ fn element_matches_candidate<E: TElement>(element: &E,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_same_common_style_affecting_attributes<E: TElement>(element: &E,
|
fn have_same_common_style_affecting_attributes<E: TElement>(element: &E,
|
||||||
candidate: &mut StyleSharingCandidate,
|
candidate: &mut StyleSharingCandidate<E>,
|
||||||
candidate_element: &E) -> bool {
|
candidate_element: &E) -> bool {
|
||||||
if candidate.common_style_affecting_attributes.is_none() {
|
if candidate.common_style_affecting_attributes.is_none() {
|
||||||
candidate.common_style_affecting_attributes =
|
candidate.common_style_affecting_attributes =
|
||||||
|
@ -272,7 +274,7 @@ pub fn rare_style_affecting_attributes() -> [LocalName; 3] {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn have_same_class<E: TElement>(element: &E,
|
fn have_same_class<E: TElement>(element: &E,
|
||||||
candidate: &mut StyleSharingCandidate,
|
candidate: &mut StyleSharingCandidate<E>,
|
||||||
candidate_element: &E) -> bool {
|
candidate_element: &E) -> bool {
|
||||||
// XXX Efficiency here, I'm only validating ideas.
|
// XXX Efficiency here, I'm only validating ideas.
|
||||||
let mut element_class_attributes = vec![];
|
let mut element_class_attributes = vec![];
|
||||||
|
@ -304,21 +306,21 @@ fn match_same_sibling_affecting_rules<E: TElement>(element: &E,
|
||||||
|
|
||||||
static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 8;
|
static STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 8;
|
||||||
|
|
||||||
impl StyleSharingCandidateCache {
|
impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
StyleSharingCandidateCache {
|
StyleSharingCandidateCache {
|
||||||
cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE),
|
cache: LRUCache::new(STYLE_SHARING_CANDIDATE_CACHE_SIZE),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_mut(&mut self) -> IterMut<(StyleSharingCandidate, ())> {
|
fn iter_mut(&mut self) -> IterMut<(StyleSharingCandidate<E>, ())> {
|
||||||
self.cache.iter_mut()
|
self.cache.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_if_possible<E: TElement>(&mut self,
|
pub fn insert_if_possible(&mut self,
|
||||||
element: &E,
|
element: &E,
|
||||||
style: &Arc<ComputedValues>,
|
style: &Arc<ComputedValues>,
|
||||||
relations: StyleRelations) {
|
relations: StyleRelations) {
|
||||||
use traversal::relations_are_shareable;
|
use traversal::relations_are_shareable;
|
||||||
|
|
||||||
let parent = match element.parent_element() {
|
let parent = match element.parent_element() {
|
||||||
|
@ -348,10 +350,10 @@ impl StyleSharingCandidateCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Inserting into cache: {:?} with parent {:?}",
|
debug!("Inserting into cache: {:?} with parent {:?}",
|
||||||
element.as_node().to_unsafe(), parent.as_node().to_unsafe());
|
element, parent);
|
||||||
|
|
||||||
self.cache.insert(StyleSharingCandidate {
|
self.cache.insert(StyleSharingCandidate {
|
||||||
node: element.as_node().to_unsafe(),
|
element: SendElement(*element),
|
||||||
common_style_affecting_attributes: None,
|
common_style_affecting_attributes: None,
|
||||||
class_attributes: None,
|
class_attributes: None,
|
||||||
}, ());
|
}, ());
|
||||||
|
@ -392,7 +394,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
/// Note that animations only apply to nodes or ::before or ::after
|
/// Note that animations only apply to nodes or ::before or ::after
|
||||||
/// pseudo-elements.
|
/// pseudo-elements.
|
||||||
fn cascade_node_pseudo_element<'a>(&self,
|
fn cascade_node_pseudo_element<'a>(&self,
|
||||||
context: &StyleContext,
|
context: &StyleContext<Self>,
|
||||||
parent_style: Option<&Arc<ComputedValues>>,
|
parent_style: Option<&Arc<ComputedValues>>,
|
||||||
old_style: Option<&Arc<ComputedValues>>,
|
old_style: Option<&Arc<ComputedValues>>,
|
||||||
rule_node: &StrongRuleNode,
|
rule_node: &StrongRuleNode,
|
||||||
|
@ -497,20 +499,17 @@ trait PrivateMatchMethods: TElement {
|
||||||
|
|
||||||
fn share_style_with_candidate_if_possible(&self,
|
fn share_style_with_candidate_if_possible(&self,
|
||||||
shared_context: &SharedStyleContext,
|
shared_context: &SharedStyleContext,
|
||||||
candidate: &mut StyleSharingCandidate)
|
candidate: &mut StyleSharingCandidate<Self>)
|
||||||
-> Result<ComputedStyle, CacheMiss> {
|
-> Result<ComputedStyle, CacheMiss> {
|
||||||
let candidate_element = unsafe {
|
let candidate_element = candidate.element.0;
|
||||||
Self::ConcreteNode::from_unsafe(&candidate.node).as_element().unwrap()
|
|
||||||
};
|
|
||||||
|
|
||||||
element_matches_candidate(self, candidate, &candidate_element,
|
element_matches_candidate(self, candidate, &candidate_element,
|
||||||
shared_context)
|
shared_context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_rule_node(context: &StyleContext,
|
fn compute_rule_node<E: TElement>(context: &StyleContext<E>,
|
||||||
applicable_declarations: &mut Vec<ApplicableDeclarationBlock>)
|
applicable_declarations: &mut Vec<ApplicableDeclarationBlock>)
|
||||||
-> StrongRuleNode
|
-> StrongRuleNode
|
||||||
{
|
{
|
||||||
let rules = applicable_declarations.drain(..).map(|d| (d.source, d.importance));
|
let rules = applicable_declarations.drain(..).map(|d| (d.source, d.importance));
|
||||||
let rule_node = context.shared.stylist.rule_tree.insert_ordered_rules(rules);
|
let rule_node = context.shared.stylist.rule_tree.insert_ordered_rules(rules);
|
||||||
|
@ -520,7 +519,7 @@ fn compute_rule_node(context: &StyleContext,
|
||||||
impl<E: TElement> PrivateMatchMethods for E {}
|
impl<E: TElement> PrivateMatchMethods for E {}
|
||||||
|
|
||||||
pub trait MatchMethods : TElement {
|
pub trait MatchMethods : TElement {
|
||||||
fn match_element(&self, context: &StyleContext, parent_bf: Option<&BloomFilter>)
|
fn match_element(&self, context: &StyleContext<Self>, parent_bf: Option<&BloomFilter>)
|
||||||
-> MatchResults
|
-> MatchResults
|
||||||
{
|
{
|
||||||
let mut applicable_declarations: Vec<ApplicableDeclarationBlock> = Vec::with_capacity(16);
|
let mut applicable_declarations: Vec<ApplicableDeclarationBlock> = Vec::with_capacity(16);
|
||||||
|
@ -569,7 +568,7 @@ pub trait MatchMethods : TElement {
|
||||||
/// guarantee that at the type system level yet.
|
/// guarantee that at the type system level yet.
|
||||||
unsafe fn share_style_if_possible(&self,
|
unsafe fn share_style_if_possible(&self,
|
||||||
style_sharing_candidate_cache:
|
style_sharing_candidate_cache:
|
||||||
&mut StyleSharingCandidateCache,
|
&mut StyleSharingCandidateCache<Self>,
|
||||||
shared_context: &SharedStyleContext,
|
shared_context: &SharedStyleContext,
|
||||||
data: &mut AtomicRefMut<ElementData>)
|
data: &mut AtomicRefMut<ElementData>)
|
||||||
-> StyleSharingResult {
|
-> StyleSharingResult {
|
||||||
|
@ -718,7 +717,7 @@ pub trait MatchMethods : TElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn cascade_node(&self,
|
unsafe fn cascade_node(&self,
|
||||||
context: &StyleContext,
|
context: &StyleContext<Self>,
|
||||||
mut data: &mut AtomicRefMut<ElementData>,
|
mut data: &mut AtomicRefMut<ElementData>,
|
||||||
parent: Option<Self>,
|
parent: Option<Self>,
|
||||||
primary_rule_node: StrongRuleNode,
|
primary_rule_node: StrongRuleNode,
|
||||||
|
@ -795,7 +794,7 @@ pub trait MatchMethods : TElement {
|
||||||
mut old_pseudos: Option<&mut PseudoStyles>,
|
mut old_pseudos: Option<&mut PseudoStyles>,
|
||||||
new_primary: &Arc<ComputedValues>,
|
new_primary: &Arc<ComputedValues>,
|
||||||
new_pseudos: &mut PseudoStyles,
|
new_pseudos: &mut PseudoStyles,
|
||||||
context: &StyleContext,
|
context: &StyleContext<Self>,
|
||||||
mut pseudo_rule_nodes: PseudoRuleNodes,
|
mut pseudo_rule_nodes: PseudoRuleNodes,
|
||||||
possibly_expired_animations: &mut Vec<PropertyAnimation>)
|
possibly_expired_animations: &mut Vec<PropertyAnimation>)
|
||||||
-> RestyleDamage
|
-> RestyleDamage
|
||||||
|
|
|
@ -336,7 +336,7 @@ pub fn relations_are_shareable(relations: &StyleRelations) -> bool {
|
||||||
|
|
||||||
/// Handles lazy resolution of style in display:none subtrees. See the comment
|
/// Handles lazy resolution of style in display:none subtrees. See the comment
|
||||||
/// at the callsite in query.rs.
|
/// at the callsite in query.rs.
|
||||||
pub fn style_element_in_display_none_subtree<E, F>(context: &StyleContext,
|
pub fn style_element_in_display_none_subtree<E, F>(context: &StyleContext<E>,
|
||||||
element: E, init_data: &F) -> E
|
element: E, init_data: &F) -> E
|
||||||
where E: TElement,
|
where E: TElement,
|
||||||
F: Fn(E),
|
F: Fn(E),
|
||||||
|
@ -375,7 +375,7 @@ pub fn style_element_in_display_none_subtree<E, F>(context: &StyleContext,
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
pub fn recalc_style_at<E, D>(traversal: &D,
|
pub fn recalc_style_at<E, D>(traversal: &D,
|
||||||
traversal_data: &mut PerLevelTraversalData,
|
traversal_data: &mut PerLevelTraversalData,
|
||||||
context: &StyleContext,
|
context: &mut StyleContext<E>,
|
||||||
element: E,
|
element: E,
|
||||||
mut data: &mut AtomicRefMut<ElementData>)
|
mut data: &mut AtomicRefMut<ElementData>)
|
||||||
where E: TElement,
|
where E: TElement,
|
||||||
|
@ -422,7 +422,7 @@ pub fn recalc_style_at<E, D>(traversal: &D,
|
||||||
// since we have separate bits for each now.
|
// since we have separate bits for each now.
|
||||||
fn compute_style<E, D>(_traversal: &D,
|
fn compute_style<E, D>(_traversal: &D,
|
||||||
traversal_data: &mut PerLevelTraversalData,
|
traversal_data: &mut PerLevelTraversalData,
|
||||||
context: &StyleContext,
|
context: &mut StyleContext<E>,
|
||||||
element: E,
|
element: E,
|
||||||
mut data: &mut AtomicRefMut<ElementData>) -> bool
|
mut data: &mut AtomicRefMut<ElementData>) -> bool
|
||||||
where E: TElement,
|
where E: TElement,
|
||||||
|
@ -444,13 +444,10 @@ fn compute_style<E, D>(_traversal: &D,
|
||||||
bf.assert_complete(element);
|
bf.assert_complete(element);
|
||||||
|
|
||||||
// Check to see whether we can share a style with someone.
|
// Check to see whether we can share a style with someone.
|
||||||
let mut style_sharing_candidate_cache =
|
|
||||||
context.thread_local.style_sharing_candidate_cache.borrow_mut();
|
|
||||||
|
|
||||||
let sharing_result = if element.parent_element().is_none() {
|
let sharing_result = if element.parent_element().is_none() {
|
||||||
StyleSharingResult::CannotShare
|
StyleSharingResult::CannotShare
|
||||||
} else {
|
} else {
|
||||||
unsafe { element.share_style_if_possible(&mut style_sharing_candidate_cache,
|
unsafe { element.share_style_if_possible(&mut context.thread_local.style_sharing_candidate_cache,
|
||||||
shared_context, &mut data) }
|
shared_context, &mut data) }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -485,16 +482,16 @@ fn compute_style<E, D>(_traversal: &D,
|
||||||
|
|
||||||
// Add ourselves to the LRU cache.
|
// Add ourselves to the LRU cache.
|
||||||
if let Some(element) = shareable_element {
|
if let Some(element) = shareable_element {
|
||||||
style_sharing_candidate_cache.insert_if_possible(&element,
|
context.thread_local
|
||||||
&data.styles().primary.values,
|
.style_sharing_candidate_cache
|
||||||
relations);
|
.insert_if_possible(&element, &data.styles().primary.values, relations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StyleSharingResult::StyleWasShared(index) => {
|
StyleSharingResult::StyleWasShared(index) => {
|
||||||
if opts::get().style_sharing_stats {
|
if opts::get().style_sharing_stats {
|
||||||
STYLE_SHARING_CACHE_HITS.fetch_add(1, Ordering::Relaxed);
|
STYLE_SHARING_CACHE_HITS.fetch_add(1, Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
style_sharing_candidate_cache.touch(index);
|
context.thread_local.style_sharing_candidate_cache.touch(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -875,12 +875,12 @@ pub extern "C" fn Servo_ResolveStyle(element: RawGeckoElementBorrowed,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut tlc = ThreadLocalStyleContext::new(traversal.shared_context());
|
let mut tlc = ThreadLocalStyleContext::new(traversal.shared_context());
|
||||||
let context = StyleContext {
|
let mut context = StyleContext {
|
||||||
shared: traversal.shared_context(),
|
shared: traversal.shared_context(),
|
||||||
thread_local: &mut tlc,
|
thread_local: &mut tlc,
|
||||||
};
|
};
|
||||||
|
|
||||||
recalc_style_at(&traversal, &mut traversal_data, &context, element, &mut data);
|
recalc_style_at(&traversal, &mut traversal_data, &mut context, element, &mut data);
|
||||||
|
|
||||||
// The element was either unstyled or needed restyle. If it was unstyled, it may have
|
// The element was either unstyled or needed restyle. If it was unstyled, it may have
|
||||||
// additional unstyled children that subsequent traversals won't find now that the style
|
// additional unstyled children that subsequent traversals won't find now that the style
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue