Skip to content

Commit

Permalink
style: Inline RestyleData.
Browse files Browse the repository at this point in the history
Bug: 1368236
MozReview-Commit-ID: 49s3SO0PMHf
  • Loading branch information
emilio committed Jun 16, 2017
1 parent 0c53ba3 commit ffc45e9
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 202 deletions.
11 changes: 3 additions & 8 deletions components/layout/wrapper.rs
Expand Up @@ -171,19 +171,14 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {

let damage = {
let data = node.get_raw_data().unwrap();
if let Some(r) = data.style_data.element_data.borrow().get_restyle() {
// We're reflowing a node that just got a restyle, and so the
// damage has been computed and stored in the RestyleData.
r.damage
} else if !data.layout_data.borrow().flags.contains(::data::HAS_BEEN_TRAVERSED) {

if !data.layout_data.borrow().flags.contains(::data::HAS_BEEN_TRAVERSED) {
// We're reflowing a node that was styled for the first time and
// has never been visited by layout. Return rebuild_and_reflow,
// because that's what the code expects.
RestyleDamage::rebuild_and_reflow()
} else {
// We're reflowing a node whose style data didn't change, but whose
// layout may change due to changes in ancestors or descendants.
RestyleDamage::empty()
data.style_data.element_data.borrow().restyle.damage
}
};

Expand Down
11 changes: 5 additions & 6 deletions components/layout_thread/lib.rs
Expand Up @@ -1116,7 +1116,7 @@ impl LayoutThread {
let el = node.as_element().unwrap();
if let Some(mut d) = element.mutate_data() {
if d.has_styles() {
d.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
d.restyle.hint.insert(RestyleHint::restyle_subtree());
}
}
if let Some(p) = el.parent_element() {
Expand Down Expand Up @@ -1152,7 +1152,7 @@ impl LayoutThread {
if needs_dirtying {
if let Some(mut d) = element.mutate_data() {
if d.has_styles() {
d.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
d.restyle.hint.insert(RestyleHint::restyle_subtree());
}
}
}
Expand Down Expand Up @@ -1197,12 +1197,11 @@ impl LayoutThread {
}

let mut style_data = style_data.borrow_mut();
let mut restyle_data = style_data.ensure_restyle();

// Stash the data on the element for processing by the style system.
restyle_data.hint.insert(restyle.hint.into());
restyle_data.damage = restyle.damage;
debug!("Noting restyle for {:?}: {:?}", el, restyle_data);
style_data.restyle.hint.insert(restyle.hint.into());
style_data.restyle.damage = restyle.damage;
debug!("Noting restyle for {:?}: {:?}", el, style_data.restyle);
}

// Create a layout context for use throughout the following passes.
Expand Down
141 changes: 77 additions & 64 deletions components/style/data.rs
Expand Up @@ -348,27 +348,80 @@ impl ElementStyles {
}
}

bitflags! {
flags RestyleFlags: u8 {
/// Whether the styles changed for this restyle.
const WAS_RESTYLED = 1 << 0,
/// Whether we reframed/reconstructed any ancestor or self.
const ANCESTOR_WAS_RECONSTRUCTED = 1 << 1,
}
}

/// Transient data used by the restyle algorithm. This structure is instantiated
/// either before or during restyle traversal, and is cleared at the end of node
/// processing.
#[derive(Debug, Default)]
#[derive(Debug)]
pub struct RestyleData {
/// The restyle hint, which indicates whether selectors need to be rematched
/// for this element, its children, and its descendants.
pub hint: RestyleHint,

/// Whether we reframed/reconstructed any ancestor or self.
pub reconstructed_ancestor: bool,
/// A few flags to have in mind.
flags: RestyleFlags,

/// The restyle damage, indicating what kind of layout changes are required
/// afte restyling.
pub damage: RestyleDamage,
}

impl RestyleData {
/// Returns true if this RestyleData might invalidate the current style.
pub fn has_invalidations(&self) -> bool {
self.hint.has_self_invalidations()
fn new() -> Self {
Self {
hint: RestyleHint::empty(),
flags: RestyleFlags::empty(),
damage: RestyleDamage::empty(),
}
}

/// Clear all the restyle state associated with this element.
fn clear(&mut self) {
*self = Self::new();
}

/// Returns whether this element or any ancestor is going to be
/// reconstructed.
pub fn reconstructed_self_or_ancestor(&self) -> bool {
self.reconstructed_ancestor() ||
self.damage.contains(RestyleDamage::reconstruct())
}

/// Returns whether any ancestor of this element was restyled.
fn reconstructed_ancestor(&self) -> bool {
self.flags.contains(ANCESTOR_WAS_RECONSTRUCTED)
}

/// Sets the flag that tells us whether we've reconstructed an ancestor.
pub fn set_reconstructed_ancestor(&mut self) {
// If it weren't for animation-only traversals, we could assert
// `!self.reconstructed_ancestor()` here.
self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED);
}

/// Mark this element as restyled, which is useful to know whether we need
/// to do a post-traversal.
pub fn set_restyled(&mut self) {
self.flags.insert(WAS_RESTYLED);
}

/// Mark this element as restyled, which is useful to know whether we need
/// to do a post-traversal.
pub fn is_restyle(&self) -> bool {
self.flags.contains(WAS_RESTYLED)
}

/// Returns whether this element has been part of a restyle.
pub fn contains_restyle_data(&self) -> bool {
self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty()
}
}

Expand All @@ -382,9 +435,8 @@ pub struct ElementData {
/// The computed styles for the element and its pseudo-elements.
styles: Option<ElementStyles>,

/// Restyle tracking. We separate this into a separate allocation so that
/// we can drop it when no restyles are pending on the elemnt.
restyle: Option<Box<RestyleData>>,
/// Restyle state.
pub restyle: RestyleData,
}

/// The kind of restyle that a single element should do.
Expand All @@ -402,6 +454,14 @@ pub enum RestyleKind {
}

impl ElementData {
/// Borrows both styles and restyle mutably at the same time.
pub fn styles_and_restyle_mut(
&mut self
) -> (&mut ElementStyles, &mut RestyleData) {
(self.styles.as_mut().unwrap(),
&mut self.restyle)
}

/// Invalidates style for this element, its descendants, and later siblings,
/// based on the snapshot of the element that we took when attributes or
/// state changed.
Expand Down Expand Up @@ -437,7 +497,7 @@ impl ElementData {
pub fn new(existing: Option<ElementStyles>) -> Self {
ElementData {
styles: existing,
restyle: None,
restyle: RestyleData::new(),
}
}

Expand All @@ -448,7 +508,7 @@ impl ElementData {

/// Returns whether we have any outstanding style invalidation.
pub fn has_invalidations(&self) -> bool {
self.restyle.as_ref().map_or(false, |r| r.has_invalidations())
self.restyle.hint.has_self_invalidations()
}

/// Returns the kind of restyling that we're going to need to do on this
Expand All @@ -465,10 +525,7 @@ impl ElementData {
return RestyleKind::MatchAndCascade;
}

debug_assert!(self.restyle.is_some());
let restyle_data = self.restyle.as_ref().unwrap();

let hint = restyle_data.hint;
let hint = self.restyle.hint;
if shared_context.traversal_flags.for_animation_only() {
// return either CascadeWithReplacements or CascadeOnly in case of
// animation-only restyle.
Expand All @@ -488,7 +545,8 @@ impl ElementData {
return RestyleKind::CascadeWithReplacements(hint & RestyleHint::replacements());
}

debug_assert!(hint.has_recascade_self(), "We definitely need to do something!");
debug_assert!(hint.has_recascade_self(),
"We definitely need to do something!");
return RestyleKind::CascadeOnly;
}

Expand All @@ -513,13 +571,6 @@ impl ElementData {
self.styles.as_mut().expect("Calling styles_mut() on unstyled ElementData")
}

/// Borrows both styles and restyle mutably at the same time.
pub fn styles_and_restyle_mut(&mut self) -> (&mut ElementStyles,
Option<&mut RestyleData>) {
(self.styles.as_mut().unwrap(),
self.restyle.as_mut().map(|r| &mut **r))
}

/// Sets the computed element styles.
pub fn set_styles(&mut self, styles: ElementStyles) {
self.styles = Some(styles);
Expand Down Expand Up @@ -558,47 +609,9 @@ impl ElementData {
important_rules != other_important_rules
}

/// Returns true if the Element has a RestyleData.
pub fn has_restyle(&self) -> bool {
self.restyle.is_some()
}

/// Drops any RestyleData.
pub fn clear_restyle(&mut self) {
self.restyle = None;
}

/// Creates a RestyleData if one doesn't exist.
///
/// Asserts that the Element has been styled.
pub fn ensure_restyle(&mut self) -> &mut RestyleData {
debug_assert!(self.styles.is_some(), "restyling unstyled element");
if self.restyle.is_none() {
self.restyle = Some(Box::new(RestyleData::default()));
}
self.restyle.as_mut().unwrap()
}

/// Gets a reference to the restyle data, if any.
pub fn get_restyle(&self) -> Option<&RestyleData> {
self.restyle.as_ref().map(|r| &**r)
}

/// Gets a reference to the restyle data. Panic if the element does not
/// have restyle data.
pub fn restyle(&self) -> &RestyleData {
self.get_restyle().expect("Calling restyle without RestyleData")
}

/// Gets a mutable reference to the restyle data, if any.
pub fn get_restyle_mut(&mut self) -> Option<&mut RestyleData> {
self.restyle.as_mut().map(|r| &mut **r)
}

/// Gets a mutable reference to the restyle data. Panic if the element does
/// not have restyle data.
pub fn restyle_mut(&mut self) -> &mut RestyleData {
self.get_restyle_mut().expect("Calling restyle_mut without RestyleData")
/// Drops any restyle state from the element.
pub fn clear_restyle_state(&mut self) {
self.restyle.clear();
}

/// Returns SMIL overriden value if exists.
Expand Down
3 changes: 1 addition & 2 deletions components/style/dom.rs
Expand Up @@ -567,8 +567,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone +
Some(d) => d,
None => return false,
};
return data.get_restyle()
.map_or(false, |r| r.hint.has_animation_hint());
return data.restyle.hint.has_animation_hint()
}

/// Gets declarations from XBL bindings from the element. Only gecko element could have this.
Expand Down
12 changes: 5 additions & 7 deletions components/style/invalidation/element/invalidator.rs
Expand Up @@ -114,7 +114,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
// We can't just return here because there may also be attribute
// changes as well that imply additional hints.
let mut data = self.data.as_mut().unwrap();
data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree().into());
data.restyle.hint.insert(RestyleHint::restyle_subtree());
}

let mut classes_removed = SmallVec::<[Atom; 8]>::new();
Expand Down Expand Up @@ -211,7 +211,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>

if invalidated_self {
if let Some(ref mut data) = self.data {
data.ensure_restyle().hint.insert(RESTYLE_SELF.into());
data.restyle.hint.insert(RESTYLE_SELF);
}
}

Expand Down Expand Up @@ -287,10 +287,8 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
match self.data {
None => return false,
Some(ref data) => {
if let Some(restyle) = data.get_restyle() {
if restyle.hint.contains_subtree() {
return false;
}
if data.restyle.hint.contains_subtree() {
return false;
}
}
}
Expand Down Expand Up @@ -494,7 +492,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>

if invalidated_self {
if let Some(ref mut data) = self.data {
data.ensure_restyle().hint.insert(RESTYLE_SELF.into());
data.restyle.hint.insert(RESTYLE_SELF);
}
}

Expand Down
14 changes: 6 additions & 8 deletions components/style/invalidation/stylesheets.rs
Expand Up @@ -134,7 +134,7 @@ impl StylesheetInvalidationSet {
if self.fully_invalid {
debug!("process_invalidations: fully_invalid({:?})",
element);
data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
data.restyle.hint.insert(RestyleHint::restyle_subtree());
return true;
}
}
Expand Down Expand Up @@ -165,19 +165,17 @@ impl StylesheetInvalidationSet {
return false;
}

if let Some(ref r) = data.get_restyle() {
if r.hint.contains_subtree() {
debug!("process_invalidations_in_subtree: {:?} was already invalid",
element);
return false;
}
if data.restyle.hint.contains_subtree() {
debug!("process_invalidations_in_subtree: {:?} was already invalid",
element);
return false;
}

for scope in &self.invalid_scopes {
if scope.matches(element) {
debug!("process_invalidations_in_subtree: {:?} matched {:?}",
element, scope);
data.ensure_restyle().hint.insert(RestyleHint::restyle_subtree());
data.restyle.hint.insert(RestyleHint::restyle_subtree());
return true;
}
}
Expand Down

0 comments on commit ffc45e9

Please sign in to comment.