From 388875ca4418664ee904a618cc4ca2236c397c3f Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Tue, 25 Jul 2017 18:20:50 +1000 Subject: [PATCH] Record viewport unit usage and generate proper restyle hint. --- components/style/gecko/generated/bindings.rs | 5 +++-- components/style/gecko/media_queries.rs | 11 +++++++++++ components/style/stylesheets/viewport_rule.rs | 4 ++++ ports/geckolib/glue.rs | 15 ++++++++++++--- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index fb3d1a35c898..962cf8056fad 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -1921,8 +1921,9 @@ extern "C" { pub fn Servo_StyleSet_RebuildData(set: RawServoStyleSetBorrowed); } extern "C" { - pub fn Servo_StyleSet_MediumFeaturesChanged(set: RawServoStyleSetBorrowed) - -> bool; + pub fn Servo_StyleSet_MediumFeaturesChanged(set: RawServoStyleSetBorrowed, + viewport_changed: bool) + -> nsRestyleHint; } extern "C" { pub fn Servo_StyleSet_CompatModeChanged(raw_data: diff --git a/components/style/gecko/media_queries.rs b/components/style/gecko/media_queries.rs index 7ce33b506ffa..1693980ac3cb 100644 --- a/components/style/gecko/media_queries.rs +++ b/components/style/gecko/media_queries.rs @@ -54,6 +54,9 @@ pub struct Device { /// Whether any styles computed in the document relied on the root font-size /// by using rem units. used_root_font_size: AtomicBool, + /// Whether any styles computed in the document relied on the viewport size + /// by using vw/vh/vmin/vmax units. + used_viewport_size: AtomicBool, } unsafe impl Sync for Device {} @@ -69,6 +72,7 @@ impl Device { viewport_override: None, root_font_size: AtomicIsize::new(font_size::get_initial_value().0 as isize), // FIXME(bz): Seems dubious? used_root_font_size: AtomicBool::new(false), + used_viewport_size: AtomicBool::new(false), } } @@ -112,6 +116,7 @@ impl Device { self.viewport_override = None; self.default_values = ComputedValues::default_values(self.pres_context()); self.used_root_font_size.store(false, Ordering::Relaxed); + self.used_viewport_size.store(false, Ordering::Relaxed); } /// Returns whether we ever looked up the root font size of the Device. @@ -146,6 +151,7 @@ impl Device { /// Returns the current viewport size in app units. pub fn au_viewport_size(&self) -> Size2D { + self.used_viewport_size.store(true, Ordering::Relaxed); self.viewport_override.as_ref().map(|v| { Size2D::new(Au::from_f32_px(v.size.width), Au::from_f32_px(v.size.height)) @@ -156,6 +162,11 @@ impl Device { }) } + /// Returns whether we ever looked up the viewport size of the Device. + pub fn used_viewport_size(&self) -> bool { + self.used_viewport_size.load(Ordering::Relaxed) + } + /// Returns the device pixel ratio. pub fn device_pixel_ratio(&self) -> ScaleFactor { let override_dppx = self.pres_context().mOverrideDPPX; diff --git a/components/style/stylesheets/viewport_rule.rs b/components/style/stylesheets/viewport_rule.rs index af2cb097c318..7d3339a92148 100644 --- a/components/style/stylesheets/viewport_rule.rs +++ b/components/style/stylesheets/viewport_rule.rs @@ -696,6 +696,10 @@ impl MaybeNew for ViewportConstraints { // // Note: DEVICE-ADAPT ยง 5. states that relative length values are // resolved against initial values + // + // Note, we set used_viewport_size flag for Gecko in au_viewport_size. + // If we ever start supporting ViewportRule in Gecko, we probably want + // to avoid doing so at this place. let initial_viewport = device.au_viewport_size(); let provider = get_metrics_provider_for_product(); diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 9e1ce47c893e..670690a79df4 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -865,7 +865,8 @@ pub extern "C" fn Servo_StyleSet_AppendStyleSheet( #[no_mangle] pub extern "C" fn Servo_StyleSet_MediumFeaturesChanged( raw_data: RawServoStyleSetBorrowed, -) -> bool { + viewport_changed: bool, +) -> nsRestyleHint { let global_style_data = &*GLOBAL_STYLE_DATA; let guard = global_style_data.shared_lock.read(); @@ -881,11 +882,19 @@ pub extern "C" fn Servo_StyleSet_MediumFeaturesChanged( // less often. let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut(); + let viewport_units_used = data.stylist.device().used_viewport_size(); data.stylist.device_mut().reset_computed_values(); - data.stylist.media_features_change_changed_style( + let rules_changed = data.stylist.media_features_change_changed_style( data.stylesheets.iter(), &guard, - ) + ); + if rules_changed { + structs::nsRestyleHint_eRestyle_Subtree + } else if viewport_changed && viewport_units_used { + structs::nsRestyleHint_eRestyle_ForceDescendants + } else { + nsRestyleHint(0) + } } #[no_mangle]