diff options
author | Martin Robinson <mrobinson@igalia.com> | 2024-05-17 15:37:02 +0200 |
---|---|---|
committer | Martin Robinson <mrobinson@igalia.com> | 2024-05-17 18:58:54 +0200 |
commit | f02e19dc8d726751a8a51ccd5f02add6378897bc (patch) | |
tree | 4d19bb0e6b6fbccb0751dd6fe8e7b95c9f531778 | |
parent | 814445144d539771d9cad491c7d7eb230fe683b9 (diff) | |
download | servo-gfx-base-reorganization-part2.tar.gz servo-gfx-base-reorganization-part2.zip |
Move `script_traits::WebrenderIpcSender` to `webrender_traits::WebRenderScriptApi`gfx-base-reorganization-part2
-rw-r--r-- | Cargo.lock | 3 | ||||
-rw-r--r-- | components/constellation/constellation.rs | 10 | ||||
-rw-r--r-- | components/constellation/pipeline.rs | 8 | ||||
-rw-r--r-- | components/layout_thread/Cargo.toml | 1 | ||||
-rw-r--r-- | components/layout_thread/lib.rs | 7 | ||||
-rw-r--r-- | components/layout_thread_2020/Cargo.toml | 1 | ||||
-rw-r--r-- | components/layout_thread_2020/lib.rs | 7 | ||||
-rw-r--r-- | components/net/image_cache.rs | 10 | ||||
-rw-r--r-- | components/script/dom/htmlmediaelement.rs | 6 | ||||
-rw-r--r-- | components/script/dom/window.rs | 9 | ||||
-rw-r--r-- | components/script/script_thread.rs | 5 | ||||
-rw-r--r-- | components/shared/net/image_cache.rs | 4 | ||||
-rw-r--r-- | components/shared/script/lib.rs | 150 | ||||
-rw-r--r-- | components/shared/script_layout/Cargo.toml | 1 | ||||
-rw-r--r-- | components/shared/script_layout/lib.rs | 5 | ||||
-rw-r--r-- | components/shared/webrender/lib.rs | 232 |
16 files changed, 233 insertions, 226 deletions
diff --git a/Cargo.lock b/Cargo.lock index 5df0bf8e5df..29f90f157b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3347,6 +3347,7 @@ dependencies = [ "time 0.1.45", "url", "webrender_api", + "webrender_traits", ] [[package]] @@ -3383,6 +3384,7 @@ dependencies = [ "style_traits", "url", "webrender_api", + "webrender_traits", ] [[package]] @@ -5170,6 +5172,7 @@ dependencies = [ "style", "style_traits", "webrender_api", + "webrender_traits", ] [[package]] diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 26ff28df2a8..5270b037cd4 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -155,7 +155,7 @@ use style_traits::CSSPixel; use webgpu::{self, WebGPU, WebGPURequest}; use webrender::{RenderApi, RenderApiSender}; use webrender_api::DocumentId; -use webrender_traits::WebrenderExternalImageRegistry; +use webrender_traits::{WebrenderExternalImageRegistry, WebRenderNetApi, WebRenderScriptApi}; use crate::browsingcontext::{ AllBrowsingContextsIterator, BrowsingContext, FullyActiveBrowsingContextsIterator, @@ -392,11 +392,11 @@ pub struct Constellation<STF, SWF> { /// A channel for content processes to send messages that will /// be relayed to the WebRender thread. - webrender_api_ipc_sender: script_traits::WebrenderIpcSender, + webrender_api_ipc_sender: WebRenderScriptApi, /// A channel for content process image caches to send messages /// that will be relayed to the WebRender thread. - webrender_image_api_sender: webrender_traits::WebrenderIpcSender, + webrender_image_api_sender: WebRenderNetApi, /// A map of message-port Id to info. message_ports: HashMap<MessagePortId, MessagePortInfo>, @@ -785,10 +785,10 @@ where scheduler_receiver, document_states: HashMap::new(), webrender_document: state.webrender_document, - webrender_api_ipc_sender: script_traits::WebrenderIpcSender::new( + webrender_api_ipc_sender: WebRenderScriptApi::new( webrender_ipc_sender, ), - webrender_image_api_sender: webrender_traits::WebrenderIpcSender::new( + webrender_image_api_sender: WebRenderNetApi::new( webrender_image_ipc_sender, ), webrender_wgpu, diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index af1ae1304ee..9547aa8a354 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -185,10 +185,10 @@ pub struct InitialPipelineState { pub prev_throttled: bool, /// Webrender api. - pub webrender_image_api_sender: webrender_traits::WebrenderIpcSender, + pub webrender_image_api_sender: webrender_traits::WebRenderNetApi, /// Webrender api. - pub webrender_api_sender: script_traits::WebrenderIpcSender, + pub webrender_api_sender: webrender_traits::WebRenderScriptApi, /// The ID of the document processed by this script thread. pub webrender_document: DocumentId, @@ -502,8 +502,8 @@ pub struct UnprivilegedPipelineContent { opts: Opts, prefs: HashMap<String, PrefValue>, pipeline_namespace_id: PipelineNamespaceId, - webrender_api_sender: script_traits::WebrenderIpcSender, - webrender_image_api_sender: webrender_traits::WebrenderIpcSender, + webrender_api_sender: webrender_traits::WebRenderScriptApi, + webrender_image_api_sender: webrender_traits::WebRenderNetApi, webrender_document: DocumentId, webgl_chan: Option<WebGLPipeline>, webxr_registry: webxr_api::Registry, diff --git a/components/layout_thread/Cargo.toml b/components/layout_thread/Cargo.toml index 978b597212b..a95c7f9b8aa 100644 --- a/components/layout_thread/Cargo.toml +++ b/components/layout_thread/Cargo.toml @@ -45,3 +45,4 @@ style_traits = { workspace = true } time = { workspace = true } url = { workspace = true } webrender_api = { workspace = true } +webrender_traits = { workspace = true } diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index cc2f0adfe29..8cb612bd1de 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -69,7 +69,7 @@ use script_layout_interface::{ use script_traits::{ ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress, - WebrenderIpcSender, WindowSizeData, WindowSizeType, + WindowSizeData, WindowSizeType, }; use servo_arc::Arc as ServoArc; use servo_atoms::Atom; @@ -102,6 +102,7 @@ use style::traversal_flags::TraversalFlags; use style_traits::{CSSPixel, DevicePixel, SpeculativePainter}; use url::Url; use webrender_api::{units, ColorF, HitTestFlags}; +use webrender_traits::WebRenderScriptApi; /// Information needed by layout. pub struct LayoutThread { @@ -176,7 +177,7 @@ pub struct LayoutThread { registered_painters: RegisteredPaintersImpl, /// Webrender interface. - webrender_api: WebrenderIpcSender, + webrender_api: WebRenderScriptApi, /// Paint time metrics. paint_time_metrics: PaintTimeMetrics, @@ -567,7 +568,7 @@ impl LayoutThread { image_cache: Arc<dyn ImageCache>, font_cache_thread: FontCacheThread, time_profiler_chan: profile_time::ProfilerChan, - webrender_api: WebrenderIpcSender, + webrender_api: WebRenderScriptApi, paint_time_metrics: PaintTimeMetrics, window_size: WindowSizeData, ) -> LayoutThread { diff --git a/components/layout_thread_2020/Cargo.toml b/components/layout_thread_2020/Cargo.toml index 633b903e509..6b96f358b2a 100644 --- a/components/layout_thread_2020/Cargo.toml +++ b/components/layout_thread_2020/Cargo.toml @@ -41,3 +41,4 @@ style = { workspace = true } style_traits = { workspace = true } url = { workspace = true } webrender_api = { workspace = true } +webrender_traits = { workspace = true } diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index a700c52e9ba..4dd245a4925 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -55,7 +55,7 @@ use script_layout_interface::{ use script_traits::{ ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress, - WebrenderIpcSender, WindowSizeData, WindowSizeType, + WindowSizeData, WindowSizeType, }; use servo_arc::Arc as ServoArc; use servo_atoms::Atom; @@ -89,6 +89,7 @@ use style_traits::{CSSPixel, DevicePixel, SpeculativePainter}; use url::Url; use webrender_api::units::LayoutPixel; use webrender_api::{units, ExternalScrollId, HitTestFlags}; +use webrender_traits::WebRenderScriptApi; /// Information needed by layout. pub struct LayoutThread { @@ -158,7 +159,7 @@ pub struct LayoutThread { registered_painters: RegisteredPaintersImpl, /// Webrender interface. - webrender_api: WebrenderIpcSender, + webrender_api: WebRenderScriptApi, /// Paint time metrics. paint_time_metrics: PaintTimeMetrics, @@ -484,7 +485,7 @@ impl LayoutThread { image_cache: Arc<dyn ImageCache>, font_cache_thread: FontCacheThread, time_profiler_chan: profile_time::ProfilerChan, - webrender_api_sender: WebrenderIpcSender, + webrender_api_sender: WebRenderScriptApi, paint_time_metrics: PaintTimeMetrics, window_size: WindowSizeData, ) -> LayoutThread { diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs index 67d447b68f3..8fdda030da6 100644 --- a/components/net/image_cache.rs +++ b/components/net/image_cache.rs @@ -24,7 +24,7 @@ use net_traits::{ use servo_url::{ImmutableOrigin, ServoUrl}; use webrender_api::units::DeviceIntSize; use webrender_api::{ImageData, ImageDescriptor, ImageDescriptorFlags, ImageFormat}; -use webrender_traits::WebrenderIpcSender; +use webrender_traits::WebRenderNetApi; use crate::resource_thread::CoreResourceThreadPool; @@ -47,13 +47,13 @@ fn decode_bytes_sync(key: LoadKey, bytes: &[u8], cors: CorsStatus) -> DecoderMsg DecoderMsg { key, image } } -fn get_placeholder_image(webrender_api: &WebrenderIpcSender, data: &[u8]) -> Arc<Image> { +fn get_placeholder_image(webrender_api: &WebRenderNetApi, data: &[u8]) -> Arc<Image> { let mut image = load_from_memory(data, CorsStatus::Unsafe).unwrap(); set_webrender_image_key(webrender_api, &mut image); Arc::new(image) } -fn set_webrender_image_key(webrender_api: &WebrenderIpcSender, image: &mut Image) { +fn set_webrender_image_key(webrender_api: &WebRenderNetApi, image: &mut Image) { if image.id.is_some() { return; } @@ -331,7 +331,7 @@ struct ImageCacheStore { placeholder_url: ServoUrl, // Webrender API instance. - webrender_api: WebrenderIpcSender, + webrender_api: WebRenderNetApi, } impl ImageCacheStore { @@ -418,7 +418,7 @@ pub struct ImageCacheImpl { } impl ImageCache for ImageCacheImpl { - fn new(webrender_api: WebrenderIpcSender) -> ImageCacheImpl { + fn new(webrender_api: WebRenderNetApi) -> ImageCacheImpl { debug!("New image cache"); let rippy_data = resources::read_bytes(Resource::RippyPNG); diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index 1bf00c0e567..05394141df7 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -27,7 +27,7 @@ use net_traits::{ ResourceFetchTiming, ResourceTimingType, }; use script_layout_interface::HTMLMediaData; -use script_traits::WebrenderIpcSender; +use webrender_traits::WebRenderScriptApi; use servo_config::pref; use servo_media::player::audio::AudioRenderer; use servo_media::player::video::{VideoFrame, VideoFrameRenderer}; @@ -155,7 +155,7 @@ impl FrameHolder { pub struct MediaFrameRenderer { player_id: Option<u64>, - api: WebrenderIpcSender, + api: WebRenderScriptApi, current_frame: Option<(ImageKey, i32, i32)>, old_frame: Option<ImageKey>, very_old_frame: Option<ImageKey>, @@ -164,7 +164,7 @@ pub struct MediaFrameRenderer { } impl MediaFrameRenderer { - fn new(render_api_sender: WebrenderIpcSender) -> Self { + fn new(render_api_sender: WebRenderScriptApi) -> Self { Self { player_id: None, api: render_api_sender, diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index b034c9c5d29..fcba7ffcbeb 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -56,7 +56,7 @@ use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use script_traits::{ ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData, ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEventId, - TimerSchedulerMsg, WebrenderIpcSender, WindowSizeData, WindowSizeType, + TimerSchedulerMsg, WindowSizeData, WindowSizeType, }; use selectors::attr::CaseSensitivity; use servo_arc::Arc as ServoArc; @@ -76,6 +76,7 @@ use style_traits::{CSSPixel, DevicePixel, ParsingMode}; use url::Position; use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel}; use webrender_api::{DocumentId, ExternalScrollId}; +use webrender_traits::WebRenderScriptApi; use super::bindings::trace::HashMapTracedValues; use crate::dom::bindings::cell::{DomRefCell, Ref}; @@ -318,7 +319,7 @@ pub struct Window { /// Webrender API Sender #[ignore_malloc_size_of = "Wraps an IpcSender"] #[no_trace] - webrender_api_sender: WebrenderIpcSender, + webrender_api_sender: WebRenderScriptApi, /// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete. /// It is used to avoid sending idle message more than once, which is unneccessary. @@ -521,7 +522,7 @@ impl Window { self.add_pending_reflow(); } - pub fn get_webrender_api_sender(&self) -> WebrenderIpcSender { + pub fn get_webrender_api_sender(&self) -> WebRenderScriptApi { self.webrender_api_sender.clone() } @@ -2537,7 +2538,7 @@ impl Window { webxr_registry: webxr_api::Registry, microtask_queue: Rc<MicrotaskQueue>, webrender_document: DocumentId, - webrender_api_sender: WebrenderIpcSender, + webrender_api_sender: WebRenderScriptApi, relayout_event: bool, prepare_for_screenshot: bool, unminify_js: bool, diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 7231dfc54dd..4c67071a7b0 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -83,7 +83,7 @@ use script_traits::{ LayoutMsg, LoadData, LoadOrigin, MediaSessionActionType, MouseButton, MouseEventType, NewLayoutInfo, Painter, ProgressiveWebMetricType, ScriptMsg, ScriptToConstellationChan, StructuredSerializedData, TimerSchedulerMsg, TouchEventType, TouchId, UntrustedNodeAddress, - UpdatePipelineIdReason, WebrenderIpcSender, WheelDelta, WindowSizeData, WindowSizeType, + UpdatePipelineIdReason, WheelDelta, WindowSizeData, WindowSizeType, }; use servo_atoms::Atom; use servo_config::opts; @@ -95,6 +95,7 @@ use url::Position; use webgpu::WebGPUMsg; use webrender_api::units::LayoutPixel; use webrender_api::DocumentId; +use webrender_traits::WebRenderScriptApi; use crate::document_loader::DocumentLoader; use crate::dom::bindings::cell::DomRefCell; @@ -674,7 +675,7 @@ pub struct ScriptThread { /// Webrender API sender. #[no_trace] - webrender_api_sender: WebrenderIpcSender, + webrender_api_sender: WebRenderScriptApi, /// Periodically print out on which events script threads spend their processing time. profile_script_events: bool, diff --git a/components/shared/net/image_cache.rs b/components/shared/net/image_cache.rs index cef274f96d6..47427d842ba 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 serde::{Deserialize, Serialize}; use servo_url::{ImmutableOrigin, ServoUrl}; -use webrender_traits::WebrenderIpcSender; +use webrender_traits::WebRenderNetApi; use pixels::{Image, ImageMetadata}; use crate::request::CorsSettings; use crate::FetchResponseMsg; @@ -99,7 +99,7 @@ pub enum ImageCacheResult { } pub trait ImageCache: Sync + Send { - fn new(webrender_api: WebrenderIpcSender) -> Self + fn new(webrender_api: WebRenderNetApi) -> Self where Self: Sized; diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs index 40673c5e6dd..bc29497f31b 100644 --- a/components/shared/script/lib.rs +++ b/components/shared/script/lib.rs @@ -34,7 +34,7 @@ use embedder_traits::CompositorEventVariant; use euclid::default::Point2D; use euclid::{Length, Rect, Scale, Size2D, UnknownUnit, Vector2D}; use http::{HeaderMap, Method}; -use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; +use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::Error as IpcError; use keyboard_types::webdriver::Event as WebDriverInputEvent; use keyboard_types::{CompositionEvent, KeyboardEvent}; @@ -54,13 +54,9 @@ use servo_atoms::Atom; use servo_url::{ImmutableOrigin, ServoUrl}; use style_traits::{CSSPixel, SpeculativePainter}; use webgpu::WebGPUMsg; -use webrender_api::units::{DeviceIntSize, DevicePixel, DevicePoint, LayoutPixel, LayoutPoint}; -use webrender_api::{ - BuiltDisplayList, DocumentId, ExternalScrollId, - HitTestFlags, ImageData, ImageKey, PipelineId as WebRenderPipelineId, -}; -use webrender_traits::{CompositorHitTestResult, ImageUpdate, ScriptToCompositorMsg, SerializedImageData, SerializedImageUpdate, UntrustedNodeAddress as WebRenderUntrustedNodeAddress}; -use webrender_traits::display_list::CompositorDisplayListInfo; +use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel}; +use webrender_api::{DocumentId, ExternalScrollId, ImageKey}; +use webrender_traits::{UntrustedNodeAddress as WebRenderUntrustedNodeAddress, WebRenderScriptApi}; pub use crate::script_msg::{ DOMMessage, EventResult, HistoryEntryReplacement, IFrameSizeMsg, Job, JobError, JobResult, JobResultValue, JobType, LayoutMsg, LogEntry, SWManagerMsg, SWManagerSenders, ScopeThings, @@ -694,7 +690,7 @@ pub struct InitialScriptState { /// 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: WebrenderIpcSender, + pub webrender_api_sender: WebRenderScriptApi, /// Application window's GL Context for Media player pub player_context: WindowGLContext, } @@ -1096,142 +1092,6 @@ impl From<i32> for MediaSessionActionType { } } -#[derive(Clone, Deserialize, Serialize)] -/// A mechanism to communicate with the parent process' WebRender instance. -pub struct WebrenderIpcSender(IpcSender<ScriptToCompositorMsg>); - -impl WebrenderIpcSender { - /// Create a new WebrenderIpcSender object that wraps the provided channel sender. - pub fn new(sender: IpcSender<ScriptToCompositorMsg>) -> Self { - Self(sender) - } - - /// 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, - 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); - } - }); - } -} - #[derive( Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize, )] diff --git a/components/shared/script_layout/Cargo.toml b/components/shared/script_layout/Cargo.toml index b809fb00108..803a247bc2d 100644 --- a/components/shared/script_layout/Cargo.toml +++ b/components/shared/script_layout/Cargo.toml @@ -38,3 +38,4 @@ servo_url = { path = "../../url" } style = { workspace = true } style_traits = { workspace = true } webrender_api = { workspace = true } +webrender_traits = { workspace = true } diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs index 7c1f4ee2162..d07a009af0e 100644 --- a/components/shared/script_layout/lib.rs +++ b/components/shared/script_layout/lib.rs @@ -33,7 +33,7 @@ use profile_traits::mem::Report; use profile_traits::time; use script_traits::{ ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, Painter, - ScrollState, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, + ScrollState, UntrustedNodeAddress, WindowSizeData, }; use serde::{Deserialize, Serialize}; use servo_arc::Arc as ServoArc; @@ -51,6 +51,7 @@ use style::stylesheets::Stylesheet; use style::Atom; use style_traits::CSSPixel; use webrender_api::ImageKey; +use webrender_traits::WebRenderScriptApi; pub type GenericLayoutData = dyn Any + Send + Sync; @@ -165,7 +166,7 @@ pub struct LayoutConfig { pub image_cache: Arc<dyn ImageCache>, pub font_cache_thread: FontCacheThread, pub time_profiler_chan: time::ProfilerChan, - pub webrender_api_sender: WebrenderIpcSender, + pub webrender_api_sender: WebRenderScriptApi, pub paint_time_metrics: PaintTimeMetrics, pub window_size: WindowSizeData, } diff --git a/components/shared/webrender/lib.rs b/components/shared/webrender/lib.rs index 9e48131d7b2..c67f3afe8ee 100644 --- a/components/shared/webrender/lib.rs +++ b/components/shared/webrender/lib.rs @@ -20,9 +20,7 @@ use log::warn; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect}; use webrender_api::{ - BuiltDisplayListDescriptor, ExternalImage, ExternalImageData, ExternalImageHandler, ExternalImageId, - ExternalImageSource, ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontKey, HitTestFlags, - ImageData, ImageDescriptor, ImageKey, NativeFontHandle + BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData, ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId, FontInstanceFlags, FontInstanceKey, FontKey, HitTestFlags, ImageData, ImageDescriptor, ImageKey, NativeFontHandle }; use webrender_api::PipelineId as WebRenderPipelineId; @@ -191,49 +189,6 @@ pub trait WebRenderFontApi { fn add_system_font(&self, handle: NativeFontHandle) -> FontKey; } -#[derive(Deserialize, Serialize)] -/// Serializable image updates that must be performed by WebRender. -pub enum ImageUpdate { - /// Register a new image. - AddImage(ImageKey, ImageDescriptor, ImageData), - /// 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), -} - -#[derive(Debug, Deserialize, Serialize)] -/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too -/// slow. -pub enum SerializedImageData { - /// 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), - /// 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)), - } - } -} pub enum CanvasToCompositorMsg { GenerateKey(Sender<ImageKey>), @@ -283,10 +238,11 @@ pub enum ScriptToCompositorMsg { UpdateImages(Vec<SerializedImageUpdate>), } +/// A mechanism to send messages from networking to the WebRender instance. #[derive(Clone, Deserialize, Serialize)] -pub struct WebrenderIpcSender(IpcSender<NetToCompositorMsg>); +pub struct WebRenderNetApi(IpcSender<NetToCompositorMsg>); -impl WebrenderIpcSender { +impl WebRenderNetApi { pub fn new(sender: IpcSender<NetToCompositorMsg>) -> Self { Self(sender) } @@ -309,6 +265,186 @@ impl WebrenderIpcSender { } } +/// 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 WebrenderIpcSender object that wraps the provided channel sender. + pub fn new(sender: IpcSender<ScriptToCompositorMsg>) -> Self { + Self(sender) + } + + /// 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, + 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); + } + }); + } +} + +#[derive(Deserialize, Serialize)] +/// Serializable image updates that must be performed by WebRender. +pub enum ImageUpdate { + /// Register a new image. + AddImage(ImageKey, ImageDescriptor, ImageData), + /// 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), +} + +#[derive(Debug, Deserialize, Serialize)] +/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too +/// slow. +pub enum SerializedImageData { + /// 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), + /// 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)), + } + } +} + /// The address of a node. Layout sends these back. They must be validated via /// `from_untrusted_node_address` before they can be used, because we do not trust layout. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] |