mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Lazily initialize canvas paint thread in constellation (#37765)
This PR moves canvas paint thread initialization to constellation. This allows us to lazily initialize it on first create canvas request (like we do for webgpu). If we didn't started canvas paint thread we also do not need to wait for it's teardown. Per https://chromestatus.com/metrics/webfeature/timeline/popularity/201 ~30% of websites still use 2d canvas. Testing: Existing WPT tests Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
ee7cb80213
commit
5311beb34a
5 changed files with 34 additions and 32 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1454,6 +1454,7 @@ dependencies = [
|
|||
"backtrace",
|
||||
"base",
|
||||
"bluetooth_traits",
|
||||
"canvas",
|
||||
"canvas_traits",
|
||||
"compositing_traits",
|
||||
"constellation_traits",
|
||||
|
@ -4846,7 +4847,6 @@ dependencies = [
|
|||
"bincode",
|
||||
"bluetooth",
|
||||
"bluetooth_traits",
|
||||
"canvas",
|
||||
"canvas_traits",
|
||||
"compositing",
|
||||
"compositing_traits",
|
||||
|
|
|
@ -23,6 +23,7 @@ background_hang_monitor_api = { workspace = true }
|
|||
backtrace = { workspace = true }
|
||||
base = { workspace = true }
|
||||
bluetooth_traits = { workspace = true, optional = true }
|
||||
canvas = { path = "../canvas" }
|
||||
canvas_traits = { workspace = true }
|
||||
compositing_traits = { workspace = true }
|
||||
constellation_traits = { workspace = true }
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
//! See <https://github.com/servo/servo/issues/14704>
|
||||
|
||||
use std::borrow::ToOwned;
|
||||
use std::cell::OnceCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::marker::PhantomData;
|
||||
|
@ -105,6 +106,7 @@ use base::id::{
|
|||
};
|
||||
#[cfg(feature = "bluetooth")]
|
||||
use bluetooth_traits::BluetoothRequest;
|
||||
use canvas::canvas_paint_thread::CanvasPaintThread;
|
||||
use canvas_traits::ConstellationCanvasMsg;
|
||||
use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
||||
use canvas_traits::webgl::WebGLThreads;
|
||||
|
@ -425,10 +427,8 @@ pub struct Constellation<STF, SWF> {
|
|||
/// The XR device registry
|
||||
webxr_registry: Option<webxr_api::Registry>,
|
||||
|
||||
/// A channel through which messages can be sent to the canvas paint thread.
|
||||
canvas_sender: Sender<ConstellationCanvasMsg>,
|
||||
|
||||
canvas_ipc_sender: IpcSender<CanvasMsg>,
|
||||
/// Lazily initialized channels for canvas paint thread.
|
||||
canvas: OnceCell<(Sender<ConstellationCanvasMsg>, IpcSender<CanvasMsg>)>,
|
||||
|
||||
/// Navigation requests from script awaiting approval from the embedder.
|
||||
pending_approval_navigations: PendingApprovalNavigations,
|
||||
|
@ -584,8 +584,6 @@ where
|
|||
random_pipeline_closure_probability: Option<f32>,
|
||||
random_pipeline_closure_seed: Option<usize>,
|
||||
hard_fail: bool,
|
||||
canvas_create_sender: Sender<ConstellationCanvasMsg>,
|
||||
canvas_ipc_sender: IpcSender<CanvasMsg>,
|
||||
) -> Sender<EmbedderToConstellationMessage> {
|
||||
let (compositor_sender, compositor_receiver) = unbounded();
|
||||
|
||||
|
@ -707,8 +705,7 @@ where
|
|||
}),
|
||||
webgl_threads: state.webgl_threads,
|
||||
webxr_registry: state.webxr_registry,
|
||||
canvas_sender: canvas_create_sender,
|
||||
canvas_ipc_sender,
|
||||
canvas: OnceCell::new(),
|
||||
pending_approval_navigations: HashMap::new(),
|
||||
pressed_mouse_buttons: 0,
|
||||
active_keyboard_modifiers: Modifiers::empty(),
|
||||
|
@ -2665,14 +2662,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
debug!("Exiting Canvas Paint thread.");
|
||||
let (canvas_exit_sender, canvas_exit_receiver) = unbounded();
|
||||
if let Err(e) = self
|
||||
.canvas_sender
|
||||
.send(ConstellationCanvasMsg::Exit(canvas_exit_sender))
|
||||
{
|
||||
warn!("Exit Canvas Paint thread failed ({})", e);
|
||||
}
|
||||
let canvas_exit_receiver = if let Some((canvas_sender, _)) = self.canvas.get() {
|
||||
debug!("Exiting Canvas Paint thread.");
|
||||
let (canvas_exit_sender, canvas_exit_receiver) = unbounded();
|
||||
if let Err(e) = canvas_sender.send(ConstellationCanvasMsg::Exit(canvas_exit_sender)) {
|
||||
warn!("Exit Canvas Paint thread failed ({})", e);
|
||||
}
|
||||
Some(canvas_exit_receiver)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
debug!("Exiting WebGPU threads.");
|
||||
#[cfg(feature = "webgpu")]
|
||||
|
@ -2714,7 +2713,9 @@ where
|
|||
|
||||
// Wait for the canvas thread to exit before shutting down the font service, as
|
||||
// canvas might still be using the system font service before shutting down.
|
||||
let _ = canvas_exit_receiver.recv();
|
||||
if let Some(canvas_exit_receiver) = canvas_exit_receiver {
|
||||
let _ = canvas_exit_receiver.recv();
|
||||
}
|
||||
|
||||
debug!("Exiting the system font service thread.");
|
||||
self.system_font_service.exit();
|
||||
|
@ -4493,8 +4494,11 @@ where
|
|||
response_sender: IpcSender<(IpcSender<CanvasMsg>, CanvasId, ImageKey)>,
|
||||
) {
|
||||
let (canvas_data_sender, canvas_data_receiver) = unbounded();
|
||||
let (canvas_sender, canvas_ipc_sender) = self
|
||||
.canvas
|
||||
.get_or_init(|| self.create_canvas_paint_thread());
|
||||
|
||||
if let Err(e) = self.canvas_sender.send(ConstellationCanvasMsg::Create {
|
||||
if let Err(e) = canvas_sender.send(ConstellationCanvasMsg::Create {
|
||||
sender: canvas_data_sender,
|
||||
size,
|
||||
}) {
|
||||
|
@ -4504,8 +4508,7 @@ where
|
|||
Ok(canvas_data) => canvas_data,
|
||||
Err(e) => return warn!("Create canvas paint thread id response failed ({})", e),
|
||||
};
|
||||
if let Err(e) = response_sender.send((self.canvas_ipc_sender.clone(), canvas_id, image_key))
|
||||
{
|
||||
if let Err(e) = response_sender.send((canvas_ipc_sender.clone(), canvas_id, image_key)) {
|
||||
warn!("Create canvas paint thread response failed ({})", e);
|
||||
}
|
||||
}
|
||||
|
@ -5745,4 +5748,12 @@ where
|
|||
warn!("Could not sent paint metric event to pipeline: {pipeline_id:?}: {error:?}");
|
||||
}
|
||||
}
|
||||
|
||||
fn create_canvas_paint_thread(&self) -> (Sender<ConstellationCanvasMsg>, IpcSender<CanvasMsg>) {
|
||||
CanvasPaintThread::start(
|
||||
self.compositor_proxy.cross_process_compositor_api.clone(),
|
||||
self.system_font_service.clone(),
|
||||
self.public_resource_threads.clone(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,6 @@ base = { workspace = true }
|
|||
bincode = { workspace = true }
|
||||
bluetooth = { path = "../bluetooth", optional = true }
|
||||
bluetooth_traits = { workspace = true, optional = true }
|
||||
canvas = { path = "../canvas" }
|
||||
webgl = { path = "../webgl", default-features = false }
|
||||
canvas_traits = { workspace = true }
|
||||
compositing = { path = "../compositing" }
|
||||
|
|
|
@ -39,7 +39,6 @@ use base::id::{PipelineNamespace, PipelineNamespaceId};
|
|||
use bluetooth::BluetoothThreadFactory;
|
||||
#[cfg(feature = "bluetooth")]
|
||||
use bluetooth_traits::BluetoothRequest;
|
||||
use canvas::canvas_paint_thread::CanvasPaintThread;
|
||||
use canvas_traits::webgl::{GlType, WebGLThreads};
|
||||
use clipboard_delegate::StringRequest;
|
||||
pub use compositing::WebRenderDebugOption;
|
||||
|
@ -115,7 +114,7 @@ use webview::WebViewInner;
|
|||
#[cfg(feature = "webxr")]
|
||||
pub use webxr;
|
||||
pub use {
|
||||
background_hang_monitor, base, canvas, canvas_traits, devtools, devtools_traits, euclid, fonts,
|
||||
background_hang_monitor, base, canvas_traits, devtools, devtools_traits, euclid, fonts,
|
||||
ipc_channel, layout_api, media, net, net_traits, profile, profile_traits, script,
|
||||
script_traits, servo_config as config, servo_config, servo_geometry, servo_url, style,
|
||||
style_traits, webrender_api,
|
||||
|
@ -1095,12 +1094,6 @@ fn create_constellation(
|
|||
.to_proxy(),
|
||||
);
|
||||
|
||||
let (canvas_create_sender, canvas_ipc_sender) = CanvasPaintThread::start(
|
||||
compositor_proxy.cross_process_compositor_api.clone(),
|
||||
system_font_service.clone(),
|
||||
public_resource_threads.clone(),
|
||||
);
|
||||
|
||||
let initial_state = InitialConstellationState {
|
||||
compositor_proxy,
|
||||
embedder_proxy,
|
||||
|
@ -1133,8 +1126,6 @@ fn create_constellation(
|
|||
opts.random_pipeline_closure_probability,
|
||||
opts.random_pipeline_closure_seed,
|
||||
opts.hard_fail,
|
||||
canvas_create_sender,
|
||||
canvas_ipc_sender,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue