Bug 1435939: Don't reset the default computed values if they cannot change. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 06 Feb 2018 15:17:10 +0100
changeset 751623 25cf2c5ff1b25d848afb07f6be5aeb0f0072cb25
parent 751622 ceee35775a5df57e9d548fa017488807f9ddf604
child 751624 622bfbf26459c173d13d4292a065f2efa4c21ce7
push id98022
push userbmo:emilio@crisal.io
push dateTue, 06 Feb 2018 19:03:46 +0000
reviewersxidorn
bugs1435939
milestone60.0a1
Bug 1435939: Don't reset the default computed values if they cannot change. r?xidorn This actually fixes the bug. MozReview-Commit-ID: AejqMLZzpQp
layout/style/ServoBindingList.h
layout/style/ServoStyleSet.cpp
servo/ports/geckolib/glue.rs
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -82,17 +82,18 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_GetO
                    RawServoStyleSheetContentsBorrowed sheet)
 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)
+                   RawServoStyleSetBorrowed set, bool* viewport_units_used,
+                   bool may_affect_default_style)
 // 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)
--- a/layout/style/ServoStyleSet.cpp
+++ b/layout/style/ServoStyleSet.cpp
@@ -286,25 +286,36 @@ ServoStyleSet::MediumFeaturesChanged(Med
     bool(aReason & MediaFeatureChangeReason::ViewportChange);
   if (viewportUnitsUsed && viewportChanged) {
     return eRestyle_ForceDescendants;
   }
 
   return nsRestyleHint(0);
 }
 
+static const MediaFeatureChangeReason kMediaFeaturesAffectingDefaultStyle =
+  // Zoom changes change the meaning of em units.
+  MediaFeatureChangeReason::ZoomChange |
+  // Changes the meaning of em units, depending on which one is the actual
+  // min-font-size.
+  MediaFeatureChangeReason::MinFontSizeChange;
+
 bool
 ServoStyleSet::MediumFeaturesChangedRules(
   bool* aViewportUnitsUsed,
   MediaFeatureChangeReason aReason)
 {
   MOZ_ASSERT(aViewportUnitsUsed);
 
+  bool mayAffectDefaultStyle =
+    bool(aReason & kMediaFeaturesAffectingDefaultStyle);
+
   const OriginFlags rulesChanged = static_cast<OriginFlags>(
-    Servo_StyleSet_MediumFeaturesChanged(mRawSet.get(), aViewportUnitsUsed));
+    Servo_StyleSet_MediumFeaturesChanged(
+      mRawSet.get(), aViewportUnitsUsed, mayAffectDefaultStyle));
 
   if (rulesChanged != OriginFlags(0)) {
     MarkOriginsDirty(rulesChanged);
     return true;
   }
 
   return false;
 }
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1116,39 +1116,45 @@ pub extern "C" fn Servo_StyleSet_AppendS
     let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
     let data = &mut *data;
     let guard = global_style_data.shared_lock.read();
     let sheet = unsafe { GeckoStyleSheet::new(sheet) };
     data.stylist.append_stylesheet(sheet, &guard);
 }
 
 #[no_mangle]
-pub extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
+pub unsafe extern "C" fn Servo_StyleSet_MediumFeaturesChanged(
     raw_data: RawServoStyleSetBorrowed,
     viewport_units_used: *mut bool,
+    may_affect_default_style: bool,
 ) -> u8 {
     let global_style_data = &*GLOBAL_STYLE_DATA;
     let guard = global_style_data.shared_lock.read();
 
     // NOTE(emilio): We don't actually need to flush the stylist here and ensure
     // it's up to date.
     //
     // In case it isn't we would trigger a rebuild + restyle as needed too.
     //
     // We need to ensure the default computed values are up to date though,
     // because those can influence the result of media query evaluation.
     //
     // FIXME(emilio, bug 1369984): do the computation conditionally, to do it
     // less often.
     let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
 
-    unsafe {
-        *viewport_units_used = data.stylist.device().used_viewport_size();
+    *viewport_units_used = data.stylist.device().used_viewport_size();
+    if may_affect_default_style {
+        // FIXME(emilio): It's a shame we do this too for XBL stuff, but we need
+        // to right now to evaluate relative units in media queries correctly.
+        //
+        // We should instead just pass the `Device` reference from the master
+        // stylist, but that looked kinda gross... Maybe it's not actually.
+        data.stylist.device_mut().reset_computed_values();
     }
-    data.stylist.device_mut().reset_computed_values();
     let guards = StylesheetGuards::same(&guard);
     let origins_in_which_rules_changed =
         data.stylist.media_features_change_changed_style(&guards);
 
     // 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, so for now just unwrap it.
     OriginFlags::from(origins_in_which_rules_changed).0