compositor: Allow canvas to upload rendered contents asynchronously (#37776)

Adds epoch to each WR image op command that is sent to compositor. The
renderer now has a `FrameDelayer` data structure that is responsible for
tracking when a frame is ready to be displayed. When asking canvases to
update their rendering, they are given an optional `Epoch` which denotes
the `Document`'s canvas epoch. When all image updates for that `Epoch`
are seen in the renderer, the frame can be displayed.

Testing: Existing WPT tests
Fixes: #35733

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
Signed-off-by: Martin Robinson <mrobinson@igalia.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Sam 2025-08-29 12:04:41 +02:00 committed by GitHub
parent 4700149fcb
commit 8beef6c21f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 452 additions and 100 deletions

View file

@ -6,6 +6,7 @@ use std::borrow::ToOwned;
use std::collections::HashMap;
use std::{f32, thread};
use base::Epoch;
use canvas_traits::ConstellationCanvasMsg;
use canvas_traits::canvas::*;
use compositing_traits::CrossProcessCompositorApi;
@ -253,9 +254,8 @@ impl CanvasPaintThread {
self.canvas(canvas_id)
.put_image_data(snapshot.to_owned(), rect);
},
Canvas2dMsg::UpdateImage(sender) => {
self.canvas(canvas_id).update_image_rendering();
sender.send(()).unwrap();
Canvas2dMsg::UpdateImage(canvas_epoch) => {
self.canvas(canvas_id).update_image_rendering(canvas_epoch);
},
Canvas2dMsg::PopClips(clips) => self.canvas(canvas_id).pop_clips(clips),
}
@ -526,12 +526,12 @@ impl Canvas {
}
}
fn update_image_rendering(&mut self) {
fn update_image_rendering(&mut self, canvas_epoch: Option<Epoch>) {
match self {
#[cfg(feature = "vello")]
Canvas::Vello(canvas_data) => canvas_data.update_image_rendering(),
Canvas::Vello(canvas_data) => canvas_data.update_image_rendering(canvas_epoch),
#[cfg(feature = "vello_cpu")]
Canvas::VelloCPU(canvas_data) => canvas_data.update_image_rendering(),
Canvas::VelloCPU(canvas_data) => canvas_data.update_image_rendering(canvas_epoch),
}
}