mirror of
https://github.com/servo/servo.git
synced 2025-08-12 17:05:33 +01:00
layout: Stop storing PrecomputedStyleData in LayoutNode
Use the SharedStyleContext instead.
This commit is contained in:
parent
979c3a54b9
commit
2a499d5a0b
15 changed files with 176 additions and 190 deletions
|
@ -3,7 +3,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use properties::ComputedValues;
|
||||
use selector_matching::PrecomputedStyleData;
|
||||
use selectors::parser::SelectorImpl;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::BuildHasherDefault;
|
||||
|
@ -14,12 +13,6 @@ pub struct PrivateStyleData<Impl: SelectorImpl, ConcreteComputedValues: Computed
|
|||
/// The results of CSS styling for this node.
|
||||
pub style: Option<Arc<ConcreteComputedValues>>,
|
||||
|
||||
/// Shared rules data needed to avoid doing the cascade for some
|
||||
/// pseudo-elements like "-servo-details-content"
|
||||
///
|
||||
/// TODO: Move to TLS to avoid this extra pointer?
|
||||
pub precomputed: Arc<PrecomputedStyleData<Impl, ConcreteComputedValues>>,
|
||||
|
||||
/// The results of CSS styling for each pseudo-element (if any).
|
||||
pub per_pseudo: HashMap<Impl::PseudoElement, Arc<ConcreteComputedValues>,
|
||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||
|
@ -30,11 +23,9 @@ pub struct PrivateStyleData<Impl: SelectorImpl, ConcreteComputedValues: Computed
|
|||
|
||||
impl<Impl, ConcreteComputedValues> PrivateStyleData<Impl, ConcreteComputedValues>
|
||||
where Impl: SelectorImpl, ConcreteComputedValues: ComputedValues {
|
||||
pub fn new(precomputed: Arc<PrecomputedStyleData<Impl, ConcreteComputedValues>>)
|
||||
-> PrivateStyleData<Impl, ConcreteComputedValues> {
|
||||
pub fn new() -> PrivateStyleData<Impl, ConcreteComputedValues> {
|
||||
PrivateStyleData {
|
||||
style: None,
|
||||
precomputed: precomputed,
|
||||
per_pseudo: HashMap::with_hasher(Default::default()),
|
||||
parallel: DomParallelInfo::new(),
|
||||
}
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use context::SharedStyleContext;
|
||||
use data::PrivateStyleData;
|
||||
use element_state::ElementState;
|
||||
use properties::{ComputedValues, PropertyDeclaration, PropertyDeclarationBlock};
|
||||
use restyle_hints::{ElementSnapshot, RESTYLE_DESCENDANTS, RESTYLE_LATER_SIBLINGS, RESTYLE_SELF, RestyleHint};
|
||||
use selector_impl::{ElementExt, SelectorImplExt};
|
||||
use selector_matching::PrecomputedStyleData;
|
||||
use selectors::Element;
|
||||
use selectors::matching::DeclarationBlock;
|
||||
use smallvec::VecLike;
|
||||
|
@ -90,10 +90,7 @@ pub trait TNode : Sized + Copy + Clone {
|
|||
/// initialized.
|
||||
///
|
||||
/// FIXME(pcwalton): Do this as part of fragment building instead of in a traversal.
|
||||
fn initialize_data(self,
|
||||
precomputed: &Arc<PrecomputedStyleData<<Self::ConcreteElement as Element>::Impl,
|
||||
Self::ConcreteComputedValues>>)
|
||||
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt;
|
||||
fn initialize_data(self);
|
||||
|
||||
/// While doing a reflow, the node at the root has no parent, as far as we're
|
||||
/// concerned. This method returns `None` at the reflow root.
|
||||
|
@ -174,7 +171,10 @@ pub trait TNode : Sized + Copy + Clone {
|
|||
|
||||
/// Returns the style results for the given node. If CSS selector matching
|
||||
/// has not yet been performed, fails.
|
||||
fn style(&self) -> Ref<Arc<Self::ConcreteComputedValues>> {
|
||||
fn style(&self,
|
||||
_context: &SharedStyleContext<<Self::ConcreteElement as Element>::Impl>)
|
||||
-> Ref<Arc<Self::ConcreteComputedValues>>
|
||||
where <Self::ConcreteElement as Element>::Impl: SelectorImplExt<ComputedValues=Self::ConcreteComputedValues> {
|
||||
Ref::map(self.borrow_data().unwrap(), |data| data.style.as_ref().unwrap())
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
use element_state::ElementState;
|
||||
use properties::{self, ServoComputedValues};
|
||||
use selector_matching::{USER_OR_USER_AGENT_STYLESHEETS, QUIRKS_MODE_STYLESHEET};
|
||||
use selectors::Element;
|
||||
use selectors::parser::{ParserContext, SelectorImpl};
|
||||
use stylesheets::Stylesheet;
|
||||
use properties::{self, ServoComputedValues};
|
||||
|
||||
pub trait ElementExt: Element {
|
||||
fn is_link(&self) -> bool;
|
||||
|
|
|
@ -84,42 +84,6 @@ lazy_static! {
|
|||
};
|
||||
}
|
||||
|
||||
#[derive(HeapSizeOf)]
|
||||
pub struct PrecomputedStyleData<Impl: SelectorImpl, Computed: ComputedValues> {
|
||||
/// Applicable declarations for a given non-eagerly cascaded pseudo-element.
|
||||
/// These are eagerly computed once, and then used to resolve the new
|
||||
/// computed values on the fly on layout.
|
||||
non_eagerly_cascaded_pseudo_elements: HashMap<Impl::PseudoElement,
|
||||
Vec<DeclarationBlock>,
|
||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||
_phantom: ::std::marker::PhantomData<Computed>,
|
||||
}
|
||||
|
||||
impl<Impl, Computed> PrecomputedStyleData<Impl, Computed>
|
||||
where Impl: SelectorImpl, Computed: ComputedValues {
|
||||
fn new() -> Self {
|
||||
PrecomputedStyleData {
|
||||
non_eagerly_cascaded_pseudo_elements: HashMap::with_hasher(Default::default()),
|
||||
_phantom: ::std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn computed_values_for(&self,
|
||||
pseudo: &Impl::PseudoElement,
|
||||
parent: Option<&Arc<Computed>>) -> Option<Arc<Computed>> {
|
||||
if let Some(declarations) = self.non_eagerly_cascaded_pseudo_elements.get(pseudo) {
|
||||
let (computed, _) =
|
||||
properties::cascade::<Computed>(Size2D::zero(),
|
||||
&declarations, false,
|
||||
parent.map(|p| &**p), None,
|
||||
box StdoutErrorReporter);
|
||||
Some(Arc::new(computed))
|
||||
} else {
|
||||
parent.map(|p| p.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This structure holds all the selectors and device characteristics
|
||||
/// for a given document. The selectors are converted into `Rule`s
|
||||
/// (defined in rust-selectors), and introduced in a `SelectorMap`
|
||||
|
@ -160,10 +124,12 @@ pub struct Stylist<Impl: SelectorImplExt> {
|
|||
PerPseudoElementSelectorMap<Impl>,
|
||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||
|
||||
/// Precomputed data to be shared to the nodes.
|
||||
/// Note that this has to be an Arc, since the layout thread needs the
|
||||
/// stylist mutable.
|
||||
precomputed: Arc<PrecomputedStyleData<Impl, Impl::ComputedValues>>,
|
||||
/// Applicable declarations for a given non-eagerly cascaded pseudo-element.
|
||||
/// These are eagerly computed once, and then used to resolve the new
|
||||
/// computed values on the fly on layout.
|
||||
non_eagerly_cascaded_pseudo_element_decls: HashMap<Impl::PseudoElement,
|
||||
Vec<DeclarationBlock>,
|
||||
BuildHasherDefault<::fnv::FnvHasher>>,
|
||||
|
||||
rules_source_order: usize,
|
||||
|
||||
|
@ -182,7 +148,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
|||
|
||||
element_map: PerPseudoElementSelectorMap::new(),
|
||||
pseudos_map: HashMap::with_hasher(Default::default()),
|
||||
precomputed: Arc::new(PrecomputedStyleData::new()),
|
||||
non_eagerly_cascaded_pseudo_element_decls: HashMap::with_hasher(Default::default()),
|
||||
rules_source_order: 0,
|
||||
state_deps: DependencySet::new(),
|
||||
};
|
||||
|
@ -205,7 +171,7 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
|||
|
||||
self.element_map = PerPseudoElementSelectorMap::new();
|
||||
self.pseudos_map = HashMap::with_hasher(Default::default());
|
||||
self.precomputed = Arc::new(PrecomputedStyleData::new());
|
||||
self.non_eagerly_cascaded_pseudo_element_decls = HashMap::with_hasher(Default::default());
|
||||
self.rules_source_order = 0;
|
||||
self.state_deps.clear();
|
||||
|
||||
|
@ -279,29 +245,30 @@ impl<Impl: SelectorImplExt> Stylist<Impl> {
|
|||
// This is actually kind of hard, because the stylist is shared
|
||||
// between threads.
|
||||
if let Some(map) = self.pseudos_map.remove(&pseudo) {
|
||||
let mut precomputed = Arc::get_mut(&mut self.precomputed)
|
||||
.expect("Stylist was not the single owner of PrecomputedStyleData");
|
||||
|
||||
let mut declarations = vec![];
|
||||
|
||||
map.user_agent.normal.get_universal_rules(&mut declarations);
|
||||
map.user_agent.important.get_universal_rules(&mut declarations);
|
||||
|
||||
precomputed.non_eagerly_cascaded_pseudo_elements.insert(pseudo, declarations);
|
||||
self.non_eagerly_cascaded_pseudo_element_decls.insert(pseudo, declarations);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_precomputed_data(&self) -> &Arc<PrecomputedStyleData<Impl, Impl::ComputedValues>> {
|
||||
&self.precomputed
|
||||
}
|
||||
|
||||
pub fn get_non_eagerly_cascaded_pseudo_element_style(&self,
|
||||
pseudo: &Impl::PseudoElement,
|
||||
parent: Option<&Arc<Impl::ComputedValues>>) -> Option<Arc<Impl::ComputedValues>> {
|
||||
pub fn computed_values_for_pseudo(&self,
|
||||
pseudo: &Impl::PseudoElement,
|
||||
parent: Option<&Arc<Impl::ComputedValues>>) -> Option<Arc<Impl::ComputedValues>> {
|
||||
debug_assert!(!Impl::is_eagerly_cascaded_pseudo_element(pseudo));
|
||||
self.precomputed
|
||||
.computed_values_for(pseudo, parent)
|
||||
if let Some(declarations) = self.non_eagerly_cascaded_pseudo_element_decls.get(pseudo) {
|
||||
let (computed, _) =
|
||||
properties::cascade::<Impl::ComputedValues>(Size2D::zero(),
|
||||
&declarations, false,
|
||||
parent.map(|p| &**p), None,
|
||||
box StdoutErrorReporter);
|
||||
Some(Arc::new(computed))
|
||||
} else {
|
||||
parent.map(|p| p.clone())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_restyle_hint<E>(&self, element: &E,
|
||||
|
|
|
@ -11,6 +11,5 @@ use stylesheets;
|
|||
/// Concrete types for servo Style implementation
|
||||
pub type Stylesheet = stylesheets::Stylesheet<ServoSelectorImpl>;
|
||||
pub type PrivateStyleData = data::PrivateStyleData<ServoSelectorImpl, ServoComputedValues>;
|
||||
pub type PrecomputedStyleData = selector_matching::PrecomputedStyleData<ServoSelectorImpl, ServoComputedValues>;
|
||||
pub type Stylist = selector_matching::Stylist<ServoSelectorImpl>;
|
||||
pub type SharedStyleContext = context::SharedStyleContext<ServoSelectorImpl>;
|
||||
|
|
|
@ -129,7 +129,7 @@ pub fn recalc_style_at<'a, N, C>(context: &'a C,
|
|||
//
|
||||
// FIXME(pcwalton): Stop allocating here. Ideally this should just be done by the HTML
|
||||
// parser.
|
||||
node.initialize_data(context.shared_context().stylist.get_precomputed_data());
|
||||
node.initialize_data();
|
||||
|
||||
// Get the parent node.
|
||||
let parent_opt = node.layout_parent_node(root);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue