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

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-09 10:30:24 -07:00 committed by GitHub
parent 30cbf01280
commit 9195344b75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 547 additions and 800 deletions

View file

@ -21,15 +21,18 @@ use script_traits::{
AnimationState, ConstellationControlMsg, EventResult, MouseButton, MouseEventType,
};
use style_traits::CSSPixel;
use webrender_api::units::{DeviceIntPoint, DeviceIntSize, DeviceRect};
use webrender_api::units::DeviceRect;
use webrender_api::DocumentId;
use webrender_traits::{
CanvasToCompositorMsg, FontToCompositorMsg, NetToCompositorMsg, ScriptToCompositorMsg,
};
use webrender_traits::{CrossProcessCompositorApi, CrossProcessCompositorMessage};
/// Sends messages to the compositor.
#[derive(Clone)]
pub struct CompositorProxy {
pub sender: Sender<CompositorMsg>,
/// Access to [`Self::sender`] that is possible to send across an IPC
/// channel. These messages are routed via the router thread to
/// [`Self::sender`].
pub cross_process_compositor_api: CrossProcessCompositorApi,
pub event_loop_waker: Box<dyn EventLoopWaker>,
}
@ -42,15 +45,6 @@ impl CompositorProxy {
}
}
impl Clone for CompositorProxy {
fn clone(&self) -> CompositorProxy {
CompositorProxy {
sender: self.sender.clone(),
event_loop_waker: self.event_loop_waker.clone(),
}
}
}
/// The port that the compositor receives messages on.
pub struct CompositorReceiver {
pub receiver: Receiver<CompositorMsg>,
@ -114,16 +108,9 @@ pub enum CompositorMsg {
/// WebDriver mouse move event
WebDriverMouseMoveEvent(f32, f32),
/// Get Window Informations size and position.
GetClientWindow(IpcSender<(DeviceIntSize, DeviceIntPoint)>),
/// Get screen size.
GetScreenSize(IpcSender<DeviceIntSize>),
/// Get screen available size.
GetScreenAvailSize(IpcSender<DeviceIntSize>),
/// Messages forwarded to the compositor by the constellation from other crates. These
/// messages are mainly passed on from the compositor to WebRender.
Forwarded(ForwardedToCompositorMsg),
CrossProcess(CrossProcessCompositorMessage),
}
pub struct SendableFrameTree {
@ -139,27 +126,6 @@ pub struct CompositionPipeline {
pub script_chan: IpcSender<ConstellationControlMsg>,
}
/// Messages forwarded by the Constellation to the Compositor.
pub enum ForwardedToCompositorMsg {
Layout(ScriptToCompositorMsg),
Net(NetToCompositorMsg),
SystemFontService(FontToCompositorMsg),
Canvas(CanvasToCompositorMsg),
}
impl Debug for ForwardedToCompositorMsg {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
match self {
ForwardedToCompositorMsg::Layout(_) => write!(f, "Layout(ScriptToCompositorMsg)"),
ForwardedToCompositorMsg::Net(_) => write!(f, "Net(NetToCompositorMsg)"),
ForwardedToCompositorMsg::SystemFontService(_) => {
write!(f, "SystemFontService(FontToCompositorMsg)")
},
ForwardedToCompositorMsg::Canvas(_) => write!(f, "Canvas(CanvasToCompositorMsg)"),
}
}
}
impl Debug for CompositorMsg {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
match *self {
@ -183,10 +149,7 @@ impl Debug for CompositorMsg {
CompositorMsg::LoadComplete(..) => write!(f, "LoadComplete"),
CompositorMsg::WebDriverMouseButtonEvent(..) => write!(f, "WebDriverMouseButtonEvent"),
CompositorMsg::WebDriverMouseMoveEvent(..) => write!(f, "WebDriverMouseMoveEvent"),
CompositorMsg::GetClientWindow(..) => write!(f, "GetClientWindow"),
CompositorMsg::GetScreenSize(..) => write!(f, "GetScreenSize"),
CompositorMsg::GetScreenAvailSize(..) => write!(f, "GetScreenAvailSize"),
CompositorMsg::Forwarded(..) => write!(f, "Webrender"),
CompositorMsg::CrossProcess(..) => write!(f, "CrossProcess"),
}
}
}