Bug 1372335 - Don't process RestyleKind::MatchAndCascade during animation-only restyle. r?emilio draft
authorHiroyuki Ikezoe <hikezoe@mozilla.com>
Wed, 14 Jun 2017 06:36:10 +0900
changeset 593587 bad4cc37976f8e446376ccec4cbfbc128892be72
parent 593475 91134c95d68cbcfe984211fa3cbd28d610361ef1
child 593588 3437870bfc9581c5a89778be9086878e372d18b2
push id63746
push userhikezoe@mozilla.com
push dateTue, 13 Jun 2017 21:57:46 +0000
reviewersemilio
bugs1372335
milestone56.0a1
Bug 1372335 - Don't process RestyleKind::MatchAndCascade during animation-only restyle. r?emilio MozReview-Commit-ID: FzgU4lqlTrk
servo/components/style/data.rs
servo/components/style/traversal.rs
--- a/servo/components/style/data.rs
+++ b/servo/components/style/data.rs
@@ -522,16 +522,17 @@ pub struct ElementData {
     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>>,
 }
 
 /// The kind of restyle that a single element should do.
+#[derive(Debug)]
 pub enum RestyleKind {
     /// We need to run selector matching plus re-cascade, that is, a full
     /// restyle.
     MatchAndCascade,
     /// We need to recascade with some replacement rule, such as the style
     /// attribute, or animation rules.
     CascadeWithReplacements(RestyleReplacements),
     /// We only need to recascade, for example, because only inherited
@@ -611,32 +612,48 @@ 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())
     }
 
     /// Returns the kind of restyling that we're going to need to do on this
     /// element, based of the stored restyle hint.
-    pub fn restyle_kind(&self) -> RestyleKind {
+    pub fn restyle_kind(&self,
+                        shared_context: &SharedStyleContext)
+                        -> RestyleKind {
         debug_assert!(!self.has_styles() || self.has_invalidations(),
                       "Should've stopped earlier");
         if !self.has_styles() {
+            debug_assert!(!shared_context.traversal_flags.for_animation_only(),
+                          "Unstyled element shouldn't be traversed during \
+                           animation-only traversal");
             return RestyleKind::MatchAndCascade;
         }
 
         debug_assert!(self.restyle.is_some());
         let restyle_data = self.restyle.as_ref().unwrap();
+        let hint = &restyle_data.hint.0;
 
-        let hint = &restyle_data.hint.0;
+        if shared_context.traversal_flags.for_animation_only() {
+            // return either CascadeWithReplacements or CascadeOnly in case of
+            // animation-only restyle.
+            if hint.has_animation_hint() {
+                return RestyleKind::CascadeWithReplacements(hint.replacements);
+            }
+            return RestyleKind::CascadeOnly;
+        }
+
         if hint.match_self() {
             return RestyleKind::MatchAndCascade;
         }
 
         if hint.has_replacements() {
+            debug_assert!(!hint.has_animation_hint(),
+                          "Animation only restyle hint should have already processed");
             return RestyleKind::CascadeWithReplacements(hint.replacements);
         }
 
         debug_assert!(hint.has_recascade_self(), "We definitely need to do something!");
         return RestyleKind::CascadeOnly;
     }
 
     /// Gets the element styles, if any.
--- a/servo/components/style/traversal.rs
+++ b/servo/components/style/traversal.rs
@@ -798,20 +798,25 @@ fn compute_style<E, D>(_traversal: &D,
                        -> ChildCascadeRequirement
     where E: TElement,
           D: DomTraversal<E>,
 {
     use data::RestyleKind::*;
     use sharing::StyleSharingResult::*;
 
     context.thread_local.statistics.elements_styled += 1;
-    let kind = data.restyle_kind();
+    let kind = data.restyle_kind(context.shared);
+
+    debug!("compute_style: {:?} (kind={:?})", element, kind);
 
     match kind {
         MatchAndCascade => {
+            debug_assert!(!context.shared.traversal_flags.for_animation_only(),
+                          "MatchAndCascade shouldn't be processed during \
+                           animation-only traversal");
             // Ensure the bloom filter is up to date.
             context.thread_local.bloom_filter
                    .insert_parents_recovering(element,
                                               traversal_data.current_dom_depth);
 
             context.thread_local.bloom_filter.assert_complete(element);
 
             // Now that our bloom filter is set up, try the style sharing