From d9e8756c6cc9c384f609a235e906fc2f5a9d46c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 27 Mar 2017 16:08:09 -0700 Subject: [PATCH] servo: Merge #16148 - style: Cleanup a bit the restyle hint propagation code (from emilio:cleanup-animation-only-restyle); r=hiikezoe Source-Repo: https://github.com/servo/servo Source-Revision: 0ebb9ec9e82d7985c477ee71e55f56ab5facedc9 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : 9f045c772cdb0bcbb3a6dd5ff714491e49871e93 --- servo/components/style/data.rs | 26 ++++++++-------- servo/components/style/traversal.rs | 48 +++++++++++++++++------------ 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/servo/components/style/data.rs b/servo/components/style/data.rs index 5f714fcf99d3..a5a1e1712cb1 100644 --- a/servo/components/style/data.rs +++ b/servo/components/style/data.rs @@ -135,13 +135,20 @@ pub struct StoredRestyleHint(RestyleHint); impl StoredRestyleHint { /// Propagates this restyle hint to a child element. - pub fn propagate(&self) -> Self { - // If we have RESTYLE_CSS_ANIMATIONS restyle hint, it means we are in the - // middle of an animation only restyle. In that case, we don't need to - // propagate any restyle hints. - StoredRestyleHint(if self.0.contains(RESTYLE_CSS_ANIMATIONS) { - RestyleHint::empty() - } else if self.0.contains(RESTYLE_DESCENDANTS) { + pub fn propagate(&mut self) -> Self { + use std::mem; + + // If we have RESTYLE_CSS_ANIMATIONS restyle hint, it means we are in + // the middle of an animation only restyle. In that case, we don't need + // to propagate any restyle hints, and we need to remove ourselves. + if self.0.contains(RESTYLE_CSS_ANIMATIONS) { + self.0.remove(RESTYLE_CSS_ANIMATIONS); + return Self::empty(); + } + + // Else we should clear ourselves, and return the propagated hint. + let hint = mem::replace(&mut self.0, RestyleHint::empty()); + StoredRestyleHint(if hint.contains(RESTYLE_DESCENDANTS) { RESTYLE_SELF | RESTYLE_DESCENDANTS } else { RestyleHint::empty() @@ -180,11 +187,6 @@ impl StoredRestyleHint { self.0 |= other.0 } - /// Remove animation restyle hint. - pub fn remove_animation_hint(&mut self) { - self.0.remove(RESTYLE_CSS_ANIMATIONS) - } - /// Returns true if the hint has animation-only restyle. pub fn has_animation_hint(&self) -> bool { self.0.contains(RESTYLE_CSS_ANIMATIONS) diff --git a/servo/components/style/traversal.rs b/servo/components/style/traversal.rs index df70c29664cd..10cbe8b7fbd1 100644 --- a/servo/components/style/traversal.rs +++ b/servo/components/style/traversal.rs @@ -15,7 +15,6 @@ use restyle_hints::{RESTYLE_DESCENDANTS, RESTYLE_SELF}; use selector_parser::RestyleDamage; use servo_config::opts; use std::borrow::BorrowMut; -use std::mem; use stylist::Stylist; /// A per-traversal-level chunk of data. This is sent down by the traversal, and @@ -484,37 +483,46 @@ pub fn recalc_style_at(traversal: &D, // Now that matching and cascading is done, clear the bits corresponding to // those operations and compute the propagated restyle hint. - let empty_hint = StoredRestyleHint::empty(); let propagated_hint = match data.get_restyle_mut() { - None => empty_hint, + None => StoredRestyleHint::empty(), Some(r) => { + debug_assert!(context.shared.animation_only_restyle || + !r.hint.has_animation_hint(), + "animation restyle hint should be handled during \ + animation-only restyles"); r.recascade = false; - if r.hint.has_animation_hint() { - debug_assert!(context.shared.animation_only_restyle, - "animation restyle hint should be handled during animation-only restyles"); - // Drop animation restyle hint. - let propagated_hint = r.hint.propagate(); - r.hint.remove_animation_hint(); - propagated_hint - } else { - mem::replace(&mut r.hint, empty_hint).propagate() - } + r.hint.propagate() }, }; debug_assert!(data.has_current_styles() || context.shared.animation_only_restyle, "Should have computed style or haven't yet valid computed style in case of animation-only restyle"); - trace!("propagated_hint={:?}, inherited_style_changed={:?}", propagated_hint, inherited_style_changed); + trace!("propagated_hint={:?}, inherited_style_changed={:?}", + propagated_hint, inherited_style_changed); + + let has_dirty_descendants_for_this_restyle = + if context.shared.animation_only_restyle { + element.has_animation_only_dirty_descendants() + } else { + element.has_dirty_descendants() + }; // Preprocess children, propagating restyle hints and handling sibling relationships. - if traversal.should_traverse_children(&mut context.thread_local, element, &data, DontLog) && - ((!context.shared.animation_only_restyle && element.has_dirty_descendants()) || - (context.shared.animation_only_restyle && element.has_animation_only_dirty_descendants()) || - !propagated_hint.is_empty() || - inherited_style_changed) { + if traversal.should_traverse_children(&mut context.thread_local, + element, + &data, + DontLog) && + (has_dirty_descendants_for_this_restyle || + !propagated_hint.is_empty() || + inherited_style_changed) { let damage_handled = data.get_restyle().map_or(RestyleDamage::empty(), |r| { r.damage_handled() | r.damage.handled_for_descendants() }); - preprocess_children(traversal, element, propagated_hint, damage_handled, inherited_style_changed); + + preprocess_children(traversal, + element, + propagated_hint, + damage_handled, + inherited_style_changed); } if context.shared.animation_only_restyle {