Bug 1352306 - Part 2: stylo: Only snapshot EventStates if there is some rule that depends on it. r=emilio
MozReview-Commit-ID: J5xhdi7pGSv
--- 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)