compositor: Create a single cross-process compositor API (#33619)

Instead of exposing many different kinds of messages to the compositor
that are routed through the constellation, expose a single message type
which can be sent across IPC channels. In addition, this IPC channel and
the route to the crossbeam channel with the compositor is created along
with the `CompositorProxy`, simplifying what needs to be passed around
during pipeline initialization.

Previously, some image updates (from video) were sent over IPC with a
special serialization routine and some were sent via crossbeam channels
(canvas). Now all updates go over the IPC channel `IpcSharedMemory` is
used to avoid serialization penalties. This should improve performance
and reduce copies for video, but add a memory copy overhead for canvas.
This will improve in the future when canvas renders directly into a
texture.

All-in-all this is a simplification which opens the path toward having a
standard compositor API and reduces the number of duplicate messages and
proxying that had to happen in libservo.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2024-10-03 16:42:04 +02:00 committed by GitHub
parent 986c3a38a3
commit f2f5614ad6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 547 additions and 801 deletions

View file

@ -43,6 +43,7 @@ use servo_config::prefs;
use servo_config::prefs::PrefValue;
use servo_url::ServoUrl;
use webrender_api::DocumentId;
use webrender_traits::CrossProcessCompositorApi;
use crate::event_loop::EventLoop;
use crate::sandboxing::{spawn_multiprocess, UnprivilegedContent};
@ -183,12 +184,6 @@ pub struct InitialPipelineState {
/// compositor threads after spawning a pipeline.
pub prev_throttled: bool,
/// Webrender api.
pub webrender_image_api_sender: webrender_traits::WebRenderNetApi,
/// Webrender api.
pub webrender_api_sender: webrender_traits::WebRenderScriptApi,
/// The ID of the document processed by this script thread.
pub webrender_document: DocumentId,
@ -293,9 +288,11 @@ impl Pipeline {
opts: (*opts::get()).clone(),
prefs: prefs::pref_map().iter().collect(),
pipeline_namespace_id: state.pipeline_namespace_id,
webrender_api_sender: state.webrender_api_sender,
webrender_image_api_sender: state.webrender_image_api_sender,
webrender_document: state.webrender_document,
cross_process_compositor_api: state
.compositor_proxy
.cross_process_compositor_api
.clone(),
webgl_chan: state.webgl_chan,
webxr_registry: state.webxr_registry,
player_context: state.player_context,
@ -498,8 +495,7 @@ pub struct UnprivilegedPipelineContent {
opts: Opts,
prefs: HashMap<String, PrefValue>,
pipeline_namespace_id: PipelineNamespaceId,
webrender_api_sender: webrender_traits::WebRenderScriptApi,
webrender_image_api_sender: webrender_traits::WebRenderNetApi,
cross_process_compositor_api: CrossProcessCompositorApi,
webrender_document: DocumentId,
webgl_chan: Option<WebGLPipeline>,
webxr_registry: webxr_api::Registry,
@ -518,7 +514,9 @@ impl UnprivilegedPipelineContent {
// Idempotent in single-process mode.
PipelineNamespace::set_installer_sender(self.namespace_request_sender);
let image_cache = Arc::new(ImageCacheImpl::new(self.webrender_image_api_sender.clone()));
let image_cache = Arc::new(ImageCacheImpl::new(
self.cross_process_compositor_api.clone(),
));
let (content_process_shutdown_chan, content_process_shutdown_port) = unbounded();
STF::create(
InitialScriptState {
@ -545,7 +543,7 @@ impl UnprivilegedPipelineContent {
webgl_chan: self.webgl_chan,
webxr_registry: self.webxr_registry,
webrender_document: self.webrender_document,
webrender_api_sender: self.webrender_api_sender.clone(),
compositor_api: self.cross_process_compositor_api.clone(),
player_context: self.player_context.clone(),
inherited_secure_context: self.load_data.inherited_secure_context,
},