compositor: Request reflow when doing a page zooming (#38166)

Request a reflow when doing page zoom and only modify the scaling of the
WebView scene after the first root pipeline display list with the new
zoom is ready. In addition:

  - store zoom limits in `Scale` types
  - send `ViewportDetails` along with the display list so that we can
    detect when the root pipeline scale is ready.

Testing: This is quite hard to test as it requires verification that
contents are zoomed appropriately at the right time.
Fixes: #38091.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-07-29 12:04:37 +02:00 committed by GitHub
parent 3d2f0d1be5
commit 8d5faa9bf9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 111 additions and 44 deletions

View file

@ -65,7 +65,11 @@ impl<'a> BackgroundPainter<'a> {
if &BackgroundAttachment::Fixed ==
get_cyclic(&background.background_attachment.0, layer_index)
{
return builder.compositor_info.viewport_size.into();
return builder
.compositor_info
.viewport_details
.layout_size()
.into();
}
match get_cyclic(&background.background_clip.0, layer_index) {
@ -149,7 +153,11 @@ impl<'a> BackgroundPainter<'a> {
Origin::PaddingBox => *fragment_builder.padding_rect(),
Origin::BorderBox => fragment_builder.border_rect,
},
BackgroundAttachment::Fixed => builder.compositor_info.viewport_size.into(),
BackgroundAttachment::Fixed => builder
.compositor_info
.viewport_details
.layout_size()
.into(),
}
}
}

View file

@ -14,6 +14,7 @@ use compositing_traits::display_list::{
AxesScrollSensitivity, CompositorDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo,
SpatialTreeNodeInfo, StickyNodeInfo,
};
use embedder_traits::ViewportDetails;
use euclid::SideOffsets2D;
use euclid::default::{Point2D, Rect, Size2D};
use log::warn;
@ -120,7 +121,7 @@ impl StackingContextTree {
/// pipeline id.
pub fn new(
fragment_tree: &FragmentTree,
viewport_size: LayoutSize,
viewport_details: ViewportDetails,
pipeline_id: wr::PipelineId,
first_reflow: bool,
debug: &DebugOptions,
@ -131,8 +132,9 @@ impl StackingContextTree {
scrollable_overflow.size.height.to_f32_px(),
));
let viewport_size = viewport_details.layout_size();
let compositor_info = CompositorDisplayListInfo::new(
viewport_size,
viewport_details,
scrollable_overflow,
pipeline_id,
// This epoch is set when the WebRender display list is built. For now use a dummy value.
@ -145,7 +147,7 @@ impl StackingContextTree {
let cb_for_non_fixed_descendants = ContainingBlock::new(
fragment_tree.initial_containing_block,
root_scroll_node_id,
Some(compositor_info.viewport_size),
Some(viewport_size),
ClipId::INVALID,
);
let cb_for_fixed_descendants = ContainingBlock::new(
@ -1504,7 +1506,10 @@ impl BoxFragment {
Some(size) => size,
None => {
// This is a direct descendant of a reference frame.
&stacking_context_tree.compositor_info.viewport_size
&stacking_context_tree
.compositor_info
.viewport_details
.layout_size()
},
};

View file

@ -75,7 +75,7 @@ use style::{Zero, driver};
use style_traits::{CSSPixel, SpeculativePainter};
use stylo_atoms::Atom;
use url::Url;
use webrender_api::units::{DevicePixel, DevicePoint, LayoutSize, LayoutVector2D};
use webrender_api::units::{DevicePixel, DevicePoint, LayoutVector2D};
use webrender_api::{ExternalScrollId, HitTestFlags};
use crate::context::{CachedImageOrError, ImageResolver, LayoutContext};
@ -960,12 +960,6 @@ impl LayoutThread {
return;
}
let viewport_size = self.stylist.device().au_viewport_size();
let viewport_size = LayoutSize::new(
viewport_size.width.to_f32_px(),
viewport_size.height.to_f32_px(),
);
let mut stacking_context_tree = self.stacking_context_tree.borrow_mut();
let old_scroll_offsets = stacking_context_tree
.as_ref()
@ -976,7 +970,7 @@ impl LayoutThread {
// applicable spatial and clip nodes.
let mut new_stacking_context_tree = StackingContextTree::new(
fragment_tree,
viewport_size,
reflow_request.viewport_details,
self.id.into(),
!self.have_ever_generated_display_list.get(),
&self.debug,