Fix webgl regression after WebRender upgrade (#30390)

Sending WebRender an explicit ResourceUpdate message
after every buffer swap invalidates the tile caches
that depend on the image resource created for the
webgl canvas.

The previous WebRender code that Servo was using
might have worked with WebGL only accidentally since
picture caching was disabled by [default][1] and so the
tiles were not cached between frames.

Fixes #30367

[1]: c385b3c973/third_party/webrender/webrender/src/renderer.rs (L7073)

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
This commit is contained in:
Mukilan Thiyagarajan 2023-09-20 18:51:02 +05:30 committed by GitHub
parent 49e1832763
commit c2502120cf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -684,25 +684,13 @@ impl WebGLThread {
// Reset framebuffer bindings as appropriate. // Reset framebuffer bindings as appropriate.
framebuffer_rebinding_info.apply(&self.device, &data.ctx, &*data.gl); framebuffer_rebinding_info.apply(&self.device, &data.ctx, &*data.gl);
debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR);
// Update WR image if needed.
let info = self.cached_context_info.get_mut(&context_id).unwrap();
let has_alpha = data let has_alpha = data
.state .state
.requested_flags .requested_flags
.contains(ContextAttributeFlags::ALPHA); .contains(ContextAttributeFlags::ALPHA);
let image_buffer_kind = current_wr_image_buffer_kind(&self.device); self.update_wr_image_for_context(context_id, size.to_i32(), has_alpha);
Self::update_wr_external_image(
&mut self.webrender_api,
self.webrender_doc,
size.to_i32(),
has_alpha,
context_id,
info.image_key,
image_buffer_kind,
);
debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR);
Ok(()) Ok(())
} }
@ -818,6 +806,7 @@ impl WebGLThread {
debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR); debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR);
let SurfaceInfo { let SurfaceInfo {
size,
framebuffer_object, framebuffer_object,
id, id,
.. ..
@ -830,6 +819,12 @@ impl WebGLThread {
"... rebound framebuffer {}, new back buffer surface is {:?}", "... rebound framebuffer {}, new back buffer surface is {:?}",
framebuffer_object, id framebuffer_object, id
); );
let has_alpha = data
.state
.requested_flags
.contains(ContextAttributeFlags::ALPHA);
self.update_wr_image_for_context(context_id, size, has_alpha);
} }
#[allow(unused)] #[allow(unused)]
@ -908,22 +903,23 @@ impl WebGLThread {
image_key image_key
} }
/// Updates a `ImageKey` that uses shared textures. /// Tell WebRender to invalidate any cached tiles for a given `WebGLContextId`
fn update_wr_external_image( /// when the underlying surface has changed e.g due to resize or buffer swap
webrender_api: &mut RenderApi, fn update_wr_image_for_context(
webrender_doc: DocumentId, &mut self,
size: Size2D<i32>,
alpha: bool,
context_id: WebGLContextId, context_id: WebGLContextId,
image_key: ImageKey, size: Size2D<i32>,
image_buffer_kind: ImageBufferKind, has_alpha: bool,
) { ) {
let descriptor = Self::image_descriptor(size, alpha); let info = self.cached_context_info.get(&context_id).unwrap();
let data = Self::external_image_data(context_id, image_buffer_kind); let image_buffer_kind = current_wr_image_buffer_kind(&self.device);
let descriptor = Self::image_descriptor(size, has_alpha);
let image_data = Self::external_image_data(context_id, image_buffer_kind);
let mut txn = Transaction::new(); let mut txn = Transaction::new();
txn.update_image(image_key, descriptor, data, &DirtyRect::All); txn.update_image(info.image_key, descriptor, image_data, &DirtyRect::All);
webrender_api.send_transaction(webrender_doc, txn); self.webrender_api.send_transaction(self.webrender_doc, txn);
} }
/// Helper function to create a `ImageDescriptor`. /// Helper function to create a `ImageDescriptor`.