diff options
author | Josh Matthews <josh@joshmatthews.net> | 2019-11-25 17:18:04 -0500 |
---|---|---|
committer | Josh Matthews <josh@joshmatthews.net> | 2019-11-27 20:47:53 -0500 |
commit | 564c16d75499ae45b3945f487e49587c6fd662c7 (patch) | |
tree | f650d6eb383e95133a19baec32016a5b122203a3 /components | |
parent | a922c497fade0250123b86d7535838c9a8d3b0af (diff) | |
download | servo-564c16d75499ae45b3945f487e49587c6fd662c7.tar.gz servo-564c16d75499ae45b3945f487e49587c6fd662c7.zip |
Use non-IPC webrender API over explicit IPC channels.
Diffstat (limited to 'components')
39 files changed, 470 insertions, 175 deletions
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 6b8b3eae1b7..6c52fa07d1d 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -21,6 +21,7 @@ azure = {git = "https://github.com/servo/rust-azure", optional = true} bitflags = "1.0" byteorder = "1" canvas_traits = {path = "../canvas_traits"} +crossbeam-channel = "0.3" cssparser = "0.27.1" embedder_traits = {path = "../embedder_traits"} euclid = "0.20" @@ -35,7 +36,7 @@ pixels = {path = "../pixels"} servo_config = {path = "../config"} sparkle = "0.1.12" webrender = {git = "https://github.com/servo/webrender"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webrender_traits = {path = "../webrender_traits"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} # NOTE: the sm-angle feature only enables angle on windows, not other platforms! diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index ace360c25b5..a1932a0e56f 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -3,9 +3,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::canvas_data::*; +use crate::ConstellationCanvasMsg; use canvas_traits::canvas::*; +use crossbeam_channel::{select, unbounded, Sender}; use euclid::default::Size2D; use ipc_channel::ipc::{self, IpcSender}; +use ipc_channel::router::ROUTER; use std::borrow::ToOwned; use std::collections::HashMap; use std::thread; @@ -30,53 +33,69 @@ impl<'a> CanvasPaintThread<'a> { /// Creates a new `CanvasPaintThread` and returns an `IpcSender` to /// communicate with it. - pub fn start() -> IpcSender<CanvasMsg> { - let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap(); + pub fn start() -> (Sender<ConstellationCanvasMsg>, IpcSender<CanvasMsg>) { + let (ipc_sender, ipc_receiver) = ipc::channel::<CanvasMsg>().unwrap(); + let msg_receiver = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(ipc_receiver); + let (create_sender, create_receiver) = unbounded(); thread::Builder::new() .name("CanvasThread".to_owned()) .spawn(move || { let mut canvas_paint_thread = CanvasPaintThread::new(); loop { - match receiver.recv() { - Ok(msg) => match msg { - CanvasMsg::Canvas2d(message, canvas_id) => { - canvas_paint_thread.process_canvas_2d_message(message, canvas_id); - }, - CanvasMsg::Close(canvas_id) => { - canvas_paint_thread.canvases.remove(&canvas_id); - }, - CanvasMsg::Create(creator, size, webrenderer_api_sender, antialias) => { - let canvas_id = canvas_paint_thread.create_canvas( + select! { + recv(msg_receiver) -> msg => { + match msg { + Ok(CanvasMsg::Canvas2d(message, canvas_id)) => { + canvas_paint_thread.process_canvas_2d_message(message, canvas_id); + }, + Ok(CanvasMsg::Close(canvas_id)) => { + canvas_paint_thread.canvases.remove(&canvas_id); + }, + Ok(CanvasMsg::Recreate(size, canvas_id)) => { + canvas_paint_thread.canvas(canvas_id).recreate(size); + }, + Ok(CanvasMsg::FromScript(message, canvas_id)) => match message { + FromScriptMsg::SendPixels(chan) => { + canvas_paint_thread.canvas(canvas_id).send_pixels(chan); + }, + }, + Ok(CanvasMsg::FromLayout(message, canvas_id)) => match message { + FromLayoutMsg::SendData(chan) => { + canvas_paint_thread.canvas(canvas_id).send_data(chan); + }, + }, + Err(e) => { + warn!("Error on CanvasPaintThread receive ({})", e); + }, + } + } + recv(create_receiver) -> msg => { + match msg { + Ok(ConstellationCanvasMsg::Create { + id_sender: creator, size, - webrenderer_api_sender, - antialias, - ); - creator.send(canvas_id).unwrap(); - }, - CanvasMsg::Recreate(size, canvas_id) => { - canvas_paint_thread.canvas(canvas_id).recreate(size); - }, - CanvasMsg::FromScript(message, canvas_id) => match message { - FromScriptMsg::SendPixels(chan) => { - canvas_paint_thread.canvas(canvas_id).send_pixels(chan); + webrender_sender: webrenderer_api_sender, + antialias + }) => { + let canvas_id = canvas_paint_thread.create_canvas( + size, + webrenderer_api_sender, + antialias, + ); + creator.send(canvas_id).unwrap(); }, - }, - CanvasMsg::FromLayout(message, canvas_id) => match message { - FromLayoutMsg::SendData(chan) => { - canvas_paint_thread.canvas(canvas_id).send_data(chan); + Ok(ConstellationCanvasMsg::Exit) => break, + Err(e) => { + warn!("Error on CanvasPaintThread receive ({})", e); }, - }, - CanvasMsg::Exit => break, - }, - Err(e) => { - warn!("Error on CanvasPaintThread receive ({})", e); - }, + } + } } } }) .expect("Thread spawning failed"); - sender + (create_sender, ipc_sender) } pub fn create_canvas( diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index b61e32a63e8..bce829a04cc 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -4,6 +4,10 @@ #![deny(unsafe_code)] +use canvas_traits::canvas::CanvasId; +use crossbeam_channel::Sender; +use euclid::default::Size2D; + #[macro_use] extern crate bitflags; #[macro_use] @@ -22,3 +26,13 @@ pub mod canvas_paint_thread; mod webgl_limits; mod webgl_mode; pub mod webgl_thread; + +pub enum ConstellationCanvasMsg { + Create { + id_sender: Sender<CanvasId>, + size: Size2D<u64>, + webrender_sender: webrender_api::RenderApiSender, + antialias: bool, + }, + Exit, +} diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index 46c99fffaa8..d84b27684d5 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -28,7 +28,7 @@ pub struct WebGLComm { pub webgl_threads: WebGLThreads, pub webxr_swap_chains: SwapChains<WebXRSwapChainId>, pub image_handler: Box<dyn WebrenderExternalImageApi>, - pub output_handler: Option<Box<dyn webrender::OutputImageHandler>>, + pub output_handler: Option<Box<dyn webrender_api::OutputImageHandler>>, } impl WebGLComm { @@ -168,7 +168,7 @@ impl OutputHandler { } /// Bridge between the WR frame outputs and WebGL to implement DOMToTexture synchronization. -impl webrender::OutputImageHandler for OutputHandler { +impl webrender_api::OutputImageHandler for OutputHandler { fn lock( &mut self, id: webrender_api::PipelineId, diff --git a/components/canvas_traits/Cargo.toml b/components/canvas_traits/Cargo.toml index 6d37f90f941..b4dae5e2017 100644 --- a/components/canvas_traits/Cargo.toml +++ b/components/canvas_traits/Cargo.toml @@ -25,6 +25,6 @@ serde = "1.0" serde_bytes = "0.11" servo_config = {path = "../config"} sparkle = "0.1" -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webvr_traits = {path = "../webvr_traits"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} diff --git a/components/canvas_traits/canvas.rs b/components/canvas_traits/canvas.rs index 7d7a86e9961..ee659e16f3a 100644 --- a/components/canvas_traits/canvas.rs +++ b/components/canvas_traits/canvas.rs @@ -21,17 +21,10 @@ pub struct CanvasId(pub u64); #[derive(Deserialize, Serialize)] pub enum CanvasMsg { Canvas2d(Canvas2dMsg, CanvasId), - Create( - IpcSender<CanvasId>, - Size2D<u64>, - webrender_api::RenderApiSender, - bool, - ), FromLayout(FromLayoutMsg, CanvasId), FromScript(FromScriptMsg, CanvasId), Recreate(Size2D<u64>, CanvasId), Close(CanvasId), - Exit, } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index 7a1581a70ad..90daa3a3be5 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -38,7 +38,7 @@ servo_url = {path = "../url"} style_traits = {path = "../style_traits"} time = "0.1.17" webrender = {git = "https://github.com/servo/webrender", features = ["capture"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webvr_traits = {path = "../webvr_traits"} webvr = {path = "../webvr"} webxr = {git = "https://github.com/servo/webxr"} diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml index 893930c701a..f68a7e42ca9 100644 --- a/components/constellation/Cargo.toml +++ b/components/constellation/Cargo.toml @@ -49,7 +49,7 @@ servo_remutex = {path = "../remutex"} servo_url = {path = "../url"} webgpu = {path = "../webgpu"} webvr_traits = {path = "../webvr_traits"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} [target.'cfg(all(not(target_os = "windows"), not(target_os = "ios"), not(target_os="android"), not(target_arch="arm"), not(target_arch="aarch64")))'.dependencies] diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 3bd77ebf137..f8c66c3a7a9 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -104,6 +104,7 @@ use background_hang_monitor::HangMonitorRegister; use backtrace::Backtrace; use bluetooth_traits::BluetoothRequest; use canvas::canvas_paint_thread::CanvasPaintThread; +use canvas::ConstellationCanvasMsg; use canvas_traits::canvas::{CanvasId, CanvasMsg}; use canvas_traits::webgl::WebGLThreads; use compositing::compositor_thread::CompositorProxy; @@ -383,6 +384,14 @@ pub struct Constellation<Message, LTF, STF> { /// WebRender thread. webrender_api_sender: webrender_api::RenderApiSender, + /// A channel for content processes to send messages that will + /// be relayed to the WebRender thread. + webrender_api_ipc_sender: script_traits::WebrenderIpcSender, + + /// A channel for content process image caches to send messages + /// that will be relayed to the WebRender thread. + webrender_image_api_sender: net_traits::WebrenderIpcSender, + /// A map of message-port Id to info. message_ports: HashMap<MessagePortId, MessagePortInfo>, @@ -452,7 +461,9 @@ pub struct Constellation<Message, LTF, STF> { webxr_registry: webxr_api::Registry, /// A channel through which messages can be sent to the canvas paint thread. - canvas_chan: IpcSender<CanvasMsg>, + canvas_chan: Sender<ConstellationCanvasMsg>, + + ipc_canvas_chan: IpcSender<CanvasMsg>, /// Navigation requests from script awaiting approval from the embedder. pending_approval_navigations: PendingApprovalNavigations, @@ -709,6 +720,89 @@ where mpsc_receiver } +enum WebrenderMsg { + Layout(script_traits::WebrenderMsg), + Net(net_traits::WebrenderImageMsg), +} + +/// Accept messages from content processes that need to be relayed to the WebRender +/// instance in the parent process. +fn handle_webrender_message(webrender_api: &webrender_api::RenderApi, msg: WebrenderMsg) { + match msg { + WebrenderMsg::Layout(script_traits::WebrenderMsg::SendInitialTransaction( + doc, + pipeline, + )) => { + let mut txn = webrender_api::Transaction::new(); + txn.set_display_list( + webrender_api::Epoch(0), + None, + Default::default(), + (pipeline, Default::default(), Default::default()), + false, + ); + webrender_api.send_transaction(doc, txn); + }, + + WebrenderMsg::Layout(script_traits::WebrenderMsg::SendScrollNode( + doc, + point, + scroll_id, + clamping, + )) => { + let mut txn = webrender_api::Transaction::new(); + txn.scroll_node_with_id(point, scroll_id, clamping); + webrender_api.send_transaction(doc, txn); + }, + + WebrenderMsg::Layout(script_traits::WebrenderMsg::SendDisplayList( + doc, + epoch, + size, + pipeline, + size2, + data, + descriptor, + )) => { + let mut txn = webrender_api::Transaction::new(); + txn.set_display_list( + epoch, + None, + size, + ( + pipeline, + size2, + webrender_api::BuiltDisplayList::from_data(data, descriptor), + ), + true, + ); + txn.generate_frame(); + webrender_api.send_transaction(doc, txn); + }, + + WebrenderMsg::Layout(script_traits::WebrenderMsg::HitTest( + doc, + pipeline, + point, + flags, + sender, + )) => { + let result = webrender_api.hit_test(doc, pipeline, point, flags); + let _ = sender.send(result); + }, + + WebrenderMsg::Layout(script_traits::WebrenderMsg::GenerateImageKey(sender)) | + WebrenderMsg::Net(net_traits::WebrenderImageMsg::GenerateImageKey(sender)) => { + let _ = sender.send(webrender_api.generate_image_key()); + }, + + WebrenderMsg::Layout(script_traits::WebrenderMsg::UpdateResources(updates)) | + WebrenderMsg::Net(net_traits::WebrenderImageMsg::UpdateResources(updates)) => { + webrender_api.update_resources(updates); + }, + } +} + impl<Message, LTF, STF> Constellation<Message, LTF, STF> where LTF: LayoutThreadFactory<Message = Message>, @@ -786,6 +880,35 @@ where // Zero is reserved for the embedder. PipelineNamespace::install(PipelineNamespaceId(1)); + let (webrender_ipc_sender, webrender_ipc_receiver) = + ipc::channel().expect("ipc channel failure"); + let (webrender_image_ipc_sender, webrender_image_ipc_receiver) = + ipc::channel().expect("ipc channel failure"); + + let webrender_api = state.webrender_api_sender.create_api(); + ROUTER.add_route( + webrender_ipc_receiver.to_opaque(), + Box::new(move |message| { + handle_webrender_message( + &webrender_api, + WebrenderMsg::Layout(message.to().expect("conversion failure")), + ) + }), + ); + + let webrender_api = state.webrender_api_sender.create_api(); + ROUTER.add_route( + webrender_image_ipc_receiver.to_opaque(), + Box::new(move |message| { + handle_webrender_message( + &webrender_api, + WebrenderMsg::Net(message.to().expect("conversion failure")), + ) + }), + ); + + let (canvas_chan, ipc_canvas_chan) = CanvasPaintThread::start(); + let mut constellation: Constellation<Message, LTF, STF> = Constellation { namespace_receiver, namespace_sender, @@ -834,6 +957,12 @@ where document_states: HashMap::new(), webrender_document: state.webrender_document, webrender_api_sender: state.webrender_api_sender, + webrender_api_ipc_sender: script_traits::WebrenderIpcSender::new( + webrender_ipc_sender, + ), + webrender_image_api_sender: net_traits::WebrenderIpcSender::new( + webrender_image_ipc_sender, + ), shutting_down: false, handled_warnings: VecDeque::new(), random_pipeline_closure: random_pipeline_closure_probability.map(|prob| { @@ -847,7 +976,8 @@ where webgpu: state.webgpu, webvr_chan: state.webvr_chan, webxr_registry: state.webxr_registry, - canvas_chan: CanvasPaintThread::start(), + canvas_chan, + ipc_canvas_chan, pending_approval_navigations: HashMap::new(), pressed_mouse_buttons: 0, is_running_problem_test, @@ -1093,7 +1223,8 @@ where event_loop, load_data, prev_visibility: is_visible, - webrender_api_sender: self.webrender_api_sender.clone(), + webrender_api_sender: self.webrender_api_ipc_sender.clone(), + webrender_image_api_sender: self.webrender_image_api_sender.clone(), webrender_document: self.webrender_document, webgl_chan: self .webgl_threads @@ -2354,7 +2485,7 @@ where } debug!("Exiting Canvas Paint thread."); - if let Err(e) = self.canvas_chan.send(CanvasMsg::Exit) { + if let Err(e) = self.canvas_chan.send(ConstellationCanvasMsg::Exit) { warn!("Exit Canvas Paint thread failed ({})", e); } @@ -3925,23 +4056,21 @@ where response_sender: IpcSender<(IpcSender<CanvasMsg>, CanvasId)>, ) { let webrender_api = self.webrender_api_sender.clone(); - let sender = self.canvas_chan.clone(); - let (canvas_id_sender, canvas_id_receiver) = - ipc::channel::<CanvasId>().expect("ipc channel failure"); + let (canvas_id_sender, canvas_id_receiver) = unbounded(); - if let Err(e) = sender.send(CanvasMsg::Create( - canvas_id_sender, + if let Err(e) = self.canvas_chan.send(ConstellationCanvasMsg::Create { + id_sender: canvas_id_sender, size, - webrender_api, - self.enable_canvas_antialiasing, - )) { + webrender_sender: webrender_api, + antialias: self.enable_canvas_antialiasing, + }) { return warn!("Create canvas paint thread failed ({})", e); } let canvas_id = match canvas_id_receiver.recv() { Ok(canvas_id) => canvas_id, Err(e) => return warn!("Create canvas paint thread id response failed ({})", e), }; - if let Err(e) = response_sender.send((sender, canvas_id.clone())) { + if let Err(e) = response_sender.send((self.ipc_canvas_chan.clone(), canvas_id)) { warn!("Create canvas paint thread response failed ({})", e); } } diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index fd7202aa9ec..d2021646963 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -181,7 +181,10 @@ pub struct InitialPipelineState { pub prev_visibility: bool, /// Webrender api. - pub webrender_api_sender: webrender_api::RenderApiSender, + pub webrender_image_api_sender: net_traits::WebrenderIpcSender, + + /// Webrender api. + pub webrender_api_sender: script_traits::WebrenderIpcSender, /// The ID of the document processed by this script thread. pub webrender_document: webrender_api::DocumentId, @@ -300,6 +303,7 @@ impl Pipeline { pipeline_port: pipeline_port, 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, webgl_chan: state.webgl_chan, webvr_chan: state.webvr_chan, @@ -506,7 +510,8 @@ pub struct UnprivilegedPipelineContent { prefs: HashMap<String, PrefValue>, pipeline_port: IpcReceiver<LayoutControlMsg>, pipeline_namespace_id: PipelineNamespaceId, - webrender_api_sender: webrender_api::RenderApiSender, + webrender_api_sender: script_traits::WebrenderIpcSender, + webrender_image_api_sender: net_traits::WebrenderIpcSender, webrender_document: webrender_api::DocumentId, webgl_chan: Option<WebGLPipeline>, webgpu: Option<WebGPU>, @@ -529,7 +534,7 @@ impl UnprivilegedPipelineContent { // Idempotent in single-process mode. PipelineNamespace::set_installer_sender(self.namespace_request_sender); - let image_cache = Arc::new(ImageCacheImpl::new(self.webrender_api_sender.create_api())); + let image_cache = Arc::new(ImageCacheImpl::new(self.webrender_image_api_sender.clone())); let paint_time_metrics = PaintTimeMetrics::new( self.id, self.time_profiler_chan.clone(), diff --git a/components/embedder_traits/Cargo.toml b/components/embedder_traits/Cargo.toml index 9f68b7d0768..bbb7fe98a74 100644 --- a/components/embedder_traits/Cargo.toml +++ b/components/embedder_traits/Cargo.toml @@ -21,5 +21,5 @@ num-traits = "0.2" num-derive = "0.2" serde = "1.0" servo_url = {path = "../url"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml index d1519b91040..bb47f664446 100644 --- a/components/gfx/Cargo.toml +++ b/components/gfx/Cargo.toml @@ -38,7 +38,7 @@ style = {path = "../style", features = ["servo"]} time = "0.1.12" unicode-bidi = {version = "0.3", features = ["with_serde"]} unicode-script = {version = "0.3", features = ["harfbuzz"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} xi-unicode = "0.1.0" ucd = "0.1.1" diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index c68f98a831b..b45aebed3b4 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -51,7 +51,7 @@ style = {path = "../style", features = ["servo", "servo-layout-2013"]} style_traits = {path = "../style_traits"} unicode-bidi = {version = "0.3", features = ["with_serde"]} unicode-script = {version = "0.3", features = ["harfbuzz"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} xi-unicode = "0.1.0" [dev-dependencies] diff --git a/components/layout_2020/Cargo.toml b/components/layout_2020/Cargo.toml index f7167b638d5..7bfe7cbea16 100644 --- a/components/layout_2020/Cargo.toml +++ b/components/layout_2020/Cargo.toml @@ -33,4 +33,4 @@ servo_geometry = {path = "../geometry"} style = {path = "../style", features = ["servo", "servo-layout-2020"]} style_traits = {path = "../style_traits"} unicode-script = {version = "0.3", features = ["harfbuzz"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/layout_thread/Cargo.toml b/components/layout_thread/Cargo.toml index 38adb0bf4e1..39c30794901 100644 --- a/components/layout_thread/Cargo.toml +++ b/components/layout_thread/Cargo.toml @@ -50,4 +50,4 @@ servo_geometry = {path = "../geometry"} servo_url = {path = "../url"} style = {path = "../style"} style_traits = {path = "../style_traits"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 848ed595381..e85ab016833 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -83,9 +83,9 @@ use script_layout_interface::message::{QueryMsg, ReflowComplete, ReflowGoal, Scr use script_layout_interface::rpc::TextIndexResponse; use script_layout_interface::rpc::{LayoutRPC, OffsetParentResponse, StyleResponse}; use script_layout_interface::wrapper_traits::LayoutNode; -use script_traits::Painter; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{DrawAPaintImageResult, IFrameSizeMsg, PaintWorkletError, WindowSizeType}; +use script_traits::{Painter, WebrenderIpcSender}; use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData}; use selectors::Element; use servo_arc::Arc as ServoArc; @@ -230,7 +230,7 @@ pub struct LayoutThread { registered_painters: RegisteredPaintersImpl, /// Webrender interface. - webrender_api: webrender_api::RenderApi, + webrender_api: WebrenderIpcSender, /// Webrender document. webrender_document: webrender_api::DocumentId, @@ -299,7 +299,7 @@ impl LayoutThreadFactory for LayoutThread { font_cache_thread: FontCacheThread, time_profiler_chan: profile_time::ProfilerChan, mem_profiler_chan: profile_mem::ProfilerChan, - webrender_api_sender: webrender_api::RenderApiSender, + webrender_api_sender: WebrenderIpcSender, webrender_document: webrender_api::DocumentId, paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, @@ -517,7 +517,7 @@ impl LayoutThread { font_cache_thread: FontCacheThread, time_profiler_chan: profile_time::ProfilerChan, mem_profiler_chan: profile_mem::ProfilerChan, - webrender_api_sender: webrender_api::RenderApiSender, + webrender_api: WebrenderIpcSender, webrender_document: webrender_api::DocumentId, paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, @@ -533,18 +533,7 @@ impl LayoutThread { dump_flow_tree: bool, ) -> LayoutThread { // Let webrender know about this pipeline by sending an empty display list. - let mut epoch = Epoch(0); - let webrender_api = webrender_api_sender.create_api(); - let mut txn = webrender_api::Transaction::new(); - txn.set_display_list( - webrender_api::Epoch(epoch.0), - None, - Default::default(), - (id.to_webrender(), Default::default(), Default::default()), - false, - ); - webrender_api.send_transaction(webrender_document, txn); - epoch.next(); + webrender_api.send_initial_transaction(webrender_document, id.to_webrender()); let device = Device::new( MediaType::screen(), @@ -590,7 +579,8 @@ impl LayoutThread { document_shared_lock: None, running_animations: ServoArc::new(RwLock::new(Default::default())), expired_animations: ServoArc::new(RwLock::new(Default::default())), - epoch: Cell::new(epoch), + // Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR + epoch: Cell::new(Epoch(1)), viewport_size: Size2D::new(Au(0), Au(0)), webrender_api, webrender_document, @@ -829,14 +819,12 @@ impl LayoutThread { .insert(state.scroll_id, state.scroll_offset); let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y); - let mut txn = webrender_api::Transaction::new(); - txn.scroll_node_with_id( + self.webrender_api.send_scroll_node( + self.webrender_document, webrender_api::units::LayoutPoint::from_untyped(point), state.scroll_id, webrender_api::ScrollClamping::ToContentBounds, ); - self.webrender_api - .send_transaction(self.webrender_document, txn); }, Msg::ReapStyleAndLayoutData(dead_data) => unsafe { drop_style_and_layout_data(dead_data) @@ -949,7 +937,7 @@ impl LayoutThread { self.font_cache_thread.clone(), self.time_profiler_chan.clone(), self.mem_profiler_chan.clone(), - self.webrender_api.clone_sender(), + self.webrender_api.clone(), self.webrender_document, info.paint_time_metrics, info.layout_is_busy, @@ -1253,17 +1241,12 @@ impl LayoutThread { self.paint_time_metrics .maybe_observe_paint_time(self, epoch, is_contentful.0); - let mut txn = webrender_api::Transaction::new(); - txn.set_display_list( - webrender_api::Epoch(epoch.0), - None, + self.webrender_api.send_display_list( + self.webrender_document, + epoch, viewport_size, builder.finalize(), - true, ); - txn.generate_frame(); - self.webrender_api - .send_transaction(self.webrender_document, txn); }, ); } diff --git a/components/layout_thread_2020/Cargo.toml b/components/layout_thread_2020/Cargo.toml index 23bc41f9b25..525a20d8649 100644 --- a/components/layout_thread_2020/Cargo.toml +++ b/components/layout_thread_2020/Cargo.toml @@ -46,4 +46,4 @@ servo_geometry = {path = "../geometry"} servo_url = {path = "../url"} style = {path = "../style"} style_traits = {path = "../style_traits"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs index e8fdb1cfccd..3e94c535775 100644 --- a/components/layout_thread_2020/lib.rs +++ b/components/layout_thread_2020/lib.rs @@ -64,9 +64,9 @@ use script_layout_interface::message::{LayoutThreadInit, Msg, NodesFromPointQuer use script_layout_interface::message::{QueryMsg, ReflowComplete, ReflowGoal, ScriptReflow}; use script_layout_interface::rpc::TextIndexResponse; use script_layout_interface::rpc::{LayoutRPC, OffsetParentResponse, StyleResponse}; -use script_traits::Painter; use script_traits::{ConstellationControlMsg, LayoutControlMsg, LayoutMsg as ConstellationMsg}; use script_traits::{DrawAPaintImageResult, PaintWorkletError}; +use script_traits::{Painter, WebrenderIpcSender}; use script_traits::{ScrollState, UntrustedNodeAddress, WindowSizeData}; use selectors::Element; use servo_arc::Arc as ServoArc; @@ -193,7 +193,7 @@ pub struct LayoutThread { registered_painters: RegisteredPaintersImpl, /// Webrender interface. - webrender_api: webrender_api::RenderApi, + webrender_api: WebrenderIpcSender, /// Webrender document. webrender_document: webrender_api::DocumentId, @@ -233,7 +233,7 @@ impl LayoutThreadFactory for LayoutThread { font_cache_thread: FontCacheThread, time_profiler_chan: profile_time::ProfilerChan, mem_profiler_chan: profile_mem::ProfilerChan, - webrender_api_sender: webrender_api::RenderApiSender, + webrender_api_sender: WebrenderIpcSender, webrender_document: webrender_api::DocumentId, paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, @@ -442,7 +442,7 @@ impl LayoutThread { font_cache_thread: FontCacheThread, time_profiler_chan: profile_time::ProfilerChan, mem_profiler_chan: profile_mem::ProfilerChan, - webrender_api_sender: webrender_api::RenderApiSender, + webrender_api_sender: WebrenderIpcSender, webrender_document: webrender_api::DocumentId, paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, @@ -451,18 +451,7 @@ impl LayoutThread { relayout_event: bool, ) -> LayoutThread { // Let webrender know about this pipeline by sending an empty display list. - let mut epoch = Epoch(0); - let webrender_api = webrender_api_sender.create_api(); - let mut txn = webrender_api::Transaction::new(); - txn.set_display_list( - webrender_api::Epoch(epoch.0), - None, - Default::default(), - (id.to_webrender(), Default::default(), Default::default()), - false, - ); - webrender_api.send_transaction(webrender_document, txn); - epoch.next(); + webrender_api_sender.send_initial_transaction(webrender_document, id.to_webrender()); // The device pixel ratio is incorrect (it does not have the hidpi value), // but it will be set correctly when the initial reflow takes place. @@ -506,9 +495,10 @@ impl LayoutThread { box_tree_root: Default::default(), fragment_tree_root: Default::default(), document_shared_lock: None, - epoch: Cell::new(Epoch(0)), + // Epoch starts at 1 because of the initial display list for epoch 0 that we send to WR + epoch: Cell::new(Epoch(1)), viewport_size: Size2D::new(Au(0), Au(0)), - webrender_api: webrender_api_sender.create_api(), + webrender_api: webrender_api_sender, webrender_document, stylist: Stylist::new(device, QuirksMode::NoQuirks), rw_data: Arc::new(Mutex::new(LayoutThreadData { @@ -719,14 +709,12 @@ impl LayoutThread { .insert(state.scroll_id, state.scroll_offset); let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y); - let mut txn = webrender_api::Transaction::new(); - txn.scroll_node_with_id( + self.webrender_api.send_scroll_node( + self.webrender_document, webrender_api::units::LayoutPoint::from_untyped(point), state.scroll_id, webrender_api::ScrollClamping::ToContentBounds, ); - self.webrender_api - .send_transaction(self.webrender_document, txn); }, Msg::ReapStyleAndLayoutData(dead_data) => unsafe { drop_style_and_layout_data(dead_data) @@ -816,7 +804,7 @@ impl LayoutThread { self.font_cache_thread.clone(), self.time_profiler_chan.clone(), self.mem_profiler_chan.clone(), - self.webrender_api.clone_sender(), + self.webrender_api.clone(), self.webrender_document, info.paint_time_metrics, info.layout_is_busy, @@ -1308,17 +1296,12 @@ impl LayoutThread { self.paint_time_metrics .maybe_observe_paint_time(self, epoch, is_contentful.0); - let mut txn = webrender_api::Transaction::new(); - txn.set_display_list( - webrender_api::Epoch(epoch.0), - None, + self.webrender_api.send_display_list( + self.webrender_document, + epoch, viewport_size, display_list.wr.finalize(), - true, ); - txn.generate_frame(); - self.webrender_api - .send_transaction(self.webrender_document, txn); self.generation.set(self.generation.get() + 1); } diff --git a/components/layout_traits/Cargo.toml b/components/layout_traits/Cargo.toml index bfc5053ce22..a320a77263a 100644 --- a/components/layout_traits/Cargo.toml +++ b/components/layout_traits/Cargo.toml @@ -22,4 +22,4 @@ profile_traits = {path = "../profile_traits"} script_traits = {path = "../script_traits"} servo_url = {path = "../url"} servo_geometry = {path = "../geometry"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index b499bef85c6..942d37a8c87 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.rs @@ -18,7 +18,9 @@ use msg::constellation_msg::{BackgroundHangMonitorRegister, PipelineId}; use net_traits::image_cache::ImageCache; use profile_traits::{mem, time}; use script_traits::LayoutMsg as ConstellationMsg; -use script_traits::{ConstellationControlMsg, LayoutControlMsg, WindowSizeData}; +use script_traits::{ + ConstellationControlMsg, LayoutControlMsg, WebrenderIpcSender, WindowSizeData, +}; use servo_url::ServoUrl; use std::sync::atomic::AtomicBool; use std::sync::Arc; @@ -41,7 +43,7 @@ pub trait LayoutThreadFactory { font_cache_thread: FontCacheThread, time_profiler_chan: time::ProfilerChan, mem_profiler_chan: mem::ProfilerChan, - webrender_api_sender: webrender_api::RenderApiSender, + webrender_api_sender: WebrenderIpcSender, webrender_document: webrender_api::DocumentId, paint_time_metrics: PaintTimeMetrics, busy: Arc<AtomicBool>, diff --git a/components/malloc_size_of/Cargo.toml b/components/malloc_size_of/Cargo.toml index 3d2867d78b1..9ba39c1e0d6 100644 --- a/components/malloc_size_of/Cargo.toml +++ b/components/malloc_size_of/Cargo.toml @@ -44,6 +44,6 @@ string_cache = { version = "0.8", optional = true } thin-slice = "0.1.0" time = { version = "0.1.17", optional = true } url = { version = "2.0", optional = true } -webrender_api = { git = "https://github.com/servo/webrender", features = ["ipc"], optional = true } +webrender_api = { git = "https://github.com/servo/webrender", optional = true } xml5ever = { version = "0.16", optional = true } void = "1.0.2" diff --git a/components/media/Cargo.toml b/components/media/Cargo.toml index 7a4dc3ee7c9..7a72cf43d49 100644 --- a/components/media/Cargo.toml +++ b/components/media/Cargo.toml @@ -19,5 +19,5 @@ log = "0.4" serde = "1.0" servo_config = {path = "../config"} servo-media = {git = "https://github.com/servo/media"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webrender_traits = {path = "../webrender_traits"} diff --git a/components/msg/Cargo.toml b/components/msg/Cargo.toml index 8c098d9a903..5dc55caf521 100644 --- a/components/msg/Cargo.toml +++ b/components/msg/Cargo.toml @@ -20,7 +20,7 @@ malloc_size_of_derive = "0.1" parking_lot = "0.9" serde = "1.0.60" servo_url = {path = "../url"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} [dev-dependencies] size_of_test = {path = "../size_of_test"} diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index aac0b32aaeb..2649fbd5c0a 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -56,7 +56,7 @@ tokio = "0.1" time = "0.1.17" url = "2.0" uuid = {version = "0.8", features = ["v4"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} ws = { version = "0.9", features = ["ssl"] } [dev-dependencies] diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs index 098839e5ad9..57b6338dafb 100644 --- a/components/net/image_cache.rs +++ b/components/net/image_cache.rs @@ -9,7 +9,9 @@ use net_traits::image_cache::{CanRequestImages, CorsStatus, ImageCache, ImageRes use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, ImageState}; use net_traits::image_cache::{PendingImageId, UsePlaceholder}; use net_traits::request::CorsSettings; -use net_traits::{FetchMetadata, FetchResponseMsg, FilteredMetadata, NetworkError}; +use net_traits::{ + FetchMetadata, FetchResponseMsg, FilteredMetadata, NetworkError, WebrenderIpcSender, +}; use pixels::PixelFormat; use servo_url::{ImmutableOrigin, ServoUrl}; use std::collections::hash_map::Entry::{Occupied, Vacant}; @@ -43,7 +45,7 @@ fn decode_bytes_sync(key: LoadKey, bytes: &[u8], cors: CorsStatus) -> DecoderMsg } fn get_placeholder_image( - webrender_api: &webrender_api::RenderApi, + webrender_api: &WebrenderIpcSender, data: &[u8], ) -> io::Result<Arc<Image>> { let mut image = load_from_memory(&data, CorsStatus::Unsafe).unwrap(); @@ -51,7 +53,7 @@ fn get_placeholder_image( Ok(Arc::new(image)) } -fn set_webrender_image_key(webrender_api: &webrender_api::RenderApi, image: &mut Image) { +fn set_webrender_image_key(webrender_api: &WebrenderIpcSender, image: &mut Image) { if image.id.is_some() { return; } @@ -337,7 +339,7 @@ struct ImageCacheStore { placeholder_url: ServoUrl, // Webrender API instance. - webrender_api: webrender_api::RenderApi, + webrender_api: WebrenderIpcSender, } impl ImageCacheStore { @@ -423,7 +425,7 @@ pub struct ImageCacheImpl { } impl ImageCache for ImageCacheImpl { - fn new(webrender_api: webrender_api::RenderApi) -> ImageCacheImpl { + fn new(webrender_api: WebrenderIpcSender) -> ImageCacheImpl { debug!("New image cache"); let rippy_data = resources::read_bytes(Resource::RippyPNG); diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml index 5a75b523165..9fcd39fd5e5 100644 --- a/components/net_traits/Cargo.toml +++ b/components/net_traits/Cargo.toml @@ -37,7 +37,7 @@ servo_url = {path = "../url"} time = "0.1" url = "2.0" uuid = {version = "0.8", features = ["v4", "serde"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} [dev-dependencies] std_test_override = { path = "../std_test_override" } diff --git a/components/net_traits/image_cache.rs b/components/net_traits/image_cache.rs index 203941227d0..e640ca5b292 100644 --- a/components/net_traits/image_cache.rs +++ b/components/net_traits/image_cache.rs @@ -5,6 +5,7 @@ use crate::image::base::{Image, ImageMetadata}; use crate::request::CorsSettings; use crate::FetchResponseMsg; +use crate::WebrenderIpcSender; use ipc_channel::ipc::IpcSender; use servo_url::{ImmutableOrigin, ServoUrl}; use std::sync::Arc; @@ -101,7 +102,7 @@ pub enum UsePlaceholder { // ====================================================================== pub trait ImageCache: Sync + Send { - fn new(webrender_api: webrender_api::RenderApi) -> Self + fn new(webrender_api: WebrenderIpcSender) -> Self where Self: Sized; diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index cdba4f2066d..a25a804ce01 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -33,6 +33,7 @@ use msg::constellation_msg::HistoryStateId; use servo_url::ServoUrl; use std::error::Error; use time::precise_time_ns; +use webrender_api::ImageKey; pub mod blob_url_store; pub mod filemanager_thread; @@ -755,3 +756,32 @@ pub fn http_percent_encode(bytes: &[u8]) -> String { percent_encoding::percent_encode(bytes, HTTP_VALUE).to_string() } + +#[derive(Deserialize, Serialize)] +pub enum WebrenderImageMsg { + UpdateResources(Vec<webrender_api::ResourceUpdate>), + GenerateImageKey(IpcSender<ImageKey>), +} + +#[derive(Clone, Deserialize, Serialize)] +pub struct WebrenderIpcSender(IpcSender<WebrenderImageMsg>); + +impl WebrenderIpcSender { + pub fn new(sender: IpcSender<WebrenderImageMsg>) -> Self { + Self(sender) + } + + pub fn generate_image_key(&self) -> ImageKey { + let (sender, receiver) = ipc::channel().unwrap(); + self.0 + .send(WebrenderImageMsg::GenerateImageKey(sender)) + .expect("error sending image key generation"); + receiver.recv().expect("error receiving image key result") + } + + pub fn update_resources(&self, updates: Vec<webrender_api::ResourceUpdate>) { + if let Err(e) = self.0.send(WebrenderImageMsg::UpdateResources(updates)) { + warn!("Error sending image update: {}", e); + } + } +} diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 855d3d4dbc8..d7032f290e0 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -114,7 +114,7 @@ uuid = {version = "0.8", features = ["v4"]} xml5ever = "0.16" webdriver = "0.40" webgpu = {path = "../webgpu"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webvr_traits = {path = "../webvr_traits"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index fbd4da02d5b..5f10ad44446 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -96,7 +96,7 @@ use script_layout_interface::OpaqueStyleAndLayoutData; use script_traits::transferable::MessagePortImpl; use script_traits::{DocumentActivity, DrawAPaintImageResult}; use script_traits::{MediaSessionActionType, ScriptToConstellationChan, TimerEventId, TimerSource}; -use script_traits::{UntrustedNodeAddress, WindowSizeData, WindowSizeType}; +use script_traits::{UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData, WindowSizeType}; use selectors::matching::ElementSelectorFlags; use serde::{Deserialize, Serialize}; use servo_arc::Arc as ServoArc; @@ -146,7 +146,7 @@ use tendril::{StrTendril, TendrilSink}; use time::{Duration, Timespec}; use uuid::Uuid; use webgpu::{WebGPU, WebGPUAdapter}; -use webrender_api::{DocumentId, ImageKey, RenderApiSender}; +use webrender_api::{DocumentId, ImageKey}; use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState}; use webxr_api::SwapChainId as WebXRSwapChainId; @@ -527,7 +527,6 @@ unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn Player>>); unsafe_no_jsmanaged_fields!(WebRtcController); unsafe_no_jsmanaged_fields!(MediaStreamId, MediaStreamType); unsafe_no_jsmanaged_fields!(Mutex<MediaFrameRenderer>); -unsafe_no_jsmanaged_fields!(RenderApiSender); unsafe_no_jsmanaged_fields!(ResourceFetchTiming); unsafe_no_jsmanaged_fields!(Timespec); unsafe_no_jsmanaged_fields!(HTMLMediaElementFetchContext); @@ -541,6 +540,7 @@ unsafe_no_jsmanaged_fields!(WebGLContextId); unsafe_no_jsmanaged_fields!(Arc<Mutex<dyn AudioRenderer>>); unsafe_no_jsmanaged_fields!(MediaSessionActionType); unsafe_no_jsmanaged_fields!(MediaMetadata); +unsafe_no_jsmanaged_fields!(WebrenderIpcSender); unsafe impl<'a> JSTraceable for &'a str { #[inline] diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index f8f707a0dd9..651084cfb84 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -81,6 +81,7 @@ use net_traits::request::{Destination, Referrer}; use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, Metadata}; use net_traits::{NetworkError, ResourceFetchTiming, ResourceTimingType}; use script_layout_interface::HTMLMediaData; +use script_traits::WebrenderIpcSender; use servo_config::pref; use servo_media::player::audio::AudioRenderer; use servo_media::player::video::{VideoFrame, VideoFrameRenderer}; @@ -95,8 +96,7 @@ use std::rc::Rc; use std::sync::{Arc, Mutex}; use time::{self, Duration, Timespec}; use webrender_api::{ExternalImageData, ExternalImageId, ExternalImageType, TextureTarget}; -use webrender_api::{ImageData, ImageDescriptor, ImageFormat, ImageKey, RenderApi}; -use webrender_api::{RenderApiSender, Transaction}; +use webrender_api::{ImageData, ImageDescriptor, ImageFormat, ImageKey, Transaction}; #[derive(PartialEq)] enum FrameStatus { @@ -148,7 +148,7 @@ impl FrameHolder { pub struct MediaFrameRenderer { player_id: Option<u64>, - api: RenderApi, + api: WebrenderIpcSender, current_frame: Option<(ImageKey, i32, i32)>, old_frame: Option<ImageKey>, very_old_frame: Option<ImageKey>, @@ -156,10 +156,10 @@ pub struct MediaFrameRenderer { } impl MediaFrameRenderer { - fn new(render_api_sender: RenderApiSender) -> Self { + fn new(render_api_sender: WebrenderIpcSender) -> Self { Self { player_id: None, - api: render_api_sender.create_api(), + api: render_api_sender, current_frame: None, old_frame: None, very_old_frame: None, diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index ef8719ab8e6..d48f16ea662 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -108,7 +108,7 @@ use script_traits::{ConstellationControlMsg, DocumentState, HistoryEntryReplacem use script_traits::{ ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEventId, }; -use script_traits::{TimerSchedulerMsg, WindowSizeData, WindowSizeType}; +use script_traits::{TimerSchedulerMsg, WebrenderIpcSender, WindowSizeData, WindowSizeType}; use selectors::attr::CaseSensitivity; use servo_geometry::{f32_rect_to_au_rect, MaxRect}; use servo_url::{Host, ImmutableOrigin, MutableOrigin, ServoUrl}; @@ -137,7 +137,7 @@ use style_traits::{CSSPixel, DevicePixel, ParsingMode}; use url::Position; use webgpu::WebGPU; use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel}; -use webrender_api::{DocumentId, ExternalScrollId, RenderApiSender}; +use webrender_api::{DocumentId, ExternalScrollId}; use webvr_traits::WebVRMsg; /// Current state of the window object @@ -303,8 +303,8 @@ pub struct Window { exists_mut_observer: Cell<bool>, /// Webrender API Sender - #[ignore_malloc_size_of = "defined in webrender_api"] - webrender_api_sender: RenderApiSender, + #[ignore_malloc_size_of = "Wraps an IpcSender"] + webrender_api_sender: WebrenderIpcSender, /// 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. @@ -513,7 +513,7 @@ impl Window { self.add_pending_reflow(); } - pub fn get_webrender_api_sender(&self) -> RenderApiSender { + pub fn get_webrender_api_sender(&self) -> WebrenderIpcSender { self.webrender_api_sender.clone() } @@ -2218,7 +2218,7 @@ impl Window { webxr_registry: webxr_api::Registry, microtask_queue: Rc<MicrotaskQueue>, webrender_document: DocumentId, - webrender_api_sender: RenderApiSender, + webrender_api_sender: WebrenderIpcSender, layout_is_busy: Arc<AtomicBool>, relayout_event: bool, prepare_for_screenshot: bool, diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 99fca0e5608..c01ad08220c 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -143,7 +143,7 @@ use script_traits::{MediaSessionActionType, MouseButton, MouseEventType, NewLayo use script_traits::{Painter, ProgressiveWebMetricType, ScriptMsg, ScriptThreadFactory}; use script_traits::{ScriptToConstellationChan, TimerSchedulerMsg}; use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta}; -use script_traits::{UpdatePipelineIdReason, WindowSizeData, WindowSizeType}; +use script_traits::{UpdatePipelineIdReason, WebrenderIpcSender, WindowSizeData, WindowSizeType}; use servo_atoms::Atom; use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; use std::borrow::Cow; @@ -166,7 +166,7 @@ use time::{at_utc, get_time, precise_time_ns, Timespec}; use url::Position; use webgpu::WebGPU; use webrender_api::units::LayoutPixel; -use webrender_api::{DocumentId, RenderApiSender}; +use webrender_api::DocumentId; use webvr_traits::{WebVREvent, WebVRMsg}; pub type ImageCacheMsg = (PipelineId, PendingImageResponse); @@ -657,7 +657,7 @@ pub struct ScriptThread { webrender_document: DocumentId, /// Webrender API sender. - webrender_api_sender: RenderApiSender, + webrender_api_sender: WebrenderIpcSender, /// Periodically print out on which events script threads spend their processing time. profile_script_events: bool, diff --git a/components/script_layout_interface/Cargo.toml b/components/script_layout_interface/Cargo.toml index 2e436761dc8..6adc14a1b27 100644 --- a/components/script_layout_interface/Cargo.toml +++ b/components/script_layout_interface/Cargo.toml @@ -34,4 +34,4 @@ servo_atoms = {path = "../atoms"} servo_url = {path = "../url"} style = {path = "../style", features = ["servo"]} style_traits = {path = "../style_traits", features = ["servo"]} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/script_traits/Cargo.toml b/components/script_traits/Cargo.toml index 6d736ff3492..87cb044d902 100644 --- a/components/script_traits/Cargo.toml +++ b/components/script_traits/Cargo.toml @@ -25,6 +25,7 @@ hyper_serde = "0.11" ipc-channel = "0.12" keyboard-types = "0.4.3" libc = "0.2" +log = "0.4" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = "0.1" media = {path = "../media"} @@ -40,6 +41,6 @@ time = "0.1.12" url = "2.0" webdriver = "0.40" webgpu = {path = "../webgpu"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webvr_traits = {path = "../webvr_traits"} webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index efa877adb17..13429a13251 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -31,11 +31,12 @@ use euclid::{default::Point2D, Length, Rect, Scale, Size2D, UnknownUnit, Vector2 use gfx_traits::Epoch; use http::HeaderMap; use hyper::Method; -use ipc_channel::ipc::{IpcReceiver, IpcSender}; +use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::Error as IpcError; use keyboard_types::webdriver::Event as WebDriverInputEvent; use keyboard_types::{CompositionEvent, KeyboardEvent}; use libc::c_void; +use log::warn; use media::WindowGLContext; use msg::constellation_msg::BackgroundHangMonitorRegister; use msg::constellation_msg::{BrowsingContextId, HistoryStateId, MessagePortId, PipelineId}; @@ -61,8 +62,11 @@ use std::time::Duration; use style_traits::CSSPixel; use style_traits::SpeculativePainter; use webgpu::WebGPU; -use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel}; -use webrender_api::{DocumentId, ExternalScrollId, ImageKey, RenderApiSender}; +use webrender_api::units::{ + DeviceIntSize, DevicePixel, LayoutPixel, LayoutPoint, LayoutSize, WorldPoint, +}; +use webrender_api::{BuiltDisplayList, DocumentId, ExternalScrollId, ImageKey, ScrollClamping}; +use webrender_api::{BuiltDisplayListDescriptor, HitTestFlags, HitTestResult, ResourceUpdate}; use webvr_traits::{WebVREvent, WebVRMsg}; pub use crate::script_msg::{ @@ -666,7 +670,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: RenderApiSender, + pub webrender_api_sender: WebrenderIpcSender, /// Flag to indicate if the layout thread is busy handling a request. pub layout_is_busy: Arc<AtomicBool>, /// Application window's GL Context for Media player @@ -1108,3 +1112,132 @@ impl From<i32> for MediaSessionActionType { } } } + +/// The set of WebRender operations that can be initiated by the content process. +#[derive(Deserialize, Serialize)] +pub enum WebrenderMsg { + /// Inform WebRender of the existence of this pipeline. + SendInitialTransaction(DocumentId, webrender_api::PipelineId), + /// Perform a scroll operation. + SendScrollNode(DocumentId, LayoutPoint, ExternalScrollId, ScrollClamping), + /// Inform WebRender of a new display list for the given pipeline. + SendDisplayList( + DocumentId, + webrender_api::Epoch, + LayoutSize, + webrender_api::PipelineId, + LayoutSize, + Vec<u8>, + BuiltDisplayListDescriptor, + ), + /// Perform a hit test operation. The result will be returned via + /// the provided channel sender. + HitTest( + DocumentId, + Option<webrender_api::PipelineId>, + WorldPoint, + HitTestFlags, + IpcSender<HitTestResult>, + ), + /// Create a new image key. The result will be returned via the + /// provided channel sender. + GenerateImageKey(IpcSender<ImageKey>), + /// Perform a resource update operation. + UpdateResources(Vec<ResourceUpdate>), +} + +#[derive(Clone, Deserialize, Serialize)] +/// A mechanism to communicate with the parent process' WebRender instance. +pub struct WebrenderIpcSender(IpcSender<WebrenderMsg>); + +impl WebrenderIpcSender { + /// Create a new WebrenderIpcSender object that wraps the provided channel sender. + pub fn new(sender: IpcSender<WebrenderMsg>) -> Self { + Self(sender) + } + + /// Inform WebRender of the existence of this pipeline. + pub fn send_initial_transaction( + &self, + document: DocumentId, + pipeline: webrender_api::PipelineId, + ) { + if let Err(e) = self + .0 + .send(WebrenderMsg::SendInitialTransaction(document, pipeline)) + { + warn!("Error sending initial transaction: {}", e); + } + } + + /// Perform a scroll operation. + pub fn send_scroll_node( + &self, + document: DocumentId, + point: LayoutPoint, + scroll_id: ExternalScrollId, + clamping: ScrollClamping, + ) { + if let Err(e) = self.0.send(WebrenderMsg::SendScrollNode( + document, point, scroll_id, clamping, + )) { + warn!("Error sending scroll node: {}", e); + } + } + + /// Inform WebRender of a new display list for the given pipeline. + pub fn send_display_list( + &self, + document: DocumentId, + epoch: Epoch, + size: LayoutSize, + (pipeline, size2, list): (webrender_api::PipelineId, LayoutSize, BuiltDisplayList), + ) { + let (data, descriptor) = list.into_data(); + if let Err(e) = self.0.send(WebrenderMsg::SendDisplayList( + document, + webrender_api::Epoch(epoch.0), + size, + pipeline, + size2, + data, + descriptor, + )) { + warn!("Error sending display list: {}", e); + } + } + + /// Perform a hit test operation. Blocks until the operation is complete and + /// and a result is available. + pub fn hit_test( + &self, + document: DocumentId, + pipeline: Option<webrender_api::PipelineId>, + point: WorldPoint, + flags: HitTestFlags, + ) -> HitTestResult { + let (sender, receiver) = ipc::channel().unwrap(); + self.0 + .send(WebrenderMsg::HitTest( + document, 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) -> ImageKey { + let (sender, receiver) = ipc::channel().unwrap(); + self.0 + .send(WebrenderMsg::GenerateImageKey(sender)) + .expect("error sending image key generation"); + receiver.recv().expect("error receiving image key result") + } + + /// Perform a resource update operation. + pub fn update_resources(&self, updates: Vec<ResourceUpdate>) { + if let Err(e) = self.0.send(WebrenderMsg::UpdateResources(updates)) { + warn!("error sending resource updates: {}", e); + } + } +} diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 83f298fb96b..7e97468b7eb 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -81,7 +81,7 @@ style = {path = "../style", features = ["servo"]} style_traits = {path = "../style_traits", features = ["servo"]} webgpu = {path = "../webgpu"} webrender = {git = "https://github.com/servo/webrender"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} webrender_traits = {path = "../webrender_traits"} webdriver_server = {path = "../webdriver_server", optional = true} webvr = {path = "../webvr"} diff --git a/components/webrender_traits/Cargo.toml b/components/webrender_traits/Cargo.toml index 76c359d01e6..29d2bf8aa9f 100644 --- a/components/webrender_traits/Cargo.toml +++ b/components/webrender_traits/Cargo.toml @@ -12,6 +12,5 @@ path = "lib.rs" [dependencies] euclid = "0.20" -webrender = {git = "https://github.com/servo/webrender"} -webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} +webrender_api = {git = "https://github.com/servo/webrender"} diff --git a/components/webrender_traits/lib.rs b/components/webrender_traits/lib.rs index 90b1b944369..75c5f60272e 100644 --- a/components/webrender_traits/lib.rs +++ b/components/webrender_traits/lib.rs @@ -98,7 +98,7 @@ impl WebrenderExternalImageHandlers { } } -impl webrender::ExternalImageHandler for WebrenderExternalImageHandlers { +impl webrender_api::ExternalImageHandler for WebrenderExternalImageHandlers { /// Lock the external image. Then, WR could start to read the /// image content. /// The WR client should not change the image content until the @@ -108,7 +108,7 @@ impl webrender::ExternalImageHandler for WebrenderExternalImageHandlers { key: webrender_api::ExternalImageId, _channel_index: u8, _rendering: webrender_api::ImageRendering, - ) -> webrender::ExternalImage { + ) -> webrender_api::ExternalImage { let external_images = self.external_images.lock().unwrap(); let handler_type = external_images .get(&key) @@ -129,9 +129,9 @@ impl webrender::ExternalImageHandler for WebrenderExternalImageHandlers { ) }, }; - webrender::ExternalImage { + webrender_api::ExternalImage { uv, - source: webrender::ExternalImageSource::NativeTexture(texture_id), + source: webrender_api::ExternalImageSource::NativeTexture(texture_id), } } |