diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 48bfc107797..077e43fb45c 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -77,7 +77,7 @@ impl<'a, E> DomTraversal for RecalcStyleAndConstructFlows<'a> // (1) They child doesn't yet have layout data (preorder traversal initializes it). // (2) The parent element has restyle damage (so the text flow also needs fixup). node.get_raw_data().is_none() || - parent_data.restyle.damage != RestyleDamage::empty() + parent_data.damage != RestyleDamage::empty() } fn shared_context(&self) -> &SharedStyleContext { diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 2a31e17cfa1..6abe08748b4 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -146,7 +146,7 @@ impl ThreadSafeLayoutNodeHelpers for T { // because that's what the code expects. RestyleDamage::rebuild_and_reflow() } else { - data.style_data.element_data.borrow().restyle.damage + data.style_data.element_data.borrow().damage } }; diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index d8529b57a54..cd9bf1ac29b 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -1168,7 +1168,7 @@ impl LayoutThread { } if had_used_viewport_units { if let Some(mut data) = element.mutate_data() { - data.restyle.hint.insert(RestyleHint::recascade_subtree()); + data.hint.insert(RestyleHint::recascade_subtree()); } } } @@ -1250,9 +1250,9 @@ impl LayoutThread { let mut style_data = style_data.borrow_mut(); // Stash the data on the element for processing by the style system. - style_data.restyle.hint.insert(restyle.hint.into()); - style_data.restyle.damage = restyle.damage; - debug!("Noting restyle for {:?}: {:?}", el, style_data.restyle); + style_data.hint.insert(restyle.hint.into()); + style_data.damage = restyle.damage; + debug!("Noting restyle for {:?}: {:?}", el, style_data); } // Create a layout context for use throughout the following passes. diff --git a/components/style/data.rs b/components/style/data.rs index 132597d64db..006f0593c76 100644 --- a/components/style/data.rs +++ b/components/style/data.rs @@ -38,35 +38,6 @@ bitflags! { } } -/// 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)] -pub struct RestyleData { - /// The restyle damage, indicating what kind of layout changes are required - /// afte restyling. - pub damage: RestyleDamage, - - /// The restyle hint, which indicates whether selectors need to be rematched - /// for this element, its children, and its descendants. - pub hint: RestyleHint, -} - -impl Default for RestyleData { - fn default() -> Self { - Self::new() - } -} - -impl RestyleData { - fn new() -> Self { - Self { - damage: RestyleDamage::empty(), - hint: RestyleHint::empty(), - } - } -} - /// A lazily-allocated list of styles for eagerly-cascaded pseudo-elements. /// /// We use an Arc so that sharing these styles via the style sharing cache does @@ -220,8 +191,13 @@ pub struct ElementData { /// The styles for the element and its pseudo-elements. pub styles: ElementStyles, - /// Restyle state. - pub restyle: RestyleData, + /// The restyle damage, indicating what kind of layout changes are required + /// afte restyling. + pub damage: RestyleDamage, + + /// The restyle hint, which indicates whether selectors need to be rematched + /// for this element, its children, and its descendants. + pub hint: RestyleHint, /// Flags. flags: ElementDataFlags, @@ -302,19 +278,18 @@ impl ElementData { return RestyleKind::MatchAndCascade; } - let hint = self.restyle.hint; - if hint.match_self() { + if self.hint.match_self() { return RestyleKind::MatchAndCascade; } - if hint.has_replacements() { - debug_assert!(!hint.has_animation_hint(), + if self.hint.has_replacements() { + debug_assert!(!self.hint.has_animation_hint(), "Animation only restyle hint should have already processed"); - return RestyleKind::CascadeWithReplacements(hint & RestyleHint::replacements()); + return RestyleKind::CascadeWithReplacements(self.hint & RestyleHint::replacements()); } - debug_assert!(hint.has_recascade_self(), - "We definitely need to do something: {:?}!", hint); + debug_assert!(self.hint.has_recascade_self(), + "We definitely need to do something: {:?}!", self.hint); return RestyleKind::CascadeOnly; } @@ -331,9 +306,8 @@ impl ElementData { // return either CascadeWithReplacements or CascadeOnly in case of // animation-only restyle. I.e. animation-only restyle never does // selector matching. - let hint = self.restyle.hint; - if hint.has_animation_hint() { - return RestyleKind::CascadeWithReplacements(hint & RestyleHint::for_animations()); + if self.hint.has_animation_hint() { + return RestyleKind::CascadeWithReplacements(self.hint & RestyleHint::for_animations()); } return RestyleKind::CascadeOnly; @@ -365,14 +339,14 @@ impl ElementData { /// the hint is empty and call clear_flags_and_damage(). #[inline] pub fn clear_restyle_state(&mut self) { - self.restyle.hint = RestyleHint::empty(); + self.hint = RestyleHint::empty(); self.clear_restyle_flags_and_damage(); } /// Drops restyle flags and damage from the element. #[inline] pub fn clear_restyle_flags_and_damage(&mut self) { - self.restyle.damage = RestyleDamage::empty(); + self.damage = RestyleDamage::empty(); self.flags.remove(WAS_RESTYLED | ANCESTOR_WAS_RECONSTRUCTED) } @@ -384,7 +358,7 @@ impl ElementData { /// Returns whether this element is going to be reconstructed. pub fn reconstructed_self(&self) -> bool { - self.restyle.damage.contains(RestyleDamage::reconstruct()) + self.damage.contains(RestyleDamage::reconstruct()) } /// Returns whether any ancestor of this element is going to be @@ -431,7 +405,7 @@ impl ElementData { /// Returns whether this element has been part of a restyle. #[inline] pub fn contains_restyle_data(&self) -> bool { - self.is_restyle() || !self.restyle.hint.is_empty() || !self.restyle.damage.is_empty() + self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty() } /// If an ancestor is already getting reconstructed by Gecko's top-down diff --git a/components/style/dom.rs b/components/style/dom.rs index c1ea477960a..6a07c84cdbe 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -436,7 +436,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + // animation in a SequentialTask) is processed after the normal // traversal in that we had elements that handled snapshot. return data.has_styles() && - !data.restyle.hint.has_animation_hint_or_recascade(); + !data.hint.has_animation_hint_or_recascade(); } if traversal_flags.contains(traversal_flags::UnstyledOnly) { @@ -448,7 +448,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + return false; } - data.has_styles() && !data.restyle.hint.has_non_animation_invalidations() + data.has_styles() && !data.hint.has_non_animation_invalidations() } /// Returns whether the element's styles are up-to-date after traversal @@ -470,7 +470,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + // // https://bugzilla.mozilla.org/show_bug.cgi?id=1389675 tracks fixing // this. - !data.restyle.hint.has_non_animation_invalidations() + !data.hint.has_non_animation_invalidations() } /// Flag that this element has a descendant for style processing. @@ -620,7 +620,7 @@ pub trait TElement : Eq + PartialEq + Debug + Hash + Sized + Copy + Clone + Some(d) => d, None => return false, }; - return data.restyle.hint.has_animation_hint() + return data.hint.has_animation_hint() } /// Returns the anonymous content for the current element's XBL binding, diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 8ab602aa418..6c0e666abca 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -19,7 +19,7 @@ use app_units::Au; use applicable_declarations::ApplicableDeclarationBlock; use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use context::{QuirksMode, SharedStyleContext, PostAnimationTasks, UpdateAnimationsTasks}; -use data::{ElementData, RestyleData}; +use data::ElementData; use dom::{LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode}; use dom::{OpaqueNode, PresentationalHintsSynthesizer}; use element_state::{ElementState, DocumentState, NS_DOCUMENT_STATE_WINDOW_INACTIVE}; @@ -498,12 +498,12 @@ impl<'le> GeckoElement<'le> { /// Returns true if a traversal starting from this element requires a post-traversal. pub fn needs_post_traversal(&self) -> bool { - debug!("needs_post_traversal: dd={}, aodd={}, lfcd={}, lfc={}, restyle={:?}", + debug!("needs_post_traversal: dd={}, aodd={}, lfcd={}, lfc={}, data={:?}", self.has_dirty_descendants(), self.has_animation_only_dirty_descendants(), self.descendants_need_frames(), self.needs_frame(), - self.borrow_data().unwrap().restyle); + self.borrow_data().unwrap()); let has_flag = self.flags() & (ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 | @@ -688,10 +688,9 @@ impl<'le> GeckoElement<'le> { /// Also this function schedules style flush. unsafe fn maybe_restyle<'a>(&self, data: &'a mut ElementData, - animation_only: bool) -> Option<&'a mut RestyleData> { - // Don't generate a useless RestyleData if the element hasn't been styled. + animation_only: bool) -> bool { if !data.has_styles() { - return None; + return false; } // Propagate the bit up the chain. @@ -702,7 +701,7 @@ impl<'le> GeckoElement<'le> { } // Ensure and return the RestyleData. - Some(&mut data.restyle) + true } /// Set restyle and change hints to the element data. @@ -722,12 +721,12 @@ impl<'le> GeckoElement<'le> { "Animation restyle hints should not appear with non-animation restyle hints"); let mut maybe_data = self.mutate_data(); - let maybe_restyle_data = maybe_data.as_mut().and_then(|d| unsafe { + let should_restyle = maybe_data.as_mut().map_or(false, |d| unsafe { self.maybe_restyle(d, restyle_hint.has_animation_hint()) }); - if let Some(restyle_data) = maybe_restyle_data { - restyle_data.hint.insert(restyle_hint.into()); - restyle_data.damage |= damage; + if should_restyle { + maybe_data.as_mut().unwrap().hint.insert(restyle_hint.into()); + maybe_data.as_mut().unwrap().damage |= damage; } else { debug!("(Element not styled, discarding hints)"); } diff --git a/components/style/invalidation/element/invalidator.rs b/components/style/invalidation/element/invalidator.rs index be87815add0..5338bf22e3a 100644 --- a/components/style/invalidation/element/invalidator.rs +++ b/components/style/invalidation/element/invalidator.rs @@ -209,7 +209,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 data = self.data.as_mut().unwrap(); - data.restyle.hint.insert(RestyleHint::restyle_subtree()); + data.hint.insert(RestyleHint::restyle_subtree()); } let mut classes_removed = SmallVec::<[Atom; 8]>::new(); @@ -287,7 +287,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> if invalidated_self { if let Some(ref mut data) = self.data { - data.restyle.hint.insert(RESTYLE_SELF); + data.hint.insert(RESTYLE_SELF); } } @@ -499,7 +499,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> Some(ref data) => { // FIXME(emilio): Only needs to check RESTYLE_DESCENDANTS, // really. - if data.restyle.hint.contains_subtree() { + if data.hint.contains_subtree() { return false; } } @@ -507,7 +507,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> if let Some(checker) = self.stack_limit_checker { if checker.limit_exceeded() { - self.data.as_mut().unwrap().restyle.hint.insert(RESTYLE_DESCENDANTS); + self.data.as_mut().unwrap().hint.insert(RESTYLE_DESCENDANTS); return true; } } @@ -799,7 +799,7 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E> if invalidated_self { if let Some(ref mut data) = self.data { - data.restyle.hint.insert(RESTYLE_SELF); + data.hint.insert(RESTYLE_SELF); } } diff --git a/components/style/invalidation/stylesheets.rs b/components/style/invalidation/stylesheets.rs index 5a2fa8c1e0a..7d9af116ae1 100644 --- a/components/style/invalidation/stylesheets.rs +++ b/components/style/invalidation/stylesheets.rs @@ -148,7 +148,7 @@ impl StylesheetInvalidationSet { if self.fully_invalid { debug!("process_invalidations: fully_invalid({:?})", element); - data.restyle.hint.insert(RestyleHint::restyle_subtree()); + data.hint.insert(RestyleHint::restyle_subtree()); return true; } } @@ -179,7 +179,7 @@ impl StylesheetInvalidationSet { return false; } - if data.restyle.hint.contains_subtree() { + if data.hint.contains_subtree() { debug!("process_invalidations_in_subtree: {:?} was already invalid", element); return false; @@ -189,7 +189,7 @@ impl StylesheetInvalidationSet { if scope.matches(element) { debug!("process_invalidations_in_subtree: {:?} matched {:?}", element, scope); - data.restyle.hint.insert(RestyleHint::restyle_subtree()); + data.hint.insert(RestyleHint::restyle_subtree()); return true; } } diff --git a/components/style/matching.rs b/components/style/matching.rs index 4c16d81c59a..cbef380f40b 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -8,7 +8,7 @@ #![deny(missing_docs)] use context::{ElementCascadeInputs, SelectorFlagsMap, SharedStyleContext, StyleContext}; -use data::{ElementData, ElementStyles, RestyleData}; +use data::{ElementData, ElementStyles}; use dom::TElement; use invalidation::element::restyle_hints::{RESTYLE_CSS_ANIMATIONS, RESTYLE_CSS_TRANSITIONS}; use invalidation::element::restyle_hints::{RESTYLE_SMIL, RESTYLE_STYLE_ATTRIBUTE}; @@ -353,7 +353,7 @@ trait PrivateMatchMethods: TElement { &self, shared_context: &SharedStyleContext, skip_applying_damage: bool, - restyle: &mut RestyleData, + damage: &mut RestyleDamage, old_values: &ComputedValues, new_values: &ComputedValues, pseudo: Option<&PseudoElement>, @@ -370,7 +370,7 @@ trait PrivateMatchMethods: TElement { self.compute_style_difference(old_values, new_values, pseudo); if !skip_applying_damage { - restyle.damage |= difference.damage; + *damage |= difference.damage; } debug!(" > style difference: {:?}", difference); @@ -543,7 +543,7 @@ pub trait MatchMethods : TElement { context, &mut data.styles.primary, &mut new_styles.primary.as_mut().unwrap(), - data.restyle.hint, + data.hint, important_rules_changed, ); @@ -607,7 +607,7 @@ pub trait MatchMethods : TElement { self.accumulate_damage_for( context.shared, data.skip_applying_damage(), - &mut data.restyle, + &mut data.damage, &old_primary_style, new_primary_style, None, @@ -629,7 +629,7 @@ pub trait MatchMethods : TElement { self.accumulate_damage_for( context.shared, data.skip_applying_damage(), - &mut data.restyle, + &mut data.damage, old, new, Some(&PseudoElement::from_eager_index(i)), @@ -649,7 +649,7 @@ pub trait MatchMethods : TElement { old.as_ref().map_or(false, |s| pseudo.should_exist(s)); if new_pseudo_should_exist != old_pseudo_should_exist { - data.restyle.damage |= RestyleDamage::reconstruct(); + data.damage |= RestyleDamage::reconstruct(); return cascade_requirement; } } diff --git a/components/style/traversal.rs b/components/style/traversal.rs index db4303226ac..fdab3ab73c6 100644 --- a/components/style/traversal.rs +++ b/components/style/traversal.rs @@ -214,7 +214,7 @@ pub trait DomTraversal : Sync { if traversal_flags.for_animation_only() { return data.map_or(false, |d| d.has_styles()) && (el.has_animation_only_dirty_descendants() || - data.as_ref().unwrap().restyle.hint.has_animation_hint_or_recascade()); + data.as_ref().unwrap().hint.has_animation_hint_or_recascade()); } // Non-incremental layout visits every node. @@ -283,14 +283,14 @@ pub trait DomTraversal : Sync { // since that can return true even if we have a restyle hint indicating // that the element's descendants (but not necessarily the element) need // restyling. - if !data.restyle.hint.is_empty() { + if !data.hint.is_empty() { return true; } // Servo uses the post-order traversal for flow construction, so we need // to traverse any element with damage so that we can perform fixup / // reconstruction on our way back up the tree. - if cfg!(feature = "servo") && !data.restyle.damage.is_empty() { + if cfg!(feature = "servo") && !data.damage.is_empty() { return true; } @@ -510,10 +510,10 @@ where RestyleHint::empty() } else { debug_assert!(flags.for_animation_only() || - !data.restyle.hint.has_animation_hint(), + !data.hint.has_animation_hint(), "animation restyle hint should be handled during \ animation-only restyles"); - data.restyle.hint.propagate(&flags) + data.hint.propagate(&flags) }; trace!("propagated_hint={:?}, cascade_requirement={:?}, \ @@ -804,7 +804,7 @@ where let mut child_data = child_data.as_mut().map(|d| &mut **d); trace!(" > {:?} -> {:?} + {:?}, pseudo: {:?}", child, - child_data.as_ref().map(|d| d.restyle.hint), + child_data.as_ref().map(|d| d.hint), propagated_hint, child.implemented_pseudo_element()); @@ -830,7 +830,7 @@ where } } - child_data.restyle.hint.insert(child_hint); + child_data.hint.insert(child_hint); // Handle element snapshots and invalidation of descendants and siblings // as needed. diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 844940ded06..28a2bec6bd4 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -292,12 +292,12 @@ pub extern "C" fn Servo_TraverseSubtree( traversal_flags, unsafe { &*snapshots }); - debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, lfcd={}, lfc={}, restyle={:?})", + debug!("Servo_TraverseSubtree complete (dd={}, aodd={}, lfcd={}, lfc={}, data={:?})", element.has_dirty_descendants(), element.has_animation_only_dirty_descendants(), element.descendants_need_frames(), element.needs_frame(), - element.borrow_data().unwrap().restyle); + element.borrow_data().unwrap()); element.needs_post_traversal() } @@ -2982,7 +2982,7 @@ pub extern "C" fn Servo_TakeChangeHint(element: RawGeckoElementBorrowed, Some(mut data) => { *was_restyled = data.is_restyle(); - let damage = data.restyle.damage; + let damage = data.damage; data.clear_restyle_state(); damage } @@ -3859,7 +3859,7 @@ pub extern "C" fn Servo_HasPendingRestyleAncestor(element: RawGeckoElementBorrow let mut element = Some(GeckoElement(element)); while let Some(e) = element { if let Some(data) = e.borrow_data() { - if !data.restyle.hint.is_empty() { + if !data.hint.is_empty() { return true; } } diff --git a/tests/unit/stylo/size_of.rs b/tests/unit/stylo/size_of.rs index df415cfca11..4a05b25ada3 100644 --- a/tests/unit/stylo/size_of.rs +++ b/tests/unit/stylo/size_of.rs @@ -7,7 +7,7 @@ use servo_arc::Arc; use std::mem::{size_of, align_of}; use style; use style::applicable_declarations::ApplicableDeclarationBlock; -use style::data::{ElementData, ElementStyles, RestyleData}; +use style::data::{ElementData, ElementStyles}; use style::gecko::selector_parser as real; use style::properties::ComputedValues; use style::rule_tree::{RuleNode, StrongRuleNode}; @@ -38,7 +38,6 @@ size_of_test!(test_size_of_option_arc_cv, Option>, 8); size_of_test!(test_size_of_option_rule_node, Option, 8); size_of_test!(test_size_of_element_styles, ElementStyles, 16); -size_of_test!(test_size_of_restyle_data, RestyleData, 8); size_of_test!(test_size_of_element_data, ElementData, 24); size_of_test!(test_size_of_property_declaration, style::properties::PropertyDeclaration, 32);