Bug 1352306 - Part 2: stylo: Only snapshot EventStates if there is some rule that depends on it. r=emilio
authorCameron McCormack <cam@mcc.id.au>
Tue, 09 May 2017 18:13:45 +0800
changeset 364580 064975f358bc7efe7a6da2fcb1583e0ba1f65698
parent 364579 cde7eed4820808907b2102cb177e7744d95bb804
child 364581 0eacbd673e5af7ecb45ff5037e5c8bd70e0537d8
push id32049
push usercbook@mozilla.com
push dateMon, 19 Jun 2017 11:36:23 +0000
treeherdermozilla-central@26d62a1ac0e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1352306
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1352306 - Part 2: stylo: Only snapshot EventStates if there is some rule that depends on it. r=emilio MozReview-Commit-ID: J5xhdi7pGSv
layout/base/ServoRestyleManager.cpp
layout/style/ServoBindingList.h
layout/style/ServoStyleSet.cpp
layout/style/ServoStyleSet.h
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -777,16 +777,26 @@ ServoRestyleManager::ContentStateChanged
   // vs processing the restyle hint in-place, dirtying the nodes on
   // PostRestyleEvent.
   //
   // If we definitely take the snapshot approach, we should take rid of
   // HasStateDependentStyle, etc (though right now they're no-ops).
   ContentStateChangedInternal(aElement, aChangedBits, &changeHint,
                               &restyleHint);
 
+  // Don't bother taking a snapshot if no rules depend on these state bits.
+  //
+  // We always take a snapshot for the LTR/RTL event states, since Servo doesn't
+  // track those bits in the same way, and we know that :dir() rules are always
+  // present in UA style sheets.
+  if (!aChangedBits.HasAtLeastOneOfStates(DIRECTION_STATES) &&
+      !StyleSet()->HasStateDependency(aChangedBits)) {
+    return;
+  }
+
   ServoElementSnapshot& snapshot = SnapshotFor(aElement);
   EventStates previousState = aElement->StyleState() ^ aChangedBits;
   snapshot.AddState(previousState);
 
   if (Element* parent = aElement->GetFlattenedTreeParentElementForStyle()) {
     parent->NoteDirtyDescendantsForServo();
   }
   PostRestyleEvent(aElement, restyleHint, changeHint);
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -94,16 +94,19 @@ SERVO_BINDING_FUNC(Servo_StyleSet_GetCou
 SERVO_BINDING_FUNC(Servo_StyleSet_ResolveForDeclarations,
                    ServoComputedValuesStrong,
                    RawServoStyleSetBorrowed set,
                    ServoComputedValuesBorrowedOrNull parent_style,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_StyleSet_MightHaveAttributeDependency, bool,
                    RawServoStyleSetBorrowed set,
                    nsIAtom* local_name)
+SERVO_BINDING_FUNC(Servo_StyleSet_HasStateDependency, bool,
+                   RawServoStyleSetBorrowed set,
+                   uint64_t state)
 
 // CSSRuleList
 SERVO_BINDING_FUNC(Servo_CssRules_ListTypes, void,
                    ServoCssRulesBorrowed rules,
                    nsTArrayBorrowed_uintptr_t result)
 SERVO_BINDING_FUNC(Servo_CssRules_InsertRule, nsresult,
                    ServoCssRulesBorrowed rules,
                    RawServoStyleSheetBorrowed sheet, const nsACString* rule,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -1357,9 +1357,15 @@ ServoStyleSet::RunPostTraversalTasks()
 }
 
 bool
 ServoStyleSet::MightHaveAttributeDependency(nsIAtom* aAttribute)
 {
   return Servo_StyleSet_MightHaveAttributeDependency(mRawSet.get(), aAttribute);
 }
 
+bool
+ServoStyleSet::HasStateDependency(EventStates aState)
+{
+  return Servo_StyleSet_HasStateDependency(mRawSet.get(), aState.ServoValue());
+}
+
 ServoStyleSet* ServoStyleSet::sInServoTraversal = nullptr;
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -437,16 +437,26 @@ public:
    * local name might require us to restyle the element.
    *
    * This function allows us to skip taking a an attribute snapshot when
    * the modified attribute doesn't appear in an attribute selector in
    * a style sheet.
    */
   bool MightHaveAttributeDependency(nsIAtom* aAttribute);
 
+  /**
+   * Returns true if a change in event state on an element might require
+   * us to restyle the element.
+   *
+   * This function allows us to skip taking a state snapshot when
+   * the changed state isn't depended upon by any pseudo-class selectors
+   * in a style sheet.
+   */
+  bool HasStateDependency(EventStates aState);
+
 private:
   // On construction, sets sInServoTraversal to the given ServoStyleSet.
   // On destruction, clears sInServoTraversal and calls RunPostTraversalTasks.
   class MOZ_STACK_CLASS AutoSetInServoTraversal
   {
   public:
     explicit AutoSetInServoTraversal(ServoStyleSet* aSet)
       : mSet(aSet)