Auto merge of #18465 - bholley:kill_restyledata, r=emilio

Eliminate RestyleData

https://bugzilla.mozilla.org/show_bug.cgi?id=1399011

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18465)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-09-12 13:16:26 -05:00 committed by GitHub
commit 72f0fda836
13 changed files with 160 additions and 199 deletions

View file

@ -77,7 +77,7 @@ impl<'a, E> DomTraversal<E> 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 {

View file

@ -146,7 +146,7 @@ impl<T: ThreadSafeLayoutNode> 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
}
};

View file

@ -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.

View file

@ -20,7 +20,8 @@ use std::fmt;
use std::ops::{Deref, DerefMut};
bitflags! {
flags RestyleFlags: u8 {
#[derive(Default)]
flags ElementDataFlags: u8 {
/// Whether the styles changed for this restyle.
const WAS_RESTYLED = 1 << 0,
/// Whether the last traversal of this element did not do
@ -37,119 +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 hint, which indicates whether selectors need to be rematched
/// for this element, its children, and its descendants.
pub hint: RestyleHint,
/// 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 Default for RestyleData {
fn default() -> Self {
Self::new()
}
}
impl RestyleData {
fn new() -> Self {
Self {
hint: RestyleHint::empty(),
flags: RestyleFlags::empty(),
damage: RestyleDamage::empty(),
}
}
/// Clear all the restyle state associated with this element.
///
/// FIXME(bholley): The only caller of this should probably just assert that
/// the hint is empty and call clear_flags_and_damage().
#[inline]
fn clear_restyle_state(&mut self) {
self.clear_restyle_flags_and_damage();
self.hint = RestyleHint::empty();
}
/// Clear restyle flags and damage.
///
/// Note that we don't touch the TRAVERSED_WITHOUT_STYLING bit, which gets
/// set to the correct value on each traversal. There's no reason anyone
/// needs to clear it, and clearing it accidentally mid-traversal could
/// cause incorrect style sharing behavior.
#[inline]
fn clear_restyle_flags_and_damage(&mut self) {
self.damage = RestyleDamage::empty();
self.flags = self.flags & TRAVERSED_WITHOUT_STYLING;
}
/// Returns whether this element or any ancestor is going to be
/// reconstructed.
pub fn reconstructed_self_or_ancestor(&self) -> bool {
self.reconstructed_ancestor() || self.reconstructed_self()
}
/// Returns whether this element is going to be reconstructed.
pub fn reconstructed_self(&self) -> bool {
self.damage.contains(RestyleDamage::reconstruct())
}
/// Returns whether any ancestor of this element is going to be
/// reconstructed.
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, reconstructed: bool) {
if reconstructed {
// If it weren't for animation-only traversals, we could assert
// `!self.reconstructed_ancestor()` here.
self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED);
} else {
self.flags.remove(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);
self.flags.remove(TRAVERSED_WITHOUT_STYLING);
}
/// Returns true if this element was restyled.
#[inline]
pub fn is_restyle(&self) -> bool {
self.flags.contains(WAS_RESTYLED)
}
/// Mark that we traversed this element without computing any style for it.
pub fn set_traversed_without_styling(&mut self) {
self.flags.insert(TRAVERSED_WITHOUT_STYLING);
}
/// Returns whether the element was traversed without computing any style for
/// it.
pub fn traversed_without_styling(&self) -> bool {
self.flags.contains(TRAVERSED_WITHOUT_STYLING)
}
/// Returns whether this element has been part of a restyle.
#[inline]
pub fn contains_restyle_data(&self) -> bool {
self.is_restyle() || !self.hint.is_empty() || !self.damage.is_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
@ -303,8 +191,16 @@ 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,
}
/// The kind of restyle that a single element should do.
@ -382,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;
}
@ -411,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;
@ -440,17 +334,94 @@ impl ElementData {
}
/// Drops any restyle state from the element.
///
/// FIXME(bholley): The only caller of this should probably just assert that
/// the hint is empty and call clear_flags_and_damage().
#[inline]
pub fn clear_restyle_state(&mut self) {
self.restyle.clear_restyle_state();
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.clear_restyle_flags_and_damage();
self.damage = RestyleDamage::empty();
self.flags.remove(WAS_RESTYLED | ANCESTOR_WAS_RECONSTRUCTED)
}
/// Returns whether this element or any ancestor is going to be
/// reconstructed.
pub fn reconstructed_self_or_ancestor(&self) -> bool {
self.reconstructed_ancestor() || self.reconstructed_self()
}
/// Returns whether this element is going to be reconstructed.
pub fn reconstructed_self(&self) -> bool {
self.damage.contains(RestyleDamage::reconstruct())
}
/// Returns whether any ancestor of this element is going to be
/// reconstructed.
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, reconstructed: bool) {
if reconstructed {
// If it weren't for animation-only traversals, we could assert
// `!self.reconstructed_ancestor()` here.
self.flags.insert(ANCESTOR_WAS_RECONSTRUCTED);
} else {
self.flags.remove(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);
self.flags.remove(TRAVERSED_WITHOUT_STYLING);
}
/// Returns true if this element was restyled.
#[inline]
pub fn is_restyle(&self) -> bool {
self.flags.contains(WAS_RESTYLED)
}
/// Mark that we traversed this element without computing any style for it.
pub fn set_traversed_without_styling(&mut self) {
self.flags.insert(TRAVERSED_WITHOUT_STYLING);
}
/// Returns whether the element was traversed without computing any style for
/// it.
pub fn traversed_without_styling(&self) -> bool {
self.flags.contains(TRAVERSED_WITHOUT_STYLING)
}
/// Returns whether this element has been part of a restyle.
#[inline]
pub fn contains_restyle_data(&self) -> bool {
self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty()
}
/// If an ancestor is already getting reconstructed by Gecko's top-down
/// frame constructor, no need to apply damage. Similarly if we already
/// have an explicitly stored ReconstructFrame hint.
///
/// See https://bugzilla.mozilla.org/show_bug.cgi?id=1301258#c12
/// for followup work to make the optimization here more optimal by considering
/// each bit individually.
#[cfg(feature = "gecko")]
pub fn skip_applying_damage(&self) -> bool { self.reconstructed_self_or_ancestor() }
/// N/A in Servo.
#[cfg(feature = "servo")]
pub fn skip_applying_damage(&self) -> bool { false }
/// Measures memory usage.
#[cfg(feature = "gecko")]
pub fn size_of_excluding_cvs(&self, ops: &mut MallocSizeOfOps) -> usize {

View file

@ -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,

View file

@ -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,19 +498,19 @@ 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 |
ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 |
NODE_DESCENDANTS_NEED_FRAMES as u32 |
NODE_NEEDS_FRAME as u32) != 0;
has_flag || self.borrow_data().unwrap().restyle.contains_restyle_data()
has_flag || self.borrow_data().unwrap().contains_restyle_data()
}
/// Returns true if this element has a shadow root.
@ -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)");
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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};
@ -352,10 +352,11 @@ trait PrivateMatchMethods: TElement {
fn accumulate_damage_for(
&self,
shared_context: &SharedStyleContext,
restyle: &mut RestyleData,
skip_applying_damage: bool,
damage: &mut RestyleDamage,
old_values: &ComputedValues,
new_values: &ComputedValues,
pseudo: Option<&PseudoElement>
pseudo: Option<&PseudoElement>,
) -> ChildCascadeRequirement {
debug!("accumulate_damage_for: {:?}", self);
@ -365,21 +366,11 @@ trait PrivateMatchMethods: TElement {
return ChildCascadeRequirement::MustCascadeChildren;
}
// If an ancestor is already getting reconstructed by Gecko's top-down
// frame constructor, no need to apply damage. Similarly if we already
// have an explicitly stored ReconstructFrame hint.
//
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1301258#c12
// for followup work to make the optimization here more optimal by considering
// each bit individually.
let skip_applying_damage =
cfg!(feature = "gecko") && restyle.reconstructed_self_or_ancestor();
let difference =
self.compute_style_difference(old_values, new_values, pseudo);
if !skip_applying_damage {
restyle.damage |= difference.damage;
*damage |= difference.damage;
}
debug!(" > style difference: {:?}", difference);
@ -552,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,
);
@ -615,7 +606,8 @@ pub trait MatchMethods : TElement {
cascade_requirement,
self.accumulate_damage_for(
context.shared,
&mut data.restyle,
data.skip_applying_damage(),
&mut data.damage,
&old_primary_style,
new_primary_style,
None,
@ -636,7 +628,8 @@ pub trait MatchMethods : TElement {
(&Some(ref old), &Some(ref new)) => {
self.accumulate_damage_for(
context.shared,
&mut data.restyle,
data.skip_applying_damage(),
&mut data.damage,
old,
new,
Some(&PseudoElement::from_eager_index(i)),
@ -656,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;
}
}

View file

@ -40,8 +40,7 @@ pub fn can_share_style_across_parents<E>(first: Option<E>, second: Option<E>) ->
//
// This is a somewhat conservative check. We could tighten it by having the
// invalidation logic explicitly flag elements for which it ellided styling.
if first_data.restyle.traversed_without_styling() ||
second_data.restyle.traversed_without_styling() {
if first_data.traversed_without_styling() || second_data.traversed_without_styling() {
return false;
}

View file

@ -161,7 +161,7 @@ pub trait DomTraversal<E: TElement> : Sync {
// the last traversal (at a potentially-higher root). From the
// perspective of this traversal, the root cannot have reconstructed
// ancestors.
data.restyle.set_reconstructed_ancestor(false);
data.set_reconstructed_ancestor(false);
};
let parent = root.traversal_parent();
@ -214,7 +214,7 @@ pub trait DomTraversal<E: TElement> : 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.
@ -244,7 +244,7 @@ pub trait DomTraversal<E: TElement> : Sync {
if el.is_native_anonymous() {
if let Some(parent_data) = parent_data {
let going_to_reframe =
parent_data.restyle.reconstructed_self_or_ancestor();
parent_data.reconstructed_self_or_ancestor();
let mut is_before_or_after_pseudo = false;
if let Some(pseudo) = el.implemented_pseudo_element() {
@ -283,14 +283,14 @@ pub trait DomTraversal<E: TElement> : 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;
}
@ -499,7 +499,7 @@ where
notify_paint_worklet(context, data);
} else {
debug_assert!(data.has_styles());
data.restyle.set_traversed_without_styling();
data.set_traversed_without_styling();
}
// Now that matching and cascading is done, clear the bits corresponding to
@ -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={:?}, \
@ -551,7 +551,7 @@ where
!propagated_hint.is_empty() ||
!child_cascade_requirement.can_skip_cascade() ||
context.thread_local.is_initial_style() ||
data.restyle.reconstructed_self() ||
data.reconstructed_self() ||
is_servo_nonincremental_layout();
traverse_children = traverse_children &&
@ -565,7 +565,7 @@ where
data,
propagated_hint,
child_cascade_requirement,
data.restyle.reconstructed_self_or_ancestor(),
data.reconstructed_self_or_ancestor(),
note_child
);
}
@ -631,7 +631,7 @@ where
debug!("compute_style: {:?} (kind={:?})", element, kind);
if data.has_styles() {
data.restyle.set_restyled();
data.set_restyled();
}
let mut important_rules_changed = false;
@ -804,14 +804,14 @@ 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());
if let Some(ref mut child_data) = child_data {
// Propagate the parent restyle hint, that may make us restyle the whole
// subtree.
child_data.restyle.set_reconstructed_ancestor(reconstructed_ancestor);
child_data.set_reconstructed_ancestor(reconstructed_ancestor);
let mut child_hint = propagated_hint;
match cascade_requirement {
@ -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.

View file

@ -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()
}
@ -2980,9 +2980,9 @@ pub extern "C" fn Servo_TakeChangeHint(element: RawGeckoElementBorrowed,
let damage = match element.mutate_data() {
Some(mut data) => {
*was_restyled = data.restyle.is_restyle();
*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;
}
}

View file

@ -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<Arc<ComputedValues>>, 8);
size_of_test!(test_size_of_option_rule_node, Option<StrongRuleNode>, 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);