diff --git a/Cargo.lock b/Cargo.lock index ebb2e03d7d12..8c691485ce55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -411,6 +411,7 @@ dependencies = [ "webrender 0.60.0 (git+https://github.com/servo/webrender)", "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", "webrender_traits 0.0.1", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -431,7 +432,7 @@ dependencies = [ "typetag 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -621,7 +622,7 @@ dependencies = [ "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", "webvr 0.0.1", "webvr_traits 0.0.1", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -664,7 +665,7 @@ dependencies = [ "style_traits 0.0.1", "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -1087,7 +1088,7 @@ dependencies = [ "servo_url 0.0.1", "style_traits 0.0.1", "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -2537,7 +2538,7 @@ dependencies = [ "webrender_traits 0.0.1", "webvr 0.0.1", "webvr_traits 0.0.1", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -3912,7 +3913,7 @@ dependencies = [ "uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", "xml5ever 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4004,7 +4005,7 @@ dependencies = [ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "webrender_api 0.60.0 (git+https://github.com/servo/webrender)", "webvr_traits 0.0.1", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] @@ -4101,8 +4102,8 @@ dependencies = [ "servo-media 0.1.0 (git+https://github.com/servo/media)", "sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "tinyfiledialogs 3.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "webxr 0.0.1 (git+https://github.com/servo/webxr)", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winres 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "x11 2.17.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5495,25 +5496,24 @@ dependencies = [ [[package]] name = "webxr" version = "0.0.1" -source = "git+https://github.com/servo/webxr#0418277175dbccf83e575c99d6b9c778bfdbe70b" +source = "git+https://github.com/asajeffrey/webxr?branch=optional-glsync#da820a3ab266fce07c9a8abee3e6e9231cb93ec5" dependencies = [ "euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "webxr-api 0.0.1 (git+https://github.com/servo/webxr)", + "webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)", ] [[package]] name = "webxr-api" version = "0.0.1" -source = "git+https://github.com/servo/webxr#0418277175dbccf83e575c99d6b9c778bfdbe70b" +source = "git+https://github.com/asajeffrey/webxr?branch=optional-glsync#da820a3ab266fce07c9a8abee3e6e9231cb93ec5" dependencies = [ "euclid 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", "gleam 0.6.18 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "typetag 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -6142,8 +6142,8 @@ dependencies = [ "checksum webrender 0.60.0 (git+https://github.com/servo/webrender)" = "" "checksum webrender_api 0.60.0 (git+https://github.com/servo/webrender)" = "" "checksum webrender_build 0.0.1 (git+https://github.com/servo/webrender)" = "" -"checksum webxr 0.0.1 (git+https://github.com/servo/webxr)" = "" -"checksum webxr-api 0.0.1 (git+https://github.com/servo/webxr)" = "" +"checksum webxr 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)" = "" +"checksum webxr-api 0.0.1 (git+https://github.com/asajeffrey/webxr?branch=optional-glsync)" = "" "checksum weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3bb43f70885151e629e2a19ce9e50bd730fd436cfd4b666894c9ce4de9141164" "checksum which 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b57acb10231b9493c8472b20cb57317d0679a49e0bdbee44b3b803a6473af164" "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" diff --git a/Cargo.toml b/Cargo.toml index 060be41a5d2d..b802517ea5e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,7 @@ opt-level = 3 mio = { git = "https://github.com/servo/mio.git", branch = "servo" } iovec = { git = "https://github.com/servo/iovec.git", branch = "servo" } cmake = { git = "https://github.com/alexcrichton/cmake-rs" } + +[patch."https://github.com/servo/webxr"] +webxr = { git = "https://github.com/asajeffrey/webxr", branch = "optional-glsync" } +webxr-api = { git = "https://github.com/asajeffrey/webxr", branch = "optional-glsync" } diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 03a77826ac72..bdcb93b85072 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -37,3 +37,4 @@ servo_config = {path = "../config"} webrender = {git = "https://github.com/servo/webrender"} webrender_api = {git = "https://github.com/servo/webrender", features = ["ipc"]} webrender_traits = {path = "../webrender_traits"} +webxr-api = {git = "https://github.com/servo/webxr", features = ["ipc"]} diff --git a/components/canvas/webgl_mode/inprocess.rs b/components/canvas/webgl_mode/inprocess.rs index 34a3f0eeb7a2..1ca4e9c53cb7 100644 --- a/components/canvas/webgl_mode/inprocess.rs +++ b/components/canvas/webgl_mode/inprocess.rs @@ -1,7 +1,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * 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::gl_context::GLContextFactory; use crate::webgl_thread::{WebGLMainThread, WebGLThread, WebGLThreadInit}; use canvas_traits::webgl::webgl_channel; @@ -17,6 +16,7 @@ use std::default::Default; use std::rc::Rc; use std::sync::{Arc, Mutex}; use webrender_traits::{WebrenderExternalImageApi, WebrenderExternalImageRegistry}; +use webxr_api::WebGLExternalImageApi; /// WebGL Threading API entry point that lives in the constellation. pub struct WebGLThreads(WebGLSender); @@ -38,6 +38,7 @@ impl WebGLThreads { ) -> ( WebGLThreads, Option>, + Box, Box, Option>, ) { @@ -77,6 +78,7 @@ impl WebGLThreads { ( WebGLThreads(sender), webgl_thread, + external.sendable.clone_box(), Box::new(external), output_handler.map(|b| b as Box<_>), ) @@ -96,9 +98,8 @@ impl WebGLThreads { } } -/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads. -struct WebGLExternalImages { - webrender_gl: Rc, +/// Bridge between the webxr_api::ExternalImage callbacks and the WebGLThreads. +struct SendableWebGLExternalImages { webgl_channel: WebGLSender, // Used to avoid creating a new channel on each received WebRender request. lock_channel: ( @@ -107,24 +108,26 @@ struct WebGLExternalImages { ), } -impl WebGLExternalImages { - fn new(webrender_gl: Rc, channel: WebGLSender) -> Self { - WebGLExternalImages { - webrender_gl, +impl SendableWebGLExternalImages { + fn new(channel: WebGLSender) -> Self { + Self { webgl_channel: channel, lock_channel: webgl_channel().unwrap(), } } } -impl WebrenderExternalImageApi for WebGLExternalImages { - fn lock(&mut self, id: u64) -> (u32, Size2D) { +impl webxr_api::WebGLExternalImageApi for SendableWebGLExternalImages { + fn lock(&self, id: usize) -> (u32, Size2D, Option) { if let Some(main_thread) = WebGLMainThread::on_current_thread() { // If we're on the same thread as WebGL, we can get the data directly - main_thread + let (image_id, size) = main_thread .thread_data .borrow_mut() - .handle_lock_unsync(WebGLContextId(id as usize)) + .handle_lock_unsync(WebGLContextId(id as usize)); + // We don't need a GLsync object if we're running on the main thread + // Might be better to return an option? + (image_id, size, None) } else { // WebGL Thread has it's own GL command queue that we need to synchronize with the WR GL command queue. // The WebGLMsg::Lock message inserts a fence in the WebGL command queue. @@ -135,16 +138,11 @@ impl WebrenderExternalImageApi for WebGLExternalImages { )) .unwrap(); let (image_id, size, gl_sync) = self.lock_channel.1.recv().unwrap(); - // The next glWaitSync call is run on the WR thread and it's used to synchronize the two - // flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture. - // glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem. - self.webrender_gl - .wait_sync(gl_sync as gl::GLsync, 0, gl::TIMEOUT_IGNORED); - (image_id, size) + (image_id, size, Some(gl_sync as gl::GLsync)) } } - fn unlock(&mut self, id: u64) { + fn unlock(&self, id: usize) { if let Some(main_thread) = WebGLMainThread::on_current_thread() { // If we're on the same thread as WebGL, we can unlock directly main_thread @@ -157,6 +155,42 @@ impl WebrenderExternalImageApi for WebGLExternalImages { .unwrap() } } + + fn clone_box(&self) -> Box { + Box::new(Self::new(self.webgl_channel.clone())) + } +} + +/// Bridge between the webrender::ExternalImage callbacks and the WebGLThreads. +struct WebGLExternalImages { + webrender_gl: Rc, + sendable: SendableWebGLExternalImages, +} + +impl WebGLExternalImages { + fn new(webrender_gl: Rc, channel: WebGLSender) -> Self { + Self { + webrender_gl, + sendable: SendableWebGLExternalImages::new(channel), + } + } +} + +impl WebrenderExternalImageApi for WebGLExternalImages { + fn lock(&mut self, id: u64) -> (u32, Size2D) { + let (image_id, size, gl_sync) = self.sendable.lock(id as usize); + // The next glWaitSync call is run on the WR thread and it's used to synchronize the two + // flows of OpenGL commands in order to avoid WR using a semi-ready WebGL texture. + // glWaitSync doesn't block WR thread, it affects only internal OpenGL subsystem. + if let Some(gl_sync) = gl_sync { + self.webrender_gl.wait_sync(gl_sync, 0, gl::TIMEOUT_IGNORED); + } + (image_id, size) + } + + fn unlock(&mut self, id: u64) { + self.sendable.unlock(id as usize); + } } /// struct used to implement DOMToTexture feature and webrender::OutputImageHandler trait. diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index 01262de02f26..f2099094127e 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -10,7 +10,7 @@ use euclid::default::Size2D; use fnv::FnvHashMap; use gleam::gl; use half::f16; -use ipc_channel::ipc::{self, IpcSender, OpaqueIpcMessage}; +use ipc_channel::ipc::{self, OpaqueIpcMessage}; use ipc_channel::router::ROUTER; use offscreen_gl_context::{DrawBuffer, GLContext, NativeGLContextMethods}; use pixels::{self, PixelFormat}; @@ -284,9 +284,6 @@ impl WebGLThread { WebGLMsg::Lock(ctx_id, sender) => { self.handle_lock(ctx_id, sender); }, - WebGLMsg::LockIPC(ctx_id, sender) => { - self.handle_lock_ipc(ctx_id, sender); - }, WebGLMsg::Unlock(ctx_id) => { self.handle_unlock(ctx_id); }, @@ -343,21 +340,6 @@ impl WebGLThread { context_id: WebGLContextId, sender: WebGLSender<(u32, Size2D, usize)>, ) { - sender.send(self.handle_lock_sync(context_id)).unwrap(); - } - - /// handle_lock, but unconditionally IPC (used by webxr) - fn handle_lock_ipc( - &mut self, - context_id: WebGLContextId, - sender: IpcSender<(u32, Size2D, usize)>, - ) { - sender.send(self.handle_lock_sync(context_id)).unwrap(); - } - - /// Shared code between handle_lock and handle_lock_ipc, does the actual syncing/flushing - /// but the caller must send the response back - fn handle_lock_sync(&mut self, context_id: WebGLContextId) -> (u32, Size2D, usize) { let data = Self::make_current_if_needed(context_id, &self.contexts, &mut self.bound_context_id) .expect("WebGLContext not found in a WebGLMsg::Lock message"); @@ -374,7 +356,7 @@ impl WebGLThread { data.ctx.gl().flush(); debug_assert!(data.ctx.gl().get_error() == gl::NO_ERROR); - (info.texture_id, info.size, gl_sync as usize) + let _ = sender.send((info.texture_id, info.size, gl_sync as usize)); } /// A version of locking that doesn't return a GLsync object, diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index b33f5eae1be4..a037b5288747 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -4,10 +4,8 @@ use euclid::default::{Rect, Size2D}; use gleam::gl; -use gleam::gl::GLsync; -use gleam::gl::GLuint; use gleam::gl::Gl; -use ipc_channel::ipc::{self, IpcBytesReceiver, IpcBytesSender, IpcSender, IpcSharedMemory}; +use ipc_channel::ipc::{IpcBytesReceiver, IpcBytesSender, IpcSharedMemory}; use pixels::PixelFormat; use std::borrow::Cow; use std::fmt; @@ -61,8 +59,6 @@ pub enum WebGLMsg { /// The WR client should not change the shared texture content until the Unlock call. /// Currently OpenGL Sync Objects are used to implement the synchronization mechanism. Lock(WebGLContextId, WebGLSender<(u32, Size2D, usize)>), - /// Lock(), but unconditionally IPC (used by webxr) - LockIPC(WebGLContextId, IpcSender<(u32, Size2D, usize)>), /// Unlocks a specific WebGLContext. Unlock messages are used for a correct synchronization /// with WebRender external image API. /// The WR unlocks a context when it finished reading the shared texture contents. @@ -185,39 +181,6 @@ impl WebGLMsgSender { pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult { self.sender.send(WebGLMsg::DOMToTextureCommand(command)) } - - pub fn webxr_external_image_api(&self) -> impl webxr_api::WebGLExternalImageApi { - SerializableWebGLMsgSender { - ctx_id: self.ctx_id, - sender: self.sender.to_ipc(), - } - } -} - -// WegGLMsgSender isn't actually serializable, despite what it claims. -#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] -struct SerializableWebGLMsgSender { - ctx_id: WebGLContextId, - #[ignore_malloc_size_of = "channels are hard"] - sender: IpcSender, -} - -#[typetag::serde] -impl webxr_api::WebGLExternalImageApi for SerializableWebGLMsgSender { - fn lock(&self) -> Result<(GLuint, Size2D, GLsync), webxr_api::Error> { - let (sender, receiver) = ipc::channel().or(Err(webxr_api::Error::CommunicationError))?; - self.sender - .send(WebGLMsg::LockIPC(self.ctx_id, sender)) - .or(Err(webxr_api::Error::CommunicationError))?; - let (texture, size, sync) = receiver - .recv() - .or(Err(webxr_api::Error::CommunicationError))?; - Ok((texture, size, sync as GLsync)) - } - - fn unlock(&self) { - let _ = self.sender.send(WebGLMsg::Unlock(self.ctx_id)); - } } #[derive(Deserialize, Serialize)] diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 743a2adec84f..3a273f3cfa38 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -328,6 +328,10 @@ impl WebGLRenderingContext { self.webgl_sender.clone() } + pub fn context_id(&self) -> WebGLContextId { + self.webgl_sender.context_id() + } + #[inline] pub fn send_command(&self, command: WebGLCommand) { self.webgl_sender @@ -4377,8 +4381,4 @@ impl WebGLMessageSender { pub fn send_dom_to_texture(&self, command: DOMToTextureCommand) -> WebGLSendResult { self.wake_after_send(|| self.sender.send_dom_to_texture(command)) } - - pub fn webxr_external_image_api(&self) -> impl webxr_api::WebGLExternalImageApi { - self.sender.webxr_external_image_api() - } } diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index d24e8f144cd1..8deead58b92e 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -108,18 +108,6 @@ impl Into for XRSessionMode { impl XRMethods for XR { /// https://immersive-web.github.io/webxr/#dom-xr-supportssessionmode fn SupportsSession(&self, mode: XRSessionMode) -> Rc { - #[derive(serde::Serialize, serde::Deserialize)] - pub struct SupportsSession { - sender: IpcSender, - } - - #[typetag::serde] - impl webxr_api::SessionSupportCallback for SupportsSession { - fn callback(&mut self, result: Result<(), XRError>) { - let _ = self.sender.send(result.is_ok()); - } - } - // XXXManishearth this should select an XR device first let promise = Promise::new(&self.global()); let mut trusted = Some(TrustedPromise::new(promise.clone())); @@ -139,13 +127,13 @@ impl XRMethods for XR { error!("supportsSession callback called twice!"); return; }; - let message = if let Ok(message) = message.to() { + let message: Result<(), webxr_api::Error> = if let Ok(message) = message.to() { message } else { error!("supportsSession callback given incorrect payload"); return; }; - if message { + if let Ok(()) = message { let _ = task_source.queue_with_canceller(trusted.resolve_task(()), &canceller); } else { let _ = task_source @@ -155,7 +143,7 @@ impl XRMethods for XR { ); window .webxr_registry() - .supports_session(mode.into(), SupportsSession { sender }); + .supports_session(mode.into(), sender); promise } @@ -167,17 +155,6 @@ impl XRMethods for XR { _: &XRSessionInit, comp: InCompartment, ) -> Rc { - #[derive(serde::Serialize, serde::Deserialize)] - pub struct RequestSession { - sender: IpcSender>, - } - - #[typetag::serde] - impl webxr_api::SessionRequestCallback for RequestSession { - fn callback(&mut self, result: Result) { - let _ = self.sender.send(result); - } - } let promise = Promise::new_in_current_compartment(&self.global(), comp); if mode != XRSessionMode::Immersive_vr { promise.reject_error(Error::NotSupported); @@ -206,7 +183,7 @@ impl XRMethods for XR { // router doesn't know this is only called once let trusted = trusted.take().unwrap(); let this = this.clone(); - let message = if let Ok(message) = message.to() { + let message: Result = if let Ok(message) = message.to() { message } else { error!("requestSession callback given incorrect payload"); @@ -220,9 +197,7 @@ impl XRMethods for XR { ); }), ); - window - .webxr_registry() - .request_session(mode.into(), RequestSession { sender }); + window.webxr_registry().request_session(mode.into(), sender); promise } diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 9542486f3ae0..0a9712bb92be 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -124,18 +124,6 @@ impl XRSession { } fn attach_event_handler(&self) { - #[derive(serde::Serialize, serde::Deserialize)] - pub struct EventCallback { - sender: IpcSender, - } - - #[typetag::serde] - impl webxr_api::EventCallback for EventCallback { - fn callback(&mut self, event: XREvent) { - let _ = self.sender.send(event); - } - } - let this = Trusted::new(self); let global = self.global(); let window = global.as_window(); @@ -143,6 +131,7 @@ impl XRSession { .task_manager() .dom_manipulation_task_source_with_canceller(); let (sender, receiver) = ipc::channel(global.time_profiler_chan().clone()).unwrap(); + ROUTER.add_route( receiver.to_opaque(), Box::new(move |message| { @@ -157,9 +146,7 @@ impl XRSession { ); // request animation frame - self.session - .borrow_mut() - .set_event_callback(EventCallback { sender }); + self.session.borrow_mut().set_event_dest(sender); } fn event_callback(&self, event: XREvent) { @@ -195,13 +182,10 @@ impl XRSession { // Step 6-7: XXXManishearth handle inlineVerticalFieldOfView // XXXManishearth handle inline sessions and composition disabled flag - let layer = pending.GetBaseLayer(); - if let Some(layer) = layer { - let mut session = self.session.borrow_mut(); - session.update_webgl_external_image_api( - layer.Context().webgl_sender().webxr_external_image_api(), - ); - } + let context = pending + .GetBaseLayer() + .map(|layer| layer.Context().context_id().0); + self.session.borrow_mut().set_webgl_context(context); } // Step 2 @@ -289,18 +273,6 @@ impl XRSessionMethods for XRSession { /// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe fn RequestAnimationFrame(&self, callback: Rc) -> i32 { - #[derive(serde::Serialize, serde::Deserialize)] - pub struct FrameCallback { - sender: IpcSender<(f64, Frame)>, - } - - #[typetag::serde] - impl webxr_api::FrameRequestCallback for FrameCallback { - fn callback(&mut self, time: f64, frame: Frame) { - let _ = self.sender.send((time, frame)); - } - } - // queue up RAF callback, obtain ID let raf_id = self.next_raf_id.get(); self.next_raf_id.set(raf_id + 1); @@ -334,9 +306,7 @@ impl XRSessionMethods for XRSession { let sender = self.raf_sender.borrow().clone().unwrap(); // request animation frame - self.session - .borrow_mut() - .request_animation_frame(FrameCallback { sender }); + self.session.borrow_mut().request_animation_frame(sender); raf_id } diff --git a/components/script/dom/xrtest.rs b/components/script/dom/xrtest.rs index c8f45b75b4fd..3c376366faf8 100644 --- a/components/script/dom/xrtest.rs +++ b/components/script/dom/xrtest.rs @@ -73,20 +73,6 @@ impl XRTest { impl XRTestMethods for XRTest { /// https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md fn SimulateDeviceConnection(&self, init: &FakeXRDeviceInit) -> Rc { - #[derive(serde::Serialize, serde::Deserialize)] - pub struct MockDevice { - sender: IpcSender, XRError>>, - } - - #[typetag::serde] - impl webxr_api::MockDeviceCallback for MockDevice { - fn callback(&mut self, result: Result, XRError>) { - self.sender - .send(result) - .expect("mock device callback failed"); - } - } - let p = Promise::new(&self.global()); if !init.supportsImmersive || self.session_started.get() { @@ -166,7 +152,7 @@ impl XRTestMethods for XRTest { ); window .webxr_registry() - .simulate_device_connection(init, MockDevice { sender }); + .simulate_device_connection(init, sender); p } diff --git a/components/servo/lib.rs b/components/servo/lib.rs index d94700f11feb..544517e7e7a5 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -418,22 +418,26 @@ where // Initialize WebGL Thread entry point. let webgl_result = gl_factory.map(|factory| { - let (webgl_threads, thread_data, image_handler, output_handler) = WebGLThreads::new( - factory, - window.gl(), - webrender_api_sender.clone(), - webvr_compositor.map(|c| c as Box<_>), - external_images.clone(), - if run_webgl_on_main_thread { - ThreadMode::MainThread(embedder.create_event_loop_waker()) - } else { - ThreadMode::OffThread - }, - ); + let (webgl_threads, thread_data, webxr_handler, image_handler, output_handler) = + WebGLThreads::new( + factory, + window.gl(), + webrender_api_sender.clone(), + webvr_compositor.map(|c| c as Box<_>), + external_images.clone(), + if run_webgl_on_main_thread { + ThreadMode::MainThread(embedder.create_event_loop_waker()) + } else { + ThreadMode::OffThread + }, + ); // Set webrender external image handler for WebGL textures external_image_handlers.set_handler(image_handler, WebrenderImageHandlerType::WebGL); + // Set webxr external image handler for WebGL textures + webxr_main_thread.set_webgl(webxr_handler); + // Set DOM to texture handler, if enabled. if let Some(output_handler) = output_handler { webrender.set_output_image_handler(output_handler);