webgl: Replace webrender API with compositor API for images handling (#37714)

Like in #37713, instead of updating images directly with webrender api
we use the compositor api. We still keep webrender api available in
webgl, because that's where we do shutdown, due to GL.

Testing: Existing WPT tests

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
sagudev 2025-06-26 11:06:24 +02:00 committed by GitHub
parent b9f9abee91
commit 03dbf9b6f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 30 additions and 29 deletions

View file

@ -405,8 +405,8 @@ impl Servo {
image_handler, image_handler,
} = WebGLComm::new( } = WebGLComm::new(
rendering_context.clone(), rendering_context.clone(),
compositor_proxy.cross_process_compositor_api.clone(),
webrender_api.create_sender(), webrender_api.create_sender(),
webrender_document,
external_images.clone(), external_images.clone(),
gl_type, gl_type,
); );

View file

@ -9,7 +9,8 @@ use std::sync::{Arc, Mutex};
use canvas_traits::webgl::{GlType, WebGLContextId, WebGLMsg, WebGLThreads, webgl_channel}; use canvas_traits::webgl::{GlType, WebGLContextId, WebGLMsg, WebGLThreads, webgl_channel};
use compositing_traits::rendering_context::RenderingContext; use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{ use compositing_traits::{
WebrenderExternalImageApi, WebrenderExternalImageRegistry, WebrenderImageSource, CrossProcessCompositorApi, WebrenderExternalImageApi, WebrenderExternalImageRegistry,
WebrenderImageSource,
}; };
use euclid::default::Size2D; use euclid::default::Size2D;
use fnv::FnvHashMap; use fnv::FnvHashMap;
@ -17,7 +18,6 @@ use log::debug;
use surfman::chains::{SwapChainAPI, SwapChains, SwapChainsAPI}; use surfman::chains::{SwapChainAPI, SwapChains, SwapChainsAPI};
use surfman::{Device, SurfaceTexture}; use surfman::{Device, SurfaceTexture};
use webrender::RenderApiSender; use webrender::RenderApiSender;
use webrender_api::DocumentId;
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]
use webxr::SurfmanGL as WebXRSurfman; use webxr::SurfmanGL as WebXRSurfman;
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]
@ -36,8 +36,8 @@ impl WebGLComm {
/// Creates a new `WebGLComm` object. /// Creates a new `WebGLComm` object.
pub fn new( pub fn new(
rendering_context: Rc<dyn RenderingContext>, rendering_context: Rc<dyn RenderingContext>,
compositor_api: CrossProcessCompositorApi,
webrender_api_sender: RenderApiSender, webrender_api_sender: RenderApiSender,
webrender_doc: DocumentId,
external_images: Arc<Mutex<WebrenderExternalImageRegistry>>, external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
api_type: GlType, api_type: GlType,
) -> WebGLComm { ) -> WebGLComm {
@ -57,8 +57,8 @@ impl WebGLComm {
// This implementation creates a single `WebGLThread` for all the pipelines. // This implementation creates a single `WebGLThread` for all the pipelines.
let init = WebGLThreadInit { let init = WebGLThreadInit {
compositor_api,
webrender_api_sender, webrender_api_sender,
webrender_doc,
external_images, external_images,
sender: sender.clone(), sender: sender.clone(),
receiver, receiver,

View file

@ -22,7 +22,10 @@ use canvas_traits::webgl::{
WebGLSLVersion, WebGLSamplerId, WebGLSender, WebGLShaderId, WebGLSyncId, WebGLTextureId, WebGLSLVersion, WebGLSamplerId, WebGLSender, WebGLShaderId, WebGLSyncId, WebGLTextureId,
WebGLVersion, WebGLVertexArrayId, YAxisTreatment, WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
}; };
use compositing_traits::{WebrenderExternalImageRegistry, WebrenderImageHandlerType}; use compositing_traits::{
CrossProcessCompositorApi, ImageUpdate, SerializableImageData, WebrenderExternalImageRegistry,
WebrenderImageHandlerType,
};
use euclid::default::Size2D; use euclid::default::Size2D;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use glow::{ use glow::{
@ -40,11 +43,11 @@ use surfman::{
self, Adapter, Connection, Context, ContextAttributeFlags, ContextAttributes, Device, self, Adapter, Connection, Context, ContextAttributeFlags, ContextAttributes, Device,
GLVersion, SurfaceAccess, SurfaceInfo, SurfaceType, GLVersion, SurfaceAccess, SurfaceInfo, SurfaceType,
}; };
use webrender::{RenderApi, RenderApiSender, Transaction}; use webrender::{RenderApi, RenderApiSender};
use webrender_api::units::DeviceIntSize; use webrender_api::units::DeviceIntSize;
use webrender_api::{ use webrender_api::{
DirtyRect, DocumentId, ExternalImageData, ExternalImageId, ExternalImageType, ImageBufferKind, ExternalImageData, ExternalImageId, ExternalImageType, ImageBufferKind, ImageDescriptor,
ImageData, ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey, ImageDescriptorFlags, ImageFormat, ImageKey,
}; };
use crate::webgl_limits::GLLimitsDetect; use crate::webgl_limits::GLLimitsDetect;
@ -202,8 +205,8 @@ pub(crate) struct WebGLThread {
/// The GPU device. /// The GPU device.
device: Device, device: Device,
/// Channel used to generate/update or delete `ImageKey`s. /// Channel used to generate/update or delete `ImageKey`s.
compositor_api: CrossProcessCompositorApi,
webrender_api: RenderApi, webrender_api: RenderApi,
webrender_doc: DocumentId,
/// Map of live WebGLContexts. /// Map of live WebGLContexts.
contexts: FnvHashMap<WebGLContextId, GLContextData>, contexts: FnvHashMap<WebGLContextId, GLContextData>,
/// Cached information for WebGLContexts. /// Cached information for WebGLContexts.
@ -228,8 +231,8 @@ pub(crate) struct WebGLThread {
/// The data required to initialize an instance of the WebGLThread type. /// The data required to initialize an instance of the WebGLThread type.
pub(crate) struct WebGLThreadInit { pub(crate) struct WebGLThreadInit {
pub compositor_api: CrossProcessCompositorApi,
pub webrender_api_sender: RenderApiSender, pub webrender_api_sender: RenderApiSender,
pub webrender_doc: DocumentId,
pub external_images: Arc<Mutex<WebrenderExternalImageRegistry>>, pub external_images: Arc<Mutex<WebrenderExternalImageRegistry>>,
pub sender: WebGLSender<WebGLMsg>, pub sender: WebGLSender<WebGLMsg>,
pub receiver: WebGLReceiver<WebGLMsg>, pub receiver: WebGLReceiver<WebGLMsg>,
@ -248,8 +251,8 @@ impl WebGLThread {
/// Create a new instance of WebGLThread. /// Create a new instance of WebGLThread.
pub(crate) fn new( pub(crate) fn new(
WebGLThreadInit { WebGLThreadInit {
compositor_api,
webrender_api_sender, webrender_api_sender,
webrender_doc,
external_images, external_images,
sender, sender,
receiver, receiver,
@ -265,8 +268,8 @@ impl WebGLThread {
device: connection device: connection
.create_device(&adapter) .create_device(&adapter)
.expect("Couldn't open WebGL device!"), .expect("Couldn't open WebGL device!"),
compositor_api,
webrender_api: webrender_api_sender.create_api(), webrender_api: webrender_api_sender.create_api(),
webrender_doc,
contexts: Default::default(), contexts: Default::default(),
cached_context_info: Default::default(), cached_context_info: Default::default(),
bound_context_id: None, bound_context_id: None,
@ -648,8 +651,7 @@ impl WebGLThread {
); );
let image_key = Self::create_wr_external_image( let image_key = Self::create_wr_external_image(
&mut self.webrender_api, &self.compositor_api,
self.webrender_doc,
size.to_i32(), size.to_i32(),
has_alpha, has_alpha,
id, id,
@ -717,9 +719,8 @@ impl WebGLThread {
fn remove_webgl_context(&mut self, context_id: WebGLContextId) { fn remove_webgl_context(&mut self, context_id: WebGLContextId) {
// Release webrender image keys. // Release webrender image keys.
if let Some(info) = self.cached_context_info.remove(&context_id) { if let Some(info) = self.cached_context_info.remove(&context_id) {
let mut txn = Transaction::new(); self.compositor_api
txn.delete_image(info.image_key); .update_images(vec![ImageUpdate::DeleteImage(info.image_key)]);
self.webrender_api.send_transaction(self.webrender_doc, txn)
} }
// We need to make the context current so its resources can be disposed of. // We need to make the context current so its resources can be disposed of.
@ -898,8 +899,7 @@ impl WebGLThread {
/// Creates a `webrender_api::ImageKey` that uses shared textures. /// Creates a `webrender_api::ImageKey` that uses shared textures.
fn create_wr_external_image( fn create_wr_external_image(
webrender_api: &mut RenderApi, compositor_api: &CrossProcessCompositorApi,
webrender_doc: DocumentId,
size: Size2D<i32>, size: Size2D<i32>,
alpha: bool, alpha: bool,
context_id: WebGLContextId, context_id: WebGLContextId,
@ -908,10 +908,8 @@ impl WebGLThread {
let descriptor = Self::image_descriptor(size, alpha); let descriptor = Self::image_descriptor(size, alpha);
let data = Self::external_image_data(context_id, image_buffer_kind); let data = Self::external_image_data(context_id, image_buffer_kind);
let image_key = webrender_api.generate_image_key(); let image_key = compositor_api.generate_image_key().unwrap();
let mut txn = Transaction::new(); compositor_api.add_image(image_key, descriptor, data);
txn.add_image(image_key, descriptor, data, None);
webrender_api.send_transaction(webrender_doc, txn);
image_key image_key
} }
@ -930,9 +928,12 @@ impl WebGLThread {
let descriptor = Self::image_descriptor(size, has_alpha); let descriptor = Self::image_descriptor(size, has_alpha);
let image_data = Self::external_image_data(context_id, image_buffer_kind); let image_data = Self::external_image_data(context_id, image_buffer_kind);
let mut txn = Transaction::new(); self.compositor_api
txn.update_image(info.image_key, descriptor, image_data, &DirtyRect::All); .update_images(vec![ImageUpdate::UpdateImage(
self.webrender_api.send_transaction(self.webrender_doc, txn); info.image_key,
descriptor,
image_data,
)]);
} }
/// Helper function to create a `ImageDescriptor`. /// Helper function to create a `ImageDescriptor`.
@ -952,14 +953,14 @@ impl WebGLThread {
fn external_image_data( fn external_image_data(
context_id: WebGLContextId, context_id: WebGLContextId,
image_buffer_kind: ImageBufferKind, image_buffer_kind: ImageBufferKind,
) -> ImageData { ) -> SerializableImageData {
let data = ExternalImageData { let data = ExternalImageData {
id: ExternalImageId(context_id.0), id: ExternalImageId(context_id.0),
channel_index: 0, channel_index: 0,
image_type: ExternalImageType::TextureHandle(image_buffer_kind), image_type: ExternalImageType::TextureHandle(image_buffer_kind),
normalized_uvs: false, normalized_uvs: false,
}; };
ImageData::External(data) SerializableImageData::External(data)
} }
/// Gets the GLSL Version supported by a GLContext. /// Gets the GLSL Version supported by a GLContext.