diff options
-rw-r--r-- | Cargo.lock | 36 | ||||
-rw-r--r-- | components/canvas/Cargo.toml | 2 | ||||
-rw-r--r-- | components/canvas/lib.rs | 3 | ||||
-rw-r--r-- | components/canvas/webgl_mode/inprocess.rs | 11 | ||||
-rw-r--r-- | components/canvas/webgl_thread.rs | 107 | ||||
-rw-r--r-- | components/canvas_traits/webgl.rs | 11 | ||||
-rw-r--r-- | components/canvas_traits/webgl_channel/mod.rs | 13 | ||||
-rw-r--r-- | components/canvas_traits/webgl_channel/mpsc.rs | 16 | ||||
-rw-r--r-- | components/compositing/Cargo.toml | 1 | ||||
-rw-r--r-- | components/compositing/windowing.rs | 9 | ||||
-rw-r--r-- | components/script/dom/webglframebuffer.rs | 8 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 4 | ||||
-rw-r--r-- | components/script/dom/xrsession.rs | 6 | ||||
-rw-r--r-- | components/servo/lib.rs | 45 | ||||
-rw-r--r-- | ports/glutin/embedder.rs | 8 | ||||
-rw-r--r-- | ports/libsimpleservo/api/src/lib.rs | 42 | ||||
-rw-r--r-- | tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini | 2 |
17 files changed, 215 insertions, 109 deletions
diff --git a/Cargo.lock b/Cargo.lock index a7ad0c22733..fd23f6edda5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,8 +496,8 @@ dependencies = [ "raqote", "servo_config", "sparkle", - "surfman 0.1.3", - "surfman-chains 0.2.1", + "surfman 0.1.4", + "surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "surfman-chains-api", "time", "webrender", @@ -742,6 +742,7 @@ dependencies = [ name = "compositing" version = "0.0.1" dependencies = [ + "canvas", "crossbeam-channel", "embedder_traits", "euclid", @@ -3184,7 +3185,7 @@ dependencies = [ "sparkle", "style", "style_traits", - "surfman 0.1.3", + "surfman 0.1.4", "webdriver_server", "webgpu", "webrender", @@ -5046,7 +5047,7 @@ dependencies = [ "servo-media", "sparkle", "surfman 0.2.0", - "surfman-chains 0.3.0", + "surfman-chains 0.3.0 (git+https://github.com/asajeffrey/surfman-chains?branch=multi)", "surfman-chains-api", ] @@ -5697,9 +5698,9 @@ dependencies = [ [[package]] name = "surfman" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10248da202c1c8d8798783bbc4ba08e81ff225c6e2a394d64748d2a62acb198c" +checksum = "43bf043642ad98aaa51956091c4f829a400bad5f023b5f0095ecda61f925c63d" dependencies = [ "bitflags", "cgl 0.3.2", @@ -5726,7 +5727,7 @@ dependencies = [ [[package]] name = "surfman" version = "0.2.0" -source = "git+https://github.com/pcwalton/surfman?branch=multi#808e5c5906dbcc6707536c8bac8bcc9389b4e1eb" +source = "git+https://github.com/pcwalton/surfman?branch=multi#fb782262617e7ca839a4e487b116a5199afaf963" dependencies = [ "bitflags", "cgl 0.3.2", @@ -5752,28 +5753,28 @@ dependencies = [ [[package]] name = "surfman-chains" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2c1b5976b229a807a9e79b3b5248da577948b9882c77f2afce27cf562f80e22" +version = "0.3.0" +source = "git+https://github.com/asajeffrey/surfman-chains?branch=multi#80a71b1a2df71ae70c3c194d0af40b8ebf72968a" dependencies = [ "euclid", "fnv", "log", "sparkle", - "surfman 0.1.3", + "surfman 0.2.0", "surfman-chains-api", ] [[package]] name = "surfman-chains" version = "0.3.0" -source = "git+https://github.com/asajeffrey/surfman-chains?branch=multi#80a71b1a2df71ae70c3c194d0af40b8ebf72968a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a679f5be9644bbf93662f3b1a704cc6b81c147d4b7d6d5c8d8b6f453176f01" dependencies = [ "euclid", "fnv", "log", "sparkle", - "surfman 0.2.0", + "surfman 0.1.4", "surfman-chains-api", ] @@ -6649,9 +6650,10 @@ dependencies = [ [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#a1afba096c9797c3663727de58f54eae898f3050" +source = "git+https://github.com/servo/webxr#3ac3e83f37ff64c74c847a610a8cefba9b907a9c" dependencies = [ "bindgen", + "crossbeam-channel", "euclid", "gl_generator 0.13.1", "gleam 0.9.2", @@ -6659,8 +6661,8 @@ dependencies = [ "log", "openxr", "serde", - "surfman 0.1.3", - "surfman-chains 0.2.1", + "surfman 0.1.4", + "surfman-chains 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "time", "webxr-api", "winapi", @@ -6670,7 +6672,7 @@ dependencies = [ [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#a1afba096c9797c3663727de58f54eae898f3050" +source = "git+https://github.com/servo/webxr#3ac3e83f37ff64c74c847a610a8cefba9b907a9c" dependencies = [ "euclid", "ipc-channel", diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index ffb12a7a4ce..86cd3c4e440 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -42,5 +42,5 @@ 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! surfman = { version = "0.1", features = ["sm-angle", "sm-osmesa"] } -surfman-chains = "0.2" +surfman-chains = "0.3" surfman-chains-api = "0.2" diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index 1e5872420bc..074a4a00bcb 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -12,6 +12,9 @@ extern crate log; mod raqote_backend; pub use webgl_mode::WebGLComm; +pub use webgl_thread::SurfaceProvider; +pub use webgl_thread::SurfaceProviders; +pub use webgl_thread::WebGlExecutor; pub mod canvas_data; pub mod canvas_paint_thread; diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index d84b27684d5..b46b1608101 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::webgl_thread::{WebGLThread, WebGLThreadInit}; +use crate::webgl_thread::{SurfaceProviders, WebGLThread, WebGLThreadInit, WebGlExecutor}; use canvas_traits::webgl::{webgl_channel, WebVRRenderHandler}; use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads}; use euclid::default::Size2D; @@ -11,6 +11,7 @@ use gleam; use servo_config::pref; use sparkle::gl; use sparkle::gl::GlType; +use std::collections::HashMap; use std::default::Default; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -27,8 +28,10 @@ use webxr_api::SwapChainId as WebXRSwapChainId; pub struct WebGLComm { pub webgl_threads: WebGLThreads, pub webxr_swap_chains: SwapChains<WebXRSwapChainId>, + pub webxr_surface_providers: SurfaceProviders, pub image_handler: Box<dyn WebrenderExternalImageApi>, pub output_handler: Option<Box<dyn webrender_api::OutputImageHandler>>, + pub webgl_executor: WebGlExecutor, } impl WebGLComm { @@ -46,6 +49,8 @@ impl WebGLComm { let (sender, receiver) = webgl_channel::<WebGLMsg>().unwrap(); let webrender_swap_chains = SwapChains::new(); let webxr_swap_chains = SwapChains::new(); + let webxr_surface_providers = Arc::new(Mutex::new(HashMap::new())); + let (runnable_sender, runnable_receiver) = crossbeam_channel::unbounded(); // This implementation creates a single `WebGLThread` for all the pipelines. let init = WebGLThreadInit { @@ -56,9 +61,11 @@ impl WebGLComm { receiver, webrender_swap_chains: webrender_swap_chains.clone(), webxr_swap_chains: webxr_swap_chains.clone(), + webxr_surface_providers: webxr_surface_providers.clone(), connection: device.connection(), adapter: device.adapter(), api_type, + runnable_receiver, }; let output_handler = if pref!(dom.webgl.dom_to_texture.enabled) { @@ -74,8 +81,10 @@ impl WebGLComm { WebGLComm { webgl_threads: WebGLThreads(sender), webxr_swap_chains, + webxr_surface_providers, image_handler: Box::new(external), output_handler: output_handler.map(|b| b as Box<_>), + webgl_executor: runnable_sender, } } } diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index 1658ebf94a5..f72e2c79bc1 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -54,7 +54,7 @@ use sparkle::gl::GLint; use sparkle::gl::GLuint; use sparkle::gl::Gl; use std::borrow::Cow; -use std::cell::{Cell, RefCell}; +use std::collections::HashMap; use std::rc::Rc; use std::slice; use std::sync::{Arc, Mutex}; @@ -70,9 +70,10 @@ use surfman::GLVersion; use surfman::SurfaceAccess; use surfman::SurfaceInfo; use surfman::SurfaceType; -use surfman_chains::SwapChains; +use surfman_chains::{SurfmanProvider, SwapChains}; use surfman_chains_api::SwapChainsAPI; use webrender_traits::{WebrenderExternalImageRegistry, WebrenderImageHandlerType}; +use webxr_api::SessionId; use webxr_api::SwapChainId as WebXRSwapChainId; #[cfg(feature = "xr-profile")] @@ -138,25 +139,29 @@ pub(crate) struct WebGLThread { /// We use it to get an unique ID for new WebGLContexts. external_images: Arc<Mutex<WebrenderExternalImageRegistry>>, /// The receiver that will be used for processing WebGL messages. - receiver: WebGLReceiver<WebGLMsg>, + receiver: crossbeam_channel::Receiver<WebGLMsg>, /// The receiver that should be used to send WebGL messages for processing. sender: WebGLSender<WebGLMsg>, /// The swap chains used by webrender webrender_swap_chains: SwapChains<WebGLContextId>, /// The swap chains used by webxr webxr_swap_chains: SwapChains<WebXRSwapChainId>, + /// The set of all surface providers corresponding to WebXR sessions. + webxr_surface_providers: SurfaceProviders, + /// A channel to allow arbitrary threads to execute tasks that run in the WebGL thread. + runnable_receiver: crossbeam_channel::Receiver<WebGlRunnable>, /// Whether this context is a GL or GLES context. api_type: gl::GlType, } -#[derive(PartialEq)] -enum EventLoop { - Blocking, - Nonblocking, -} +pub type WebGlExecutor = crossbeam_channel::Sender<WebGlRunnable>; +pub type WebGlRunnable = Box<dyn FnOnce() + Send>; +pub type SurfaceProviders = Arc<Mutex<HashMap<SessionId, SurfaceProvider>>>; +pub type SurfaceProvider = Box<dyn surfman_chains::SurfaceProvider + Send>; /// The data required to initialize an instance of the WebGLThread type. pub(crate) struct WebGLThreadInit { + pub webxr_surface_providers: SurfaceProviders, pub webrender_api_sender: webrender_api::RenderApiSender, pub webvr_compositor: Option<Box<dyn WebVRRenderHandler>>, pub external_images: Arc<Mutex<WebrenderExternalImageRegistry>>, @@ -167,37 +172,7 @@ pub(crate) struct WebGLThreadInit { pub connection: Connection, pub adapter: Adapter, pub api_type: gl::GlType, -} - -/// The extra data required to run an instance of WebGLThread when it is -/// not running in its own thread. -pub struct WebGLMainThread { - pub(crate) thread_data: RefCell<WebGLThread>, - shut_down: Cell<bool>, -} - -impl WebGLMainThread { - /// Synchronously process all outstanding WebGL messages. - pub fn process(&self) { - if self.shut_down.get() { - return; - } - - // Any context could be current when we start. - self.thread_data.borrow_mut().bound_context_id = None; - let result = self - .thread_data - .borrow_mut() - .process(EventLoop::Nonblocking); - if !result { - self.shut_down.set(true); - WEBGL_MAIN_THREAD.with(|thread_data| thread_data.borrow_mut().take()); - } - } -} - -thread_local! { - static WEBGL_MAIN_THREAD: RefCell<Option<Rc<WebGLMainThread>>> = RefCell::new(None); + pub runnable_receiver: crossbeam_channel::Receiver<WebGlRunnable>, } // A size at which it should be safe to create GL contexts @@ -214,9 +189,11 @@ impl WebGLThread { receiver, webrender_swap_chains, webxr_swap_chains, + webxr_surface_providers, connection, adapter, api_type, + runnable_receiver, }: WebGLThreadInit, ) -> Self { WebGLThread { @@ -229,9 +206,11 @@ impl WebGLThread { dom_outputs: Default::default(), external_images, sender, - receiver, + receiver: receiver.into_inner(), webrender_swap_chains, webxr_swap_chains, + webxr_surface_providers, + runnable_receiver, api_type, } } @@ -243,23 +222,35 @@ impl WebGLThread { .name("WebGL thread".to_owned()) .spawn(move || { let mut data = WebGLThread::new(init); - data.process(EventLoop::Blocking); + data.process(); }) .expect("Thread spawning failed"); } - fn process(&mut self, loop_type: EventLoop) -> bool { + fn process(&mut self) { let webgl_chan = WebGLChan(self.sender.clone()); - while let Ok(msg) = match loop_type { - EventLoop::Blocking => self.receiver.recv(), - EventLoop::Nonblocking => self.receiver.try_recv(), - } { - let exit = self.handle_msg(msg, &webgl_chan); - if exit { - return false; + loop { + crossbeam_channel::select! { + recv(self.receiver) -> msg => { + match msg { + Ok(msg) => { + let exit = self.handle_msg(msg, &webgl_chan); + if exit { + return; + } + } + _ => break, + } + } + recv(self.runnable_receiver) -> msg => { + if let Ok(msg) = msg { + msg(); + } else { + self.runnable_receiver = crossbeam_channel::never(); + } + } } } - true } /// Handles a generic WebGLMsg message @@ -331,8 +322,8 @@ impl WebGLThread { WebGLMsg::WebVRCommand(ctx_id, command) => { self.handle_webvr_command(ctx_id, command); }, - WebGLMsg::CreateWebXRSwapChain(ctx_id, size, sender) => { - let _ = sender.send(self.create_webxr_swap_chain(ctx_id, size)); + WebGLMsg::CreateWebXRSwapChain(ctx_id, size, sender, id) => { + let _ = sender.send(self.create_webxr_swap_chain(ctx_id, size, id)); }, WebGLMsg::SwapBuffers(swap_ids, sender, sent_time) => { self.handle_swap_buffers(swap_ids, sender, sent_time); @@ -443,6 +434,7 @@ impl WebGLThread { size: safe_size.to_i32(), }; let surface_access = self.surface_access(); + let surface_provider = Box::new(SurfmanProvider::new(surface_access)); let mut ctx = self .device @@ -469,7 +461,7 @@ impl WebGLThread { ); self.webrender_swap_chains - .create_attached_swap_chain(id, &mut self.device, &mut ctx, surface_access) + .create_attached_swap_chain(id, &mut self.device, &mut ctx, surface_provider) .expect("Failed to create the swap chain"); let swap_chain = self @@ -765,6 +757,7 @@ impl WebGLThread { &mut self, context_id: WebGLContextId, size: Size2D<i32>, + session_id: SessionId, ) -> Option<WebXRSwapChainId> { debug!("WebGLThread::create_webxr_swap_chain()"); let id = WebXRSwapChainId::new(); @@ -775,8 +768,14 @@ impl WebGLThread { &mut self.contexts, &mut self.bound_context_id, )?; + let surface_provider = self + .webxr_surface_providers + .lock() + .unwrap() + .remove(&session_id) + .unwrap_or_else(|| Box::new(SurfmanProvider::new(surface_access))); self.webxr_swap_chains - .create_detached_swap_chain(id, size, &mut self.device, &mut data.ctx, surface_access) + .create_detached_swap_chain(id, size, &mut self.device, &mut data.ctx, surface_provider) .ok()?; debug!("Created swap chain {:?}", id); Some(id) diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index 22e47ad9bb4..ce109f4e034 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -14,6 +14,7 @@ use std::num::{NonZeroU32, NonZeroU64}; use std::ops::Deref; use webrender_api::{DocumentId, ImageKey, PipelineId}; use webvr_traits::WebVRPoseInformation; +use webxr_api::SessionId; use webxr_api::SwapChainId as WebXRSwapChainId; /// Helper function that creates a WebGL channel (WebGLSender, WebGLReceiver) to be used in WebGLCommands. @@ -80,6 +81,7 @@ pub enum WebGLMsg { WebGLContextId, Size2D<i32>, WebGLSender<Option<WebXRSwapChainId>>, + SessionId, ), /// Performs a buffer swap. /// @@ -188,9 +190,14 @@ impl WebGLMsgSender { &self, size: Size2D<i32>, sender: WebGLSender<Option<WebXRSwapChainId>>, + id: SessionId, ) -> WebGLSendResult { - self.sender - .send(WebGLMsg::CreateWebXRSwapChain(self.ctx_id, size, sender)) + self.sender.send(WebGLMsg::CreateWebXRSwapChain( + self.ctx_id, + size, + sender, + id, + )) } #[inline] diff --git a/components/canvas_traits/webgl_channel/mod.rs b/components/canvas_traits/webgl_channel/mod.rs index 45c76d54605..86a6cd23bf4 100644 --- a/components/canvas_traits/webgl_channel/mod.rs +++ b/components/canvas_traits/webgl_channel/mod.rs @@ -9,6 +9,7 @@ mod mpsc; use crate::webgl::WebGLMsg; use ipc_channel::ipc::IpcSender; +use ipc_channel::router::ROUTER; use serde::{Deserialize, Serialize}; use servo_config::opts; use std::fmt; @@ -78,6 +79,18 @@ where WebGLReceiver::Mpsc(ref receiver) => receiver.try_recv().map_err(|_| ()), } } + + pub fn into_inner(self) -> crossbeam_channel::Receiver<T> + where + T: Send + 'static, + { + match self { + WebGLReceiver::Ipc(receiver) => { + ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(receiver) + }, + WebGLReceiver::Mpsc(receiver) => receiver.into_inner(), + } + } } pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()> diff --git a/components/canvas_traits/webgl_channel/mpsc.rs b/components/canvas_traits/webgl_channel/mpsc.rs index 0dd063967ea..40acb050861 100644 --- a/components/canvas_traits/webgl_channel/mpsc.rs +++ b/components/canvas_traits/webgl_channel/mpsc.rs @@ -4,7 +4,6 @@ use serde::{Deserialize, Serialize}; use serde::{Deserializer, Serializer}; -use std::sync::mpsc; #[macro_use] macro_rules! unreachable_serializable { @@ -26,8 +25,8 @@ macro_rules! unreachable_serializable { }; } -pub struct WebGLSender<T>(mpsc::Sender<T>); -pub struct WebGLReceiver<T>(mpsc::Receiver<T>); +pub struct WebGLSender<T>(crossbeam_channel::Sender<T>); +pub struct WebGLReceiver<T>(crossbeam_channel::Receiver<T>); impl<T> Clone for WebGLSender<T> { fn clone(&self) -> Self { @@ -37,24 +36,27 @@ impl<T> Clone for WebGLSender<T> { impl<T> WebGLSender<T> { #[inline] - pub fn send(&self, data: T) -> Result<(), mpsc::SendError<T>> { + pub fn send(&self, data: T) -> Result<(), crossbeam_channel::SendError<T>> { self.0.send(data) } } impl<T> WebGLReceiver<T> { #[inline] - pub fn recv(&self) -> Result<T, mpsc::RecvError> { + pub fn recv(&self) -> Result<T, crossbeam_channel::RecvError> { self.0.recv() } #[inline] - pub fn try_recv(&self) -> Result<T, mpsc::TryRecvError> { + pub fn try_recv(&self) -> Result<T, crossbeam_channel::TryRecvError> { self.0.try_recv() } + pub fn into_inner(self) -> crossbeam_channel::Receiver<T> { + self.0 + } } pub fn webgl_channel<T>() -> Result<(WebGLSender<T>, WebGLReceiver<T>), ()> { - let (sender, receiver) = mpsc::channel(); + let (sender, receiver) = crossbeam_channel::unbounded(); Ok((WebGLSender(sender), WebGLReceiver(receiver))) } diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index e8ec781bcfd..589c45a9c73 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -16,6 +16,7 @@ default = [] gl = ["gleam", "pixels"] [dependencies] +canvas = { path = "../canvas" } crossbeam-channel = "0.4" embedder_traits = {path = "../embedder_traits"} euclid = "0.20" diff --git a/components/compositing/windowing.rs b/components/compositing/windowing.rs index 4dfa27a9d02..a27473ca0f1 100644 --- a/components/compositing/windowing.rs +++ b/components/compositing/windowing.rs @@ -4,6 +4,7 @@ //! Abstract windowing methods. The concrete implementations of these can be found in `platform/`. +use canvas::{SurfaceProviders, WebGlExecutor}; use embedder_traits::EventLoopWaker; use euclid::Scale; #[cfg(feature = "gl")] @@ -184,7 +185,13 @@ pub trait EmbedderMethods { } /// Register services with a WebXR Registry. - fn register_webxr(&mut self, _: &mut webxr::MainThreadRegistry) {} + fn register_webxr( + &mut self, + _: &mut webxr::MainThreadRegistry, + _: WebGlExecutor, + _: SurfaceProviders, + ) { + } } #[derive(Clone, Copy, Debug)] diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index c285145d994..2d6fcf9122d 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -142,9 +142,11 @@ impl WebGLFramebuffer { size: Size2D<i32, Viewport>, ) -> Option<(WebXRSwapChainId, DomRoot<Self>)> { let (sender, receiver) = webgl_channel().unwrap(); - let _ = context - .webgl_sender() - .send_create_webxr_swap_chain(size.to_untyped(), sender); + let _ = context.webgl_sender().send_create_webxr_swap_chain( + size.to_untyped(), + sender, + session.session_id(), + ); let swap_chain_id = receiver.recv().unwrap()?; let framebuffer_id = WebGLFramebufferId::Opaque(WebGLOpaqueFramebufferId::WebXR(swap_chain_id)); diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index ca5c08b25e3..65134a631e1 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -81,6 +81,7 @@ use std::cell::Cell; use std::cmp; use std::ptr::{self, NonNull}; use std::rc::Rc; +use webxr_api::SessionId; use webxr_api::SwapChainId as WebXRSwapChainId; // From the GLES 2.0.25 spec, page 85: @@ -4576,8 +4577,9 @@ impl WebGLMessageSender { &self, size: Size2D<i32>, sender: WebGLSender<Option<WebXRSwapChainId>>, + id: SessionId, ) -> WebGLSendResult { - self.wake_after_send(|| self.sender.send_create_webxr_swap_chain(size, sender)) + self.wake_after_send(|| self.sender.send_create_webxr_swap_chain(size, sender, id)) } pub fn send_resize( diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index ec51c910a17..ecb78615897 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -51,7 +51,7 @@ use std::mem; use std::rc::Rc; use webxr_api::{ self, util, Display, EnvironmentBlendMode, Event as XREvent, Frame, SelectEvent, SelectKind, - Session, View, Viewer, Visibility, + Session, SessionId, View, Viewer, Visibility, }; #[dom_struct] @@ -462,6 +462,10 @@ impl XRSession { viewport: Rect::from_size(size.to_i32()), } } + + pub fn session_id(&self) -> SessionId { + self.session.borrow().id() + } } impl XRSessionMethods for XRSession { diff --git a/components/servo/lib.rs b/components/servo/lib.rs index bb408eaa2b5..a71a1e708ba 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -65,7 +65,7 @@ fn webdriver(_port: u16, _constellation: Sender<ConstellationMsg>) {} use bluetooth::BluetoothThreadFactory; use bluetooth_traits::BluetoothRequest; -use canvas::WebGLComm; +use canvas::{SurfaceProviders, WebGLComm, WebGlExecutor}; use canvas_traits::webgl::WebGLThreads; use compositing::compositor_thread::{ CompositorProxy, CompositorReceiver, InitialCompositorState, Msg, @@ -432,14 +432,6 @@ where panic!("We don't currently support running both WebVR and WebXR"); } - // For the moment, we enable use both the webxr crate and the rust-webvr crate, - // but we are migrating over to just using webxr. - let mut webxr_main_thread = webxr::MainThreadRegistry::new(event_loop_waker) - .expect("Failed to create WebXR device registry"); - if pref!(dom.webxr.enabled) { - embedder.register_webxr(&mut webxr_main_thread); - } - let mut webvr_heartbeats = Vec::new(); let webvr_services = if pref!(dom.webvr.enabled) { let mut services = VRServiceManager::new(); @@ -468,7 +460,12 @@ where let (external_image_handlers, external_images) = WebrenderExternalImageHandlers::new(); let mut external_image_handlers = Box::new(external_image_handlers); - let webgl_threads = create_webgl_threads( + // For the moment, we enable use both the webxr crate and the rust-webvr crate, + // but we are migrating over to just using webxr. + let mut webxr_main_thread = webxr::MainThreadRegistry::new(event_loop_waker) + .expect("Failed to create WebXR device registry"); + + let (webgl_threads, webgl_extras) = create_webgl_threads( &*window, &mut webrender, webrender_api_sender.clone(), @@ -478,6 +475,16 @@ where external_images.clone(), ); + if pref!(dom.webxr.enabled) { + if let Some((webxr_surface_providers, webgl_executor)) = webgl_extras { + embedder.register_webxr( + &mut webxr_main_thread, + webgl_executor, + webxr_surface_providers, + ); + } + } + let glplayer_threads = match window.get_gl_context() { GlContext::Unknown => None, _ => { @@ -1060,7 +1067,10 @@ fn create_webgl_threads<W>( webxr_main_thread: &mut webxr::MainThreadRegistry, external_image_handlers: &mut WebrenderExternalImageHandlers, external_images: Arc<Mutex<WebrenderExternalImageRegistry>>, -) -> Option<WebGLThreads> +) -> ( + Option<WebGLThreads>, + Option<(SurfaceProviders, WebGlExecutor)>, +) where W: WindowMethods + 'static + ?Sized, { @@ -1074,7 +1084,7 @@ where Ok(a) => a, Err(e) => { warn!("Failed to create software graphics context: {:?}", e); - return None; + return (None, None); }, }; (Device::Software(device), Context::Software(context)) @@ -1083,7 +1093,7 @@ where Ok(a) => a, Err(e) => { warn!("Failed to create hardware graphics context: {:?}", e); - return None; + return (None, None); }, }; (Device::Hardware(device), Context::Hardware(context)) @@ -1094,7 +1104,7 @@ where Ok(a) => a, Err(e) => { warn!("Failed to create graphics context: {:?}", e); - return None; + return (None, None); }, }; @@ -1106,8 +1116,10 @@ where let WebGLComm { webgl_threads, webxr_swap_chains, + webxr_surface_providers, image_handler, output_handler, + webgl_executor, } = WebGLComm::new( device, context, @@ -1129,5 +1141,8 @@ where webrender.set_output_image_handler(output_handler); } - Some(webgl_threads) + ( + Some(webgl_threads), + Some((webxr_surface_providers, webgl_executor)), + ) } diff --git a/ports/glutin/embedder.rs b/ports/glutin/embedder.rs index 44c925af3e4..af65d4c34a1 100644 --- a/ports/glutin/embedder.rs +++ b/ports/glutin/embedder.rs @@ -12,6 +12,7 @@ use glutin; use glutin::dpi::LogicalSize; use glutin::EventsLoopClosed; use rust_webvr::GlWindowVRService; +use servo::canvas::{SurfaceProviders, WebGlExecutor}; use servo::compositing::windowing::EmbedderMethods; use servo::embedder_traits::EventLoopWaker; use servo::servo_config::{opts, pref}; @@ -89,7 +90,12 @@ impl EmbedderMethods for EmbedderCallbacks { } } - fn register_webxr(&mut self, xr: &mut webxr::MainThreadRegistry) { + fn register_webxr( + &mut self, + xr: &mut webxr::MainThreadRegistry, + _executor: WebGlExecutor, + _surface_provider_registration: SurfaceProviders + ) { if pref!(dom.webxr.test) { xr.register_mock(webxr::headless::HeadlessMockDiscovery::new()); } else if !opts::get().headless && pref!(dom.webxr.glwindow) { diff --git a/ports/libsimpleservo/api/src/lib.rs b/ports/libsimpleservo/api/src/lib.rs index fcbcf89cc6d..64eddcb40e2 100644 --- a/ports/libsimpleservo/api/src/lib.rs +++ b/ports/libsimpleservo/api/src/lib.rs @@ -13,6 +13,7 @@ pub use servo::embedder_traits::{ pub use servo::script_traits::{MediaSessionActionType, MouseButton}; use getopts::Options; +use servo::canvas::{SurfaceProviders, WebGlExecutor}; use servo::compositing::windowing::{ AnimationState, EmbedderCoordinates, EmbedderMethods, MouseWindowEvent, WindowEvent, WindowMethods, @@ -723,19 +724,52 @@ impl EmbedderMethods for ServoEmbedderCallbacks { } #[cfg(feature = "uwp")] - fn register_webxr(&mut self, registry: &mut webxr::MainThreadRegistry) { + fn register_webxr( + &mut self, + registry: &mut webxr::MainThreadRegistry, + executor: WebGlExecutor, + surface_providers: SurfaceProviders, + ) { debug!("EmbedderMethods::register_xr"); assert!( self.xr_discovery.is_none(), "UWP builds should not be initialized with a WebXR Discovery object" ); - let gl = self.gl.clone(); - let discovery = webxr::openxr::OpenXrDiscovery::new(gl); + + struct ProviderRegistration(SurfaceProviders); + impl webxr::openxr::SurfaceProviderRegistration for ProviderRegistration { + fn register(&self, id: webxr_api::SessionId, provider: servo::canvas::SurfaceProvider) { + self.0.lock().unwrap().insert(id, provider); + } + fn clone(&self) -> Box<dyn webxr::openxr::SurfaceProviderRegistration> { + Box::new(ProviderRegistration(self.0.clone())) + } + } + + struct GlThread(WebGlExecutor); + impl webxr::openxr::GlThread for GlThread { + fn execute(&self, runnable: Box<dyn FnOnce() + Send>) { + let _ = self.0.send(runnable); + } + fn clone(&self) -> Box<dyn webxr::openxr::GlThread> { + Box::new(GlThread(self.0.clone())) + } + } + + let discovery = webxr::openxr::OpenXrDiscovery::new( + Box::new(GlThread(executor)), + Box::new(ProviderRegistration(surface_providers)), + ); registry.register(discovery); } #[cfg(not(feature = "uwp"))] - fn register_webxr(&mut self, registry: &mut webxr::MainThreadRegistry) { + fn register_webxr( + &mut self, + registry: &mut webxr::MainThreadRegistry, + _executor: WebGlExecutor, + _surface_provider_registration: SurfaceProviders, + ) { debug!("EmbedderMethods::register_xr"); if let Some(discovery) = self.xr_discovery.take() { registry.register(discovery); diff --git a/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini b/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini index 087ab66dcda..32055007d4e 100644 --- a/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini +++ b/tests/wpt/webgl/meta/conformance2/uniforms/incompatible-texture-type-for-sampler.html.ini @@ -1,2 +1,2 @@ [incompatible-texture-type-for-sampler.html] - expected: CRASH + expected: TIMEOUT |