aboutsummaryrefslogtreecommitdiffstats
path: root/components/shared
diff options
context:
space:
mode:
Diffstat (limited to 'components/shared')
-rw-r--r--components/shared/compositing/lib.rs55
-rw-r--r--components/shared/net/image_cache.rs4
-rw-r--r--components/shared/script/lib.rs8
-rw-r--r--components/shared/script/script_msg.rs10
-rw-r--r--components/shared/script_layout/lib.rs4
-rw-r--r--components/shared/webrender/lib.rs546
6 files changed, 284 insertions, 343 deletions
diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs
index e3c0c079037..f4afdc211b2 100644
--- a/components/shared/compositing/lib.rs
+++ b/components/shared/compositing/lib.rs
@@ -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"),
}
}
}
diff --git a/components/shared/net/image_cache.rs b/components/shared/net/image_cache.rs
index 317fd1b66ef..c587eab13b3 100644
--- a/components/shared/net/image_cache.rs
+++ b/components/shared/net/image_cache.rs
@@ -10,7 +10,7 @@ use malloc_size_of_derive::MallocSizeOf;
use pixels::{Image, ImageMetadata};
use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl};
-use webrender_traits::WebRenderNetApi;
+use webrender_traits::CrossProcessCompositorApi;
use crate::request::CorsSettings;
use crate::FetchResponseMsg;
@@ -99,7 +99,7 @@ pub enum ImageCacheResult {
}
pub trait ImageCache: Sync + Send {
- fn new(webrender_api: WebRenderNetApi) -> Self
+ fn new(compositor_api: CrossProcessCompositorApi) -> Self
where
Self: Sized;
diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs
index 1ab9e518731..c3bb72156b4 100644
--- a/components/shared/script/lib.rs
+++ b/components/shared/script/lib.rs
@@ -58,7 +58,9 @@ use style_traits::{CSSPixel, SpeculativePainter};
use webgpu::WebGPUMsg;
use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel};
use webrender_api::{DocumentId, ExternalScrollId, ImageKey};
-use webrender_traits::{UntrustedNodeAddress as WebRenderUntrustedNodeAddress, WebRenderScriptApi};
+use webrender_traits::{
+ CrossProcessCompositorApi, UntrustedNodeAddress as WebRenderUntrustedNodeAddress,
+};
pub use crate::script_msg::{
DOMMessage, EventResult, HistoryEntryReplacement, IFrameSizeMsg, Job, JobError, JobResult,
@@ -659,8 +661,8 @@ pub struct InitialScriptState {
pub webxr_registry: webxr_api::Registry,
/// The Webrender document ID associated with this thread.
pub webrender_document: DocumentId,
- /// FIXME(victor): The Webrender API sender in this constellation's pipeline
- pub webrender_api_sender: WebRenderScriptApi,
+ /// Access to the compositor across a process boundary.
+ pub compositor_api: CrossProcessCompositorApi,
/// Application window's GL Context for Media player
pub player_context: WindowGLContext,
}
diff --git a/components/shared/script/script_msg.rs b/components/shared/script/script_msg.rs
index ee8e8da1386..5689395ef32 100644
--- a/components/shared/script/script_msg.rs
+++ b/components/shared/script/script_msg.rs
@@ -24,7 +24,6 @@ use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl};
use style_traits::CSSPixel;
use webgpu::{wgc, WebGPU, WebGPUResponse};
-use webrender_api::units::{DeviceIntPoint, DeviceIntSize};
use crate::{
AnimationState, AuxiliaryBrowsingContextLoadInfo, BroadcastMsg, DocumentState,
@@ -245,12 +244,6 @@ pub enum ScriptMsg {
ForwardDOMMessage(DOMMessage, ServoUrl),
/// <https://w3c.github.io/ServiceWorker/#schedule-job-algorithm>
ScheduleJob(Job),
- /// Get Window Informations size and position
- GetClientWindow(IpcSender<(DeviceIntSize, DeviceIntPoint)>),
- /// Get the screen size (pixel)
- GetScreenSize(IpcSender<DeviceIntSize>),
- /// Get the available screen size (pixel)
- GetScreenAvailSize(IpcSender<DeviceIntSize>),
/// Notifies the constellation about media session events
/// (i.e. when there is metadata for the active media session, playback state changes...).
MediaSessionEvent(PipelineId, MediaSessionEvent),
@@ -318,9 +311,6 @@ impl fmt::Debug for ScriptMsg {
PipelineExited => "PipelineExited",
ForwardDOMMessage(..) => "ForwardDOMMessage",
ScheduleJob(..) => "ScheduleJob",
- GetClientWindow(..) => "GetClientWindow",
- GetScreenSize(..) => "GetScreenSize",
- GetScreenAvailSize(..) => "GetScreenAvailSize",
MediaSessionEvent(..) => "MediaSessionEvent",
RequestAdapter(..) => "RequestAdapter",
GetWebGPUChan(..) => "GetWebGPUChan",
diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs
index 1ad180411d3..228fd03556e 100644
--- a/components/shared/script_layout/lib.rs
+++ b/components/shared/script_layout/lib.rs
@@ -53,7 +53,7 @@ use style::stylesheets::Stylesheet;
use style::Atom;
use style_traits::CSSPixel;
use webrender_api::ImageKey;
-use webrender_traits::WebRenderScriptApi;
+use webrender_traits::CrossProcessCompositorApi;
pub type GenericLayoutData = dyn Any + Send + Sync;
@@ -177,7 +177,7 @@ pub struct LayoutConfig {
pub resource_threads: ResourceThreads,
pub system_font_service: Arc<SystemFontServiceProxy>,
pub time_profiler_chan: time::ProfilerChan,
- pub webrender_api_sender: WebRenderScriptApi,
+ pub compositor_api: CrossProcessCompositorApi,
pub paint_time_metrics: PaintTimeMetrics,
pub window_size: WindowSizeData,
}
diff --git a/components/shared/webrender/lib.rs b/components/shared/webrender/lib.rs
index 3e51e6bc6ea..807c8909d61 100644
--- a/components/shared/webrender/lib.rs
+++ b/components/shared/webrender/lib.rs
@@ -7,11 +7,11 @@
pub mod display_list;
pub mod rendering_context;
+use core::fmt;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use base::id::PipelineId;
-use crossbeam_channel::Sender;
use display_list::{CompositorDisplayListInfo, ScrollTreeNodeId};
use embedder_traits::Cursor;
use euclid::default::Size2D;
@@ -19,7 +19,7 @@ use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
use libc::c_void;
use log::warn;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect};
+use webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePoint, LayoutPoint, TexelRect};
use webrender_api::{
BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData,
ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId,
@@ -29,6 +29,261 @@ use webrender_api::{
pub use crate::rendering_context::RenderingContext;
+#[derive(Deserialize, Serialize)]
+pub enum CrossProcessCompositorMessage {
+ /// Inform WebRender of the existence of this pipeline.
+ SendInitialTransaction(WebRenderPipelineId),
+ /// Perform a scroll operation.
+ SendScrollNode(WebRenderPipelineId, LayoutPoint, ExternalScrollId),
+ /// Inform WebRender of a new display list for the given pipeline.
+ SendDisplayList {
+ /// The [CompositorDisplayListInfo] that describes the display list being sent.
+ display_list_info: Box<CompositorDisplayListInfo>,
+ /// 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.
+ display_list_receiver: ipc::IpcBytesReceiver,
+ },
+ /// Perform a hit test operation. The result will be returned via
+ /// the provided channel sender.
+ HitTest(
+ Option<WebRenderPipelineId>,
+ DevicePoint,
+ HitTestFlags,
+ IpcSender<Vec<CompositorHitTestResult>>,
+ ),
+ /// Create a new image key. The result will be returned via the
+ /// provided channel sender.
+ GenerateImageKey(IpcSender<ImageKey>),
+ /// Add an image with the given data and `ImageKey`.
+ AddImage(ImageKey, ImageDescriptor, SerializableImageData),
+ /// Perform a resource update operation.
+ UpdateImages(Vec<ImageUpdate>),
+
+ /// Generate a new batch of font keys which can be used to allocate
+ /// keys asynchronously.
+ GenerateFontKeys(
+ usize,
+ usize,
+ IpcSender<(Vec<FontKey>, Vec<FontInstanceKey>)>,
+ ),
+ /// Add a font with the given data and font key.
+ AddFont(FontKey, Arc<IpcSharedMemory>, u32),
+ /// Add a system font with the given font key and handle.
+ AddSystemFont(FontKey, NativeFontHandle),
+ /// Add an instance of a font with the given instance key.
+ AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
+ /// Remove the given font resources from our WebRender instance.
+ RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
+
+ /// Get the client window size and position.
+ GetClientWindowRect(IpcSender<DeviceIntRect>),
+ /// Get the size of the screen that the client window inhabits.
+ GetScreenSize(IpcSender<DeviceIntSize>),
+ /// Get the available screen size (without toolbars and docks) for the screen
+ /// the client window inhabits.
+ GetAvailableScreenSize(IpcSender<DeviceIntSize>),
+}
+
+impl fmt::Debug for CrossProcessCompositorMessage {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Self::AddImage(..) => f.write_str("AddImage"),
+ Self::GenerateFontKeys(..) => f.write_str("GenerateFontKeys"),
+ Self::AddSystemFont(..) => f.write_str("AddSystemFont"),
+ Self::SendInitialTransaction(..) => f.write_str("SendInitialTransaction"),
+ Self::SendScrollNode(..) => f.write_str("SendScrollNode"),
+ Self::SendDisplayList { .. } => f.write_str("SendDisplayList"),
+ Self::HitTest(..) => f.write_str("HitTest"),
+ Self::GenerateImageKey(..) => f.write_str("GenerateImageKey"),
+ Self::UpdateImages(..) => f.write_str("UpdateImages"),
+ Self::RemoveFonts(..) => f.write_str("RemoveFonts"),
+ Self::AddFontInstance(..) => f.write_str("AddFontInstance"),
+ Self::AddFont(..) => f.write_str("AddFont"),
+ Self::GetClientWindowRect(..) => f.write_str("GetClientWindowRect"),
+ Self::GetScreenSize(..) => f.write_str("GetScreenSize"),
+ Self::GetAvailableScreenSize(..) => f.write_str("GetAvailableScreenSize"),
+ }
+ }
+}
+
+/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
+#[derive(Clone, Deserialize, Serialize)]
+pub struct CrossProcessCompositorApi(pub IpcSender<CrossProcessCompositorMessage>);
+
+impl CrossProcessCompositorApi {
+ /// Create a new [`CrossProcessCompositorApi`] struct that does not have a listener on the other
+ /// end to use for unit testing.
+ pub fn dummy() -> Self {
+ let (sender, _) = ipc::channel().unwrap();
+ Self(sender)
+ }
+
+ /// Get the sender for this proxy.
+ pub fn sender(&self) -> &IpcSender<CrossProcessCompositorMessage> {
+ &self.0
+ }
+
+ /// Inform WebRender of the existence of this pipeline.
+ pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
+ if let Err(e) = self
+ .0
+ .send(CrossProcessCompositorMessage::SendInitialTransaction(
+ pipeline,
+ ))
+ {
+ warn!("Error sending initial transaction: {}", e);
+ }
+ }
+
+ /// Perform a scroll operation.
+ pub fn send_scroll_node(
+ &self,
+ pipeline_id: WebRenderPipelineId,
+ point: LayoutPoint,
+ scroll_id: ExternalScrollId,
+ ) {
+ if let Err(e) = self.0.send(CrossProcessCompositorMessage::SendScrollNode(
+ pipeline_id,
+ point,
+ scroll_id,
+ )) {
+ warn!("Error sending scroll node: {}", e);
+ }
+ }
+
+ /// Inform WebRender of a new display list for the given pipeline.
+ pub fn send_display_list(
+ &self,
+ display_list_info: CompositorDisplayListInfo,
+ list: BuiltDisplayList,
+ ) {
+ let (display_list_data, display_list_descriptor) = list.into_data();
+ let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
+ if let Err(e) = self.0.send(CrossProcessCompositorMessage::SendDisplayList {
+ display_list_info: Box::new(display_list_info),
+ display_list_descriptor,
+ display_list_receiver,
+ }) {
+ warn!("Error sending display list: {}", e);
+ }
+
+ if let Err(error) = display_list_sender.send(&display_list_data.items_data) {
+ 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);
+ }
+ if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) {
+ warn!("Error sending display spatial tree: {}", error);
+ }
+ }
+
+ /// Perform a hit test operation. Blocks until the operation is complete and
+ /// and a result is available.
+ pub fn hit_test(
+ &self,
+ pipeline: Option<WebRenderPipelineId>,
+ point: DevicePoint,
+ flags: HitTestFlags,
+ ) -> Vec<CompositorHitTestResult> {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.0
+ .send(CrossProcessCompositorMessage::HitTest(
+ pipeline, point, flags, sender,
+ ))
+ .expect("error sending hit test");
+ receiver.recv().expect("error receiving hit test result")
+ }
+
+ /// Create a new image key. Blocks until the key is available.
+ pub fn generate_image_key(&self) -> Option<ImageKey> {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.0
+ .send(CrossProcessCompositorMessage::GenerateImageKey(sender))
+ .ok()?;
+ receiver.recv().ok()
+ }
+
+ pub fn add_image(
+ &self,
+ key: ImageKey,
+ descriptor: ImageDescriptor,
+ data: SerializableImageData,
+ ) {
+ if let Err(e) = self.0.send(CrossProcessCompositorMessage::AddImage(
+ key, descriptor, data,
+ )) {
+ warn!("Error sending image update: {}", e);
+ }
+ }
+
+ /// Perform an image resource update operation.
+ pub fn update_images(&self, updates: Vec<ImageUpdate>) {
+ if let Err(e) = self
+ .0
+ .send(CrossProcessCompositorMessage::UpdateImages(updates))
+ {
+ warn!("error sending image updates: {}", e);
+ }
+ }
+
+ pub fn remove_unused_font_resources(
+ &self,
+ keys: Vec<FontKey>,
+ instance_keys: Vec<FontInstanceKey>,
+ ) {
+ if keys.is_empty() && instance_keys.is_empty() {
+ return;
+ }
+ let _ = self.0.send(CrossProcessCompositorMessage::RemoveFonts(
+ keys,
+ instance_keys,
+ ));
+ }
+
+ pub fn add_font_instance(
+ &self,
+ font_instance_key: FontInstanceKey,
+ font_key: FontKey,
+ size: f32,
+ flags: FontInstanceFlags,
+ ) {
+ let _x = self.0.send(CrossProcessCompositorMessage::AddFontInstance(
+ font_instance_key,
+ font_key,
+ size,
+ flags,
+ ));
+ }
+
+ pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
+ let _ = self.0.send(CrossProcessCompositorMessage::AddFont(
+ font_key, data, index,
+ ));
+ }
+
+ pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
+ let _ = self.0.send(CrossProcessCompositorMessage::AddSystemFont(
+ font_key, handle,
+ ));
+ }
+
+ pub fn fetch_font_keys(
+ &self,
+ number_of_font_keys: usize,
+ number_of_font_instance_keys: usize,
+ ) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
+ let (sender, receiver) = ipc_channel::ipc::channel().expect("Could not create IPC channel");
+ let _ = self.0.send(CrossProcessCompositorMessage::GenerateFontKeys(
+ number_of_font_keys,
+ number_of_font_instance_keys,
+ sender,
+ ));
+ receiver.recv().unwrap()
+ }
+}
+
/// This trait is used as a bridge between the different GL clients
/// in Servo that handles WebRender ExternalImages and the WebRender
/// ExternalImageHandler API.
@@ -183,303 +438,34 @@ impl ExternalImageHandler for WebrenderExternalImageHandlers {
}
}
-pub trait WebRenderFontApi {
- fn add_font_instance(
- &self,
- font_instance_key: FontInstanceKey,
- font_key: FontKey,
- size: f32,
- flags: FontInstanceFlags,
- );
- fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32);
- fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle);
- fn fetch_font_keys(
- &self,
- number_of_font_keys: usize,
- number_of_font_instance_keys: usize,
- ) -> (Vec<FontKey>, Vec<FontInstanceKey>);
-}
-
-pub enum CanvasToCompositorMsg {
- GenerateKey(Sender<ImageKey>),
- UpdateImages(Vec<ImageUpdate>),
-}
-
-pub enum FontToCompositorMsg {
- GenerateKeys(usize, usize, Sender<(Vec<FontKey>, Vec<FontInstanceKey>)>),
- AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
- AddFont(FontKey, u32, Arc<IpcSharedMemory>),
- AddSystemFont(FontKey, NativeFontHandle),
-}
-
-#[derive(Deserialize, Serialize)]
-pub enum NetToCompositorMsg {
- AddImage(ImageKey, ImageDescriptor, ImageData),
- GenerateImageKey(IpcSender<ImageKey>),
-}
-
-/// The set of WebRender operations that can be initiated by the content process.
-#[derive(Deserialize, Serialize)]
-pub enum ScriptToCompositorMsg {
- /// Inform WebRender of the existence of this pipeline.
- SendInitialTransaction(WebRenderPipelineId),
- /// Perform a scroll operation.
- SendScrollNode(WebRenderPipelineId, LayoutPoint, ExternalScrollId),
- /// Inform WebRender of a new display list for the given pipeline.
- SendDisplayList {
- /// The [CompositorDisplayListInfo] that describes the display list being sent.
- display_list_info: Box<CompositorDisplayListInfo>,
- /// 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.
- display_list_receiver: ipc::IpcBytesReceiver,
- },
- /// Perform a hit test operation. The result will be returned via
- /// the provided channel sender.
- HitTest(
- Option<WebRenderPipelineId>,
- DevicePoint,
- HitTestFlags,
- IpcSender<Vec<CompositorHitTestResult>>,
- ),
- /// Create a new image key. The result will be returned via the
- /// provided channel sender.
- GenerateImageKey(IpcSender<ImageKey>),
- /// Perform a resource update operation.
- UpdateImages(Vec<SerializedImageUpdate>),
- /// Remove the given font resources from our WebRender instance.
- RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
- AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
- AddFont(FontKey, Arc<IpcSharedMemory>, u32),
-}
-
-/// A mechanism to send messages from networking to the WebRender instance.
-#[derive(Clone, Deserialize, Serialize)]
-pub struct WebRenderNetApi(IpcSender<NetToCompositorMsg>);
-
-impl WebRenderNetApi {
- pub fn new(sender: IpcSender<NetToCompositorMsg>) -> Self {
- Self(sender)
- }
-
- pub fn generate_image_key(&self) -> ImageKey {
- let (sender, receiver) = ipc::channel().unwrap();
- self.0
- .send(NetToCompositorMsg::GenerateImageKey(sender))
- .expect("error sending image key generation");
- receiver.recv().expect("error receiving image key result")
- }
-
- pub fn add_image(&self, key: ImageKey, descriptor: ImageDescriptor, data: ImageData) {
- if let Err(e) = self
- .0
- .send(NetToCompositorMsg::AddImage(key, descriptor, data))
- {
- warn!("Error sending image update: {}", e);
- }
- }
-}
-
-/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
-#[derive(Clone, Deserialize, Serialize)]
-pub struct WebRenderScriptApi(IpcSender<ScriptToCompositorMsg>);
-
-impl WebRenderScriptApi {
- /// Create a new [`WebRenderScriptApi`] object that wraps the provided channel sender.
- pub fn new(sender: IpcSender<ScriptToCompositorMsg>) -> Self {
- Self(sender)
- }
-
- /// Create a new [`WebRenderScriptApi`] object that does not have a listener on the
- /// other end.
- pub fn dummy() -> Self {
- let (sender, _) = ipc::channel().unwrap();
- Self::new(sender)
- }
-
- /// Get the sender for this proxy.
- pub fn sender(&self) -> &IpcSender<ScriptToCompositorMsg> {
- &self.0
- }
-
- /// Inform WebRender of the existence of this pipeline.
- pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
- if let Err(e) = self
- .0
- .send(ScriptToCompositorMsg::SendInitialTransaction(pipeline))
- {
- warn!("Error sending initial transaction: {}", e);
- }
- }
-
- /// Perform a scroll operation.
- pub fn send_scroll_node(
- &self,
- pipeline_id: WebRenderPipelineId,
- point: LayoutPoint,
- scroll_id: ExternalScrollId,
- ) {
- if let Err(e) = self.0.send(ScriptToCompositorMsg::SendScrollNode(
- pipeline_id,
- point,
- scroll_id,
- )) {
- warn!("Error sending scroll node: {}", e);
- }
- }
-
- /// Inform WebRender of a new display list for the given pipeline.
- pub fn send_display_list(
- &self,
- display_list_info: CompositorDisplayListInfo,
- list: BuiltDisplayList,
- ) {
- let (display_list_data, display_list_descriptor) = list.into_data();
- let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
- if let Err(e) = self.0.send(ScriptToCompositorMsg::SendDisplayList {
- display_list_info: Box::new(display_list_info),
- display_list_descriptor,
- display_list_receiver,
- }) {
- warn!("Error sending display list: {}", e);
- }
- if let Err(error) = display_list_sender.send(&display_list_data.items_data) {
- 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);
- }
- if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) {
- warn!("Error sending display spatial tree: {}", error);
- }
- }
-
- /// Perform a hit test operation. Blocks until the operation is complete and
- /// and a result is available.
- pub fn hit_test(
- &self,
- pipeline: Option<WebRenderPipelineId>,
- point: DevicePoint,
- flags: HitTestFlags,
- ) -> Vec<CompositorHitTestResult> {
- let (sender, receiver) = ipc::channel().unwrap();
- self.0
- .send(ScriptToCompositorMsg::HitTest(
- pipeline, point, flags, sender,
- ))
- .expect("error sending hit test");
- receiver.recv().expect("error receiving hit test result")
- }
-
- /// Create a new image key. Blocks until the key is available.
- pub fn generate_image_key(&self) -> Option<ImageKey> {
- let (sender, receiver) = ipc::channel().unwrap();
- self.0
- .send(ScriptToCompositorMsg::GenerateImageKey(sender))
- .ok()?;
- receiver.recv().ok()
- }
-
- /// Perform a resource update operation.
- pub fn update_images(&self, updates: Vec<ImageUpdate>) {
- let mut senders = Vec::new();
- // Convert `ImageUpdate` to `SerializedImageUpdate` because `ImageData` may contain large
- // byes. With this conversion, we send `IpcBytesReceiver` instead and use it to send the
- // actual bytes.
- let updates = updates
- .into_iter()
- .map(|update| match update {
- ImageUpdate::AddImage(k, d, data) => {
- let data = match data {
- ImageData::Raw(r) => {
- let (sender, receiver) = ipc::bytes_channel().unwrap();
- senders.push((sender, r));
- SerializedImageData::Raw(receiver)
- },
- ImageData::External(e) => SerializedImageData::External(e),
- };
- SerializedImageUpdate::AddImage(k, d, data)
- },
- ImageUpdate::DeleteImage(k) => SerializedImageUpdate::DeleteImage(k),
- ImageUpdate::UpdateImage(k, d, data) => {
- let data = match data {
- ImageData::Raw(r) => {
- let (sender, receiver) = ipc::bytes_channel().unwrap();
- senders.push((sender, r));
- SerializedImageData::Raw(receiver)
- },
- ImageData::External(e) => SerializedImageData::External(e),
- };
- SerializedImageUpdate::UpdateImage(k, d, data)
- },
- })
- .collect();
-
- if let Err(e) = self.0.send(ScriptToCompositorMsg::UpdateImages(updates)) {
- warn!("error sending image updates: {}", e);
- }
-
- senders.into_iter().for_each(|(tx, data)| {
- if let Err(e) = tx.send(&data) {
- warn!("error sending image data: {}", e);
- }
- });
- }
-
- pub fn remove_unused_font_resources(
- &self,
- keys: Vec<FontKey>,
- instance_keys: Vec<FontInstanceKey>,
- ) {
- if keys.is_empty() && instance_keys.is_empty() {
- return;
- }
- let _ = self
- .0
- .send(ScriptToCompositorMsg::RemoveFonts(keys, instance_keys));
- }
-}
-
#[derive(Deserialize, Serialize)]
/// Serializable image updates that must be performed by WebRender.
pub enum ImageUpdate {
/// Register a new image.
- AddImage(ImageKey, ImageDescriptor, ImageData),
+ AddImage(ImageKey, ImageDescriptor, SerializableImageData),
/// Delete a previously registered image registration.
DeleteImage(ImageKey),
/// Update an existing image registration.
- UpdateImage(ImageKey, ImageDescriptor, ImageData),
-}
-
-#[derive(Deserialize, Serialize)]
-/// Serialized `ImageUpdate`.
-pub enum SerializedImageUpdate {
- /// Register a new image.
- AddImage(ImageKey, ImageDescriptor, SerializedImageData),
- /// Delete a previously registered image registration.
- DeleteImage(ImageKey),
- /// Update an existing image registration.
- UpdateImage(ImageKey, ImageDescriptor, SerializedImageData),
+ UpdateImage(ImageKey, ImageDescriptor, SerializableImageData),
}
#[derive(Debug, Deserialize, Serialize)]
/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too
/// slow.
-pub enum SerializedImageData {
+pub enum SerializableImageData {
/// A simple series of bytes, provided by the embedding and owned by WebRender.
/// The format is stored out-of-band, currently in ImageDescriptor.
- Raw(ipc::IpcBytesReceiver),
+ Raw(IpcSharedMemory),
/// An image owned by the embedding, and referenced by WebRender. This may
/// take the form of a texture or a heap-allocated buffer.
External(ExternalImageData),
}
-impl SerializedImageData {
- /// Convert to ``ImageData`.
- pub fn to_image_data(&self) -> Result<ImageData, ipc::IpcError> {
- match self {
- SerializedImageData::Raw(rx) => rx.recv().map(ImageData::new),
- SerializedImageData::External(image) => Ok(ImageData::External(*image)),
+impl From<SerializableImageData> for ImageData {
+ fn from(value: SerializableImageData) -> Self {
+ match value {
+ SerializableImageData::Raw(shared_memory) => ImageData::new(shared_memory.to_vec()),
+ SerializableImageData::External(image) => ImageData::External(image),
}
}
}