From c2502120cf51f335c24f444d0f8f3cba8d328431 Mon Sep 17 00:00:00 2001 From: Mukilan Thiyagarajan Date: Wed, 20 Sep 2023 18:51:02 +0530 Subject: [PATCH] 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]: https://github.com/servo/servo/blob/c385b3c9737c17d59cb02e520c3b68b232cb6497/third_party/webrender/webrender/src/renderer.rs#L7073 Signed-off-by: Mukilan Thiyagarajan --- components/canvas/webgl_thread.rs | 48 ++++++++++++++----------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index 8e1e55f4c91..5d3b9116773 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -684,25 +684,13 @@ impl WebGLThread { // Reset framebuffer bindings as appropriate. 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 .state .requested_flags .contains(ContextAttributeFlags::ALPHA); - let image_buffer_kind = current_wr_image_buffer_kind(&self.device); - 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); + self.update_wr_image_for_context(context_id, size.to_i32(), has_alpha); Ok(()) } @@ -818,6 +806,7 @@ impl WebGLThread { debug_assert_eq!(data.gl.get_error(), gl::NO_ERROR); let SurfaceInfo { + size, framebuffer_object, id, .. @@ -830,6 +819,12 @@ impl WebGLThread { "... rebound framebuffer {}, new back buffer surface is {:?}", 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)] @@ -908,22 +903,23 @@ impl WebGLThread { image_key } - /// Updates a `ImageKey` that uses shared textures. - fn update_wr_external_image( - webrender_api: &mut RenderApi, - webrender_doc: DocumentId, - size: Size2D, - alpha: bool, + /// Tell WebRender to invalidate any cached tiles for a given `WebGLContextId` + /// when the underlying surface has changed e.g due to resize or buffer swap + fn update_wr_image_for_context( + &mut self, context_id: WebGLContextId, - image_key: ImageKey, - image_buffer_kind: ImageBufferKind, + size: Size2D, + has_alpha: bool, ) { - let descriptor = Self::image_descriptor(size, alpha); - let data = Self::external_image_data(context_id, image_buffer_kind); + let info = self.cached_context_info.get(&context_id).unwrap(); + 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(); - txn.update_image(image_key, descriptor, data, &DirtyRect::All); - webrender_api.send_transaction(webrender_doc, txn); + txn.update_image(info.image_key, descriptor, image_data, &DirtyRect::All); + self.webrender_api.send_transaction(self.webrender_doc, txn); } /// Helper function to create a `ImageDescriptor`.