From 5f0f457ac3f70714ca14f8a6ecf4f59a3f179391 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Sat, 12 Apr 2025 22:01:22 +0200 Subject: [PATCH] compositing: Send `CompositorDisplayListInfo` as bytes to compositor (#36484) `CompositorDisplayListInfo` is a large data structure that scales with the size of the display list. Serializing it onto the Compositor's IPC channel can cause deadlocks. This change serializes it with bincode and sends it alongside the rest of the serialized display list information on the IPC `bytes_channel`. This should prevent deadlocks when the compositor API is unified. Testing: This is covered by existing WPT tests. Signed-off-by: Martin Robinson Signed-off-by: Martin Robinson --- Cargo.lock | 2 ++ components/compositing/Cargo.toml | 1 + components/compositing/compositor.rs | 16 ++++++++++++++-- components/shared/compositing/Cargo.toml | 1 + components/shared/compositing/lib.rs | 15 +++++++++------ 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 670de82c62a..5e617894f4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1089,6 +1089,7 @@ name = "compositing" version = "0.0.1" dependencies = [ "base", + "bincode", "bitflags 2.9.0", "compositing_traits", "constellation_traits", @@ -1120,6 +1121,7 @@ name = "compositing_traits" version = "0.0.1" dependencies = [ "base", + "bincode", "crossbeam-channel", "dpi", "embedder_traits", diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 6cabded02d8..b839e3599fd 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -19,6 +19,7 @@ webxr = ["dep:webxr"] [dependencies] base = { workspace = true } +bincode = { workspace = true } bitflags = { workspace = true } compositing_traits = { workspace = true } constellation_traits = { workspace = true } diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index ccb28c5df56..f038fa9ad0b 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -16,7 +16,7 @@ use base::cross_process_instant::CrossProcessInstant; use base::id::{PipelineId, WebViewId}; use base::{Epoch, WebRenderEpochToU16}; use bitflags::bitflags; -use compositing_traits::display_list::{HitTestInfo, ScrollTree}; +use compositing_traits::display_list::{CompositorDisplayListInfo, HitTestInfo, ScrollTree}; use compositing_traits::rendering_context::RenderingContext; use compositing_traits::{ CompositionPipeline, CompositorMsg, CompositorReceiver, CrossProcessCompositorMessage, @@ -740,11 +740,23 @@ impl IOCompositor { CrossProcessCompositorMessage::SendDisplayList { webview_id, - display_list_info, display_list_descriptor, display_list_receiver, } => { // This must match the order from the sender, currently in `shared/script/lib.rs`. + let display_list_info = match display_list_receiver.recv() { + Ok(display_list_info) => display_list_info, + Err(error) => { + return warn!("Could not receive display list info: {error}"); + }, + }; + let display_list_info: CompositorDisplayListInfo = + match bincode::deserialize(&display_list_info) { + Ok(display_list_info) => display_list_info, + Err(error) => { + return warn!("Could not deserialize display list info: {error}"); + }, + }; let items_data = match display_list_receiver.recv() { Ok(display_list_data) => display_list_data, Err(error) => { diff --git a/components/shared/compositing/Cargo.toml b/components/shared/compositing/Cargo.toml index d1df90106cb..f2b19c3886c 100644 --- a/components/shared/compositing/Cargo.toml +++ b/components/shared/compositing/Cargo.toml @@ -16,6 +16,7 @@ no-wgl = ["surfman/sm-angle-default"] [dependencies] base = { workspace = true } +bincode = { workspace = true } crossbeam-channel = { workspace = true } dpi = { version = "0.1" } embedder_traits = { workspace = true } diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs index baf59e53118..4e4ec39767c 100644 --- a/components/shared/compositing/lib.rs +++ b/components/shared/compositing/lib.rs @@ -147,8 +147,6 @@ pub enum CrossProcessCompositorMessage { SendDisplayList { /// The [`WebViewId`] that this display list belongs to. webview_id: WebViewId, - /// The [CompositorDisplayListInfo] that describes the display list being sent. - display_list_info: Box, /// A descriptor of this display list used to construct this display list from raw data. display_list_descriptor: BuiltDisplayListDescriptor, /// An [ipc::IpcBytesReceiver] used to send the raw data of the display list. @@ -275,21 +273,26 @@ impl CrossProcessCompositorApi { let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap(); if let Err(e) = self.0.send(CrossProcessCompositorMessage::SendDisplayList { webview_id, - display_list_info: Box::new(display_list_info), display_list_descriptor, display_list_receiver, }) { warn!("Error sending display list: {}", e); } + let display_list_info_serialized = + bincode::serialize(&display_list_info).unwrap_or_default(); + if let Err(error) = display_list_sender.send(&display_list_info_serialized) { + warn!("Error sending display list info: {error}"); + } + if let Err(error) = display_list_sender.send(&display_list_data.items_data) { - warn!("Error sending display list items: {}", error); + warn!("Error sending display list items: {error}"); } if let Err(error) = display_list_sender.send(&display_list_data.cache_data) { - warn!("Error sending display list cache data: {}", error); + warn!("Error sending display list cache data: {error}"); } if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) { - warn!("Error sending display spatial tree: {}", error); + warn!("Error sending display spatial tree: {error}"); } }