Bug 1382078 Part 4 - Avoid unneeded restyle when XBL styleset is utilized by different PresContext.
This fixed layout/style/test/test_media_queries_dynamic.html after Part 3 is added.
MozReview-Commit-ID: 7ZpSunCnkIc
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -750,17 +750,17 @@ nsBindingManager::MediumFeaturesChanged(
EnumerateBoundContentBindings([=, &rulesChanged](nsXBLBinding* aBinding) {
if (isStyledByServo) {
ServoStyleSet* styleSet = aBinding->PrototypeBinding()->GetServoStyleSet();
if (styleSet) {
bool styleSetChanged = false;
if (styleSet->IsPresContextChanged(presContext)) {
- styleSetChanged = true;
+ styleSetChanged = styleSet->SetPresContext(presContext);
} else {
// PresContext is not changed. This means aPresContext is still
// alive since the last time it initialized this XBL styleset.
// It's safe to check whether medium features changed.
bool viewportUnitsUsed = false;
styleSetChanged =
styleSet->MediumFeaturesChangedRules(&viewportUnitsUsed);
MOZ_ASSERT(!viewportUnitsUsed,
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -69,16 +69,21 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_GetO
SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSet*, RawGeckoPresContextOwned pres_context)
SERVO_BINDING_FUNC(Servo_StyleSet_RebuildCachedData, void,
RawServoStyleSetBorrowed set)
// We'd like to return `OriginFlags` here, but bindgen bitfield enums don't
// work as return values with the Linux 32-bit ABI at the moment because
// they wrap the value in a struct.
SERVO_BINDING_FUNC(Servo_StyleSet_MediumFeaturesChanged, uint8_t,
RawServoStyleSetBorrowed set, bool* viewport_units_used)
+// We'd like to return `OriginFlags` here, but bindgen bitfield enums don't
+// work as return values with the Linux 32-bit ABI at the moment because
+// they wrap the value in a struct.
+SERVO_BINDING_FUNC(Servo_StyleSet_SetDevice, uint8_t,
+ RawServoStyleSetBorrowed set, RawGeckoPresContextOwned pres_context)
SERVO_BINDING_FUNC(Servo_StyleSet_Drop, void, RawServoStyleSetOwned set)
SERVO_BINDING_FUNC(Servo_StyleSet_CompatModeChanged, void,
RawServoStyleSetBorrowed raw_data)
SERVO_BINDING_FUNC(Servo_StyleSet_AppendStyleSheet, void,
RawServoStyleSetBorrowed set,
const mozilla::ServoStyleSheet* gecko_sheet)
SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
RawServoStyleSetBorrowed set,
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -104,17 +104,17 @@ ServoStyleSet::~ServoStyleSet()
}
}
}
void
ServoStyleSet::Init(nsPresContext* aPresContext, nsBindingManager* aBindingManager)
{
mPresContext = aPresContext;
- mPresContextInitXBLStyleSet = aPresContext;
+ mLastPresContextUsesXBLStyleSet = aPresContext;
mRawSet.reset(Servo_StyleSet_Init(aPresContext));
mBindingManager = aBindingManager;
mPresContext->DeviceContext()->InitFontCache();
// Now that we have an mRawSet, go ahead and notify about whatever stylesheets
// we have so far.
@@ -161,16 +161,34 @@ ServoStyleSet::Shutdown()
void
ServoStyleSet::InvalidateStyleForCSSRuleChanges()
{
MOZ_ASSERT(StylistNeedsUpdate());
mPresContext->RestyleManager()->AsServo()->PostRestyleEventForCSSRuleChanges();
}
+bool
+ServoStyleSet::SetPresContext(nsPresContext* aPresContext)
+{
+ MOZ_ASSERT(IsForXBL(), "Only XBL styleset can set PresContext!");
+
+ mLastPresContextUsesXBLStyleSet = aPresContext;
+
+ const OriginFlags rulesChanged = static_cast<OriginFlags>(
+ Servo_StyleSet_SetDevice(mRawSet.get(), aPresContext));
+
+ if (rulesChanged != OriginFlags(0)) {
+ MarkOriginsDirty(rulesChanged);
+ return true;
+ }
+
+ return false;
+}
+
nsRestyleHint
ServoStyleSet::MediumFeaturesChanged(bool aViewportChanged)
{
bool viewportUnitsUsed = false;
bool rulesChanged = MediumFeaturesChangedRules(&viewportUnitsUsed);
if (mBindingManager &&
mBindingManager->MediumFeaturesChanged(mPresContext)) {
--- a/layout/style/ServoStyleSet.h
+++ b/layout/style/ServoStyleSet.h
@@ -435,21 +435,25 @@ public:
// Returns the style rule map.
ServoStyleRuleMap* StyleRuleMap();
// Clear mPresContext. This is needed after XBL ServoStyleSet is created.
void ClearPresContext() {
mPresContext = nullptr;
}
- // Return whether this is the PresContext that initialized us.
+ // Return whether this is the last PresContext which uses this XBL styleset.
bool IsPresContextChanged(nsPresContext* aPresContext) const {
- return aPresContext != mPresContextInitXBLStyleSet;
+ return aPresContext != mLastPresContextUsesXBLStyleSet;
}
+ // Set PresContext (i.e. Device) for mRawSet. This should be called only
+ // by XBL stylesets. Returns true if there is any rule changing.
+ bool SetPresContext(nsPresContext* aPresContext);
+
/**
* Returns true if a modification to an an attribute with the specified
* 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.
*/
@@ -582,19 +586,19 @@ private:
ServoStyleSheet* aSheet);
const Kind mKind;
// Nullptr if this is an XBL style set.
nsPresContext* MOZ_NON_OWNING_REF mPresContext = nullptr;
// Because XBL style set could be used by multiple PresContext, we need to
- // store the PresContext pointer which initializes this style set for
+ // store the last PresContext pointer which uses this XBL styleset for
// computing medium rule changes.
- void* MOZ_NON_OWNING_REF mPresContextInitXBLStyleSet = nullptr;
+ void* MOZ_NON_OWNING_REF mLastPresContextUsesXBLStyleSet = nullptr;
UniquePtr<RawServoStyleSet> mRawSet;
EnumeratedArray<SheetType, SheetType::Count,
nsTArray<RefPtr<ServoStyleSheet>>> mSheets;
bool mAuthorStyleDisabled;
StylistState mStylistState;
uint64_t mUserFontSetUpdateGeneration;
uint32_t mUserFontCacheUpdateGeneration;