mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
layout: More conservatively replace Stylist's Device (#31857)
Instead of replacing Stylist's device on every reflow, only replace it when the viewport changes. In addition, preserve the root font size from the previous reflow fixing an issue where `rem` units were not properly computed between reflows. This fixes a bug where fonts that are sized using `rem` units change size on reload.
This commit is contained in:
parent
b71de92569
commit
bf3798bbde
8 changed files with 95 additions and 61 deletions
|
@ -72,6 +72,7 @@ use style::dom::{TElement, TNode};
|
|||
use style::driver;
|
||||
use style::error_reporting::RustLogReporter;
|
||||
use style::global_style_data::{GLOBAL_STYLE_DATA, STYLE_THREAD_POOL};
|
||||
use style::invalidation::element::restyle_hints::RestyleHint;
|
||||
use style::media_queries::{Device, MediaList, MediaType};
|
||||
use style::properties::PropertyId;
|
||||
use style::selector_parser::SnapshotMap;
|
||||
|
@ -360,7 +361,10 @@ impl LayoutThread {
|
|||
fragment_tree: Default::default(),
|
||||
// Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR
|
||||
epoch: Cell::new(Epoch(1)),
|
||||
viewport_size: Size2D::new(Au(0), Au(0)),
|
||||
viewport_size: Size2D::new(
|
||||
Au::from_f32_px(window_size.initial_viewport.width),
|
||||
Au::from_f32_px(window_size.initial_viewport.height),
|
||||
),
|
||||
webrender_api: webrender_api_sender,
|
||||
stylist: Stylist::new(device, QuirksMode::NoQuirks),
|
||||
rw_data: Arc::new(Mutex::new(LayoutThreadData {
|
||||
|
@ -628,15 +632,6 @@ impl LayoutThread {
|
|||
Some(x) => x,
|
||||
};
|
||||
|
||||
let initial_viewport = data.window_size.initial_viewport;
|
||||
let device_pixel_ratio = data.window_size.device_pixel_ratio;
|
||||
let current_screen_size = Size2D::new(
|
||||
Au::from_f32_px(initial_viewport.width),
|
||||
Au::from_f32_px(initial_viewport.height),
|
||||
);
|
||||
|
||||
let origin = data.origin.clone();
|
||||
|
||||
// Calculate the actual viewport as per DEVICE-ADAPT § 6
|
||||
// If the entire flow tree is invalid, then it will be reflowed anyhow.
|
||||
let document_shared_lock = document.style_shared_lock();
|
||||
|
@ -649,17 +644,14 @@ impl LayoutThread {
|
|||
ua_or_user: &ua_or_user_guard,
|
||||
};
|
||||
|
||||
let device = Device::new(
|
||||
MediaType::screen(),
|
||||
self.stylist.quirks_mode(),
|
||||
initial_viewport,
|
||||
device_pixel_ratio,
|
||||
);
|
||||
let sheet_origins_affected_by_device_change = self.stylist.set_device(device, &guards);
|
||||
let had_used_viewport_units = self.stylist.device().used_viewport_units();
|
||||
let viewport_size_changed = self.handle_viewport_change(data.window_size, &guards);
|
||||
if viewport_size_changed && had_used_viewport_units {
|
||||
if let Some(mut data) = root_element.mutate_data() {
|
||||
data.hint.insert(RestyleHint::recascade_subtree());
|
||||
}
|
||||
}
|
||||
|
||||
self.stylist
|
||||
.force_stylesheet_origins_dirty(sheet_origins_affected_by_device_change);
|
||||
self.viewport_size = current_screen_size;
|
||||
if self.first_reflow.get() {
|
||||
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
|
||||
self.stylist
|
||||
|
@ -739,7 +731,7 @@ impl LayoutThread {
|
|||
let mut layout_context = self.build_layout_context(
|
||||
guards.clone(),
|
||||
&map,
|
||||
origin,
|
||||
data.origin.clone(),
|
||||
data.animation_timeline_value,
|
||||
&data.animations,
|
||||
data.stylesheets_changed,
|
||||
|
@ -1158,6 +1150,42 @@ impl LayoutThread {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Update layout given a new viewport. Returns true if the viewport changed or false if it didn't.
|
||||
fn handle_viewport_change(
|
||||
&mut self,
|
||||
window_size_data: WindowSizeData,
|
||||
guards: &StylesheetGuards,
|
||||
) -> bool {
|
||||
// If the viewport size and device pixel ratio has not changed, do not make any changes.
|
||||
let au_viewport_size = Size2D::new(
|
||||
Au::from_f32_px(window_size_data.initial_viewport.width),
|
||||
Au::from_f32_px(window_size_data.initial_viewport.height),
|
||||
);
|
||||
|
||||
if self.stylist.device().au_viewport_size() == au_viewport_size &&
|
||||
self.stylist.device().device_pixel_ratio() == window_size_data.device_pixel_ratio
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
let device = Device::new(
|
||||
MediaType::screen(),
|
||||
self.stylist.quirks_mode(),
|
||||
window_size_data.initial_viewport,
|
||||
window_size_data.device_pixel_ratio,
|
||||
);
|
||||
|
||||
// Preserve any previously computed root font size.
|
||||
device.set_root_font_size(self.stylist.device().root_font_size());
|
||||
|
||||
let sheet_origins_affected_by_device_change = self.stylist.set_device(device, guards);
|
||||
self.stylist
|
||||
.force_stylesheet_origins_dirty(sheet_origins_affected_by_device_change);
|
||||
|
||||
self.viewport_size = au_viewport_size;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl ProfilerMetadataFactory for LayoutThread {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue