layout: Ensure that the Epoch stored in layout is accurate (#39568)

The first epoch is 0 as that is the one used in the initial transaction,
but the code was setting the first `Epoch` to `Epoch(1)`. This means
that
when layout advanced the epoch, the `Epoch` of the first produced
display list was `Epoch(2)`.

This change makes the value reflected in `current_epoch` actually match
the index of the display list produced. In addition, we always store
this epoch in `PipelineDetails` in the renderer. This will be important
when adding the `WebView::take_screenshot` API.

Testing: This should not change behavior, so is covered by existing
tests which
rely on proper `Epoch` advancement.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-09-30 08:42:58 +02:00 committed by GitHub
parent 91e4188a64
commit 6a2a9a6e33
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 39 additions and 22 deletions

View file

@ -175,8 +175,10 @@ pub struct LayoutThread {
/// The [`StackingContextTree`] cached from previous layouts.
stacking_context_tree: RefCell<Option<StackingContextTree>>,
/// A counter for epoch messages
epoch: Cell<Epoch>,
/// The epoch of the current display list that's been sent to [`WebRender`]. Every
/// layout sends an initial empty display list, so this always starts at `0. The
/// next display list will have the value of this epoch plus `1`.
current_epoch: Cell<Epoch>,
// A cache that maps image resources specified in CSS (e.g as the `url()` value
// for `background-image` or `content` properties) to either the final resolved
@ -223,7 +225,7 @@ impl Layout for LayoutThread {
}
fn current_epoch(&self) -> Epoch {
self.epoch.get()
self.current_epoch.get()
}
fn load_web_fonts_from_stylesheet(&self, stylesheet: ServoArc<Stylesheet>) {
@ -646,7 +648,7 @@ impl LayoutThread {
// Let webrender know about this pipeline by sending an empty display list.
config
.compositor_api
.send_initial_transaction(config.id.into());
.send_initial_transaction(config.webview_id, config.id.into());
let mut font = Font::initial_values();
let default_font_size = pref!(fonts_default_size);
@ -685,8 +687,7 @@ impl LayoutThread {
box_tree: Default::default(),
fragment_tree: Default::default(),
stacking_context_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)),
current_epoch: Cell::new(Epoch(0)),
compositor_api: config.compositor_api,
stylist: Stylist::new(device, QuirksMode::NoQuirks),
resolved_images_cache: Default::default(),
@ -1232,10 +1233,8 @@ impl LayoutThread {
return false;
}
let mut epoch = self.epoch.get();
epoch.next();
self.epoch.set(epoch);
stacking_context_tree.compositor_info.epoch = epoch.into();
self.current_epoch.set(self.current_epoch().next());
stacking_context_tree.compositor_info.epoch = self.current_epoch.get().into();
let built_display_list = DisplayListBuilder::build(
stacking_context_tree,