Bug 1289868 - Part 2: stylo: Compare all structs in CalcStyleDifference so that Servo can accurately determine whether to stop traversal. r=emilio
MozReview-Commit-ID: I0WK2gDsMMu
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -1027,30 +1027,49 @@ nsStyleContext::CalcStyleDifferenceInter
*aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
}
} else {
*aEqualStructs |= NS_STYLE_INHERIT_BIT(Variables);
}
DebugOnly<int> styleStructCount = 1; // count Variables already
+ // Servo's optimization to stop the cascade when there are no style changes
+ // that children need to be recascade for relies on comparing all of the
+ // structs, not just those that are returned from PeekStyleData, although
+ // if PeekStyleData does return null we still don't want to accumulate
+ // any change hints for those structs.
+ bool checkUnrequestedServoStructs = mSource.IsServoComputedValues();
+
#define DO_STRUCT_DIFFERENCE(struct_) \
PR_BEGIN_MACRO \
const nsStyle##struct_* this##struct_ = PeekStyle##struct_(); \
+ bool unrequestedStruct; \
if (this##struct_) { \
+ unrequestedStruct = false; \
structsFound |= NS_STYLE_INHERIT_BIT(struct_); \
+ } else if (checkUnrequestedServoStructs) { \
+ this##struct_ = \
+ Servo_GetStyle##struct_(mSource.AsServoComputedValues()); \
+ unrequestedStruct = true; \
+ } else { \
+ unrequestedStruct = false; \
+ } \
+ if (this##struct_) { \
const nsStyle##struct_* other##struct_ = aNewContext->Style##struct_(); \
if (this##struct_ == other##struct_) { \
/* The very same struct, so we know that there will be no */ \
/* differences. */ \
*aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_); \
} else { \
nsChangeHint difference = \
this##struct_->CalcDifference(*other##struct_ EXTRA_DIFF_ARGS); \
- hint |= difference; \
+ if (!unrequestedStruct) { \
+ hint |= difference; \
+ } \
if (!difference) { \
*aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_); \
} \
} \
} else { \
*aEqualStructs |= NS_STYLE_INHERIT_BIT(struct_); \
} \
styleStructCount++; \