diff options
Diffstat (limited to 'components/script/dom')
35 files changed, 89 insertions, 2119 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 305c6327b82..cefc930af0a 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -157,7 +157,6 @@ use webgpu::{ WebGPUPipelineLayout, WebGPUQueue, WebGPUShaderModule, }; use webrender_api::{DocumentId, ImageKey}; -use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState}; use webxr_api::SwapChainId as WebXRSwapChainId; unsafe_no_jsmanaged_fields!(Tm); @@ -548,7 +547,6 @@ unsafe_no_jsmanaged_fields!(RefCell<Option<RawPass>>); unsafe_no_jsmanaged_fields!(GPUBufferState); unsafe_no_jsmanaged_fields!(WebXRSwapChainId); unsafe_no_jsmanaged_fields!(MediaList); -unsafe_no_jsmanaged_fields!(WebVRGamepadData, WebVRGamepadState, WebVRGamepadHand); unsafe_no_jsmanaged_fields!( webxr_api::Registry, webxr_api::Session, diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 21f82be9cee..80217fea8fb 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -44,6 +44,7 @@ use js::rust::wrappers::JS_HasPropertyById; use js::rust::wrappers::JS_SetProperty; use js::rust::{get_object_class, is_dom_class, GCMethods, ToString, ToWindowProxyIfWindow}; use js::rust::{Handle, HandleId, HandleObject, HandleValue, MutableHandleValue}; +use js::typedarray::{CreateWith, Float32Array}; use js::JS_CALLEE; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use std::ffi::CString; @@ -134,6 +135,15 @@ pub fn to_frozen_array<T: ToJSValConvertible>(convertibles: &[T], cx: SafeJSCont *ports } +/// Creates a Float32 array +pub fn create_typed_array(cx: SafeJSContext, src: &[f32], dst: &Heap<*mut JSObject>) { + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); + unsafe { + let _ = Float32Array::create(*cx, CreateWith::Slice(src), array.handle_mut()); + } + (*dst).set(array.get()); +} + /// Returns the ProtoOrIfaceArray for the given global object. /// Fails if `global` is not a DOM global object. pub fn get_proto_or_iface_array(global: *mut JSObject) -> *mut ProtoOrIfaceArray { diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs index 7223450c513..b81d6a7b228 100644 --- a/components/script/dom/gamepad.rs +++ b/components/script/dom/gamepad.rs @@ -2,26 +2,23 @@ * 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::dom::bindings::codegen::Bindings::GamepadBinding::GamepadHand; use crate::dom::bindings::codegen::Bindings::GamepadBinding::GamepadMethods; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::reflector::{DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::DOMString; use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; use crate::dom::gamepadbuttonlist::GamepadButtonList; use crate::dom::gamepadevent::{GamepadEvent, GamepadEventType}; -use crate::dom::globalscope::GlobalScope; -use crate::dom::vrpose::VRPose; +use crate::dom::gamepadpose::GamepadPose; use crate::script_runtime::JSContext; use dom_struct::dom_struct; use js::jsapi::{Heap, JSObject}; -use js::typedarray::{CreateWith, Float64Array}; use std::cell::Cell; -use std::ptr; use std::ptr::NonNull; -use webvr_traits::{WebVRGamepadData, WebVRGamepadHand, WebVRGamepadState}; #[dom_struct] pub struct Gamepad { @@ -35,12 +32,13 @@ pub struct Gamepad { #[ignore_malloc_size_of = "mozjs"] axes: Heap<*mut JSObject>, buttons: Dom<GamepadButtonList>, - pose: Option<Dom<VRPose>>, + pose: Option<Dom<GamepadPose>>, #[ignore_malloc_size_of = "Defined in rust-webvr"] - hand: WebVRGamepadHand, - display_id: u32, + hand: GamepadHand, } +// TODO: support gamepad discovery +#[allow(dead_code)] impl Gamepad { fn new_inherited( gamepad_id: u32, @@ -50,9 +48,8 @@ impl Gamepad { timestamp: f64, mapping_type: String, buttons: &GamepadButtonList, - pose: Option<&VRPose>, - hand: WebVRGamepadHand, - display_id: u32, + pose: Option<&GamepadPose>, + hand: GamepadHand, ) -> Gamepad { Self { reflector_: Reflector::new(), @@ -66,45 +63,8 @@ impl Gamepad { buttons: Dom::from_ref(buttons), pose: pose.map(Dom::from_ref), hand: hand, - display_id: display_id, } } - - #[allow(unsafe_code)] - pub fn new_from_vr( - global: &GlobalScope, - index: i32, - data: &WebVRGamepadData, - state: &WebVRGamepadState, - ) -> DomRoot<Gamepad> { - let buttons = GamepadButtonList::new_from_vr(&global, &state.buttons); - let pose = VRPose::new(&global, &state.pose); - - let gamepad = reflect_dom_object( - Box::new(Gamepad::new_inherited( - state.gamepad_id, - data.name.clone(), - index, - state.connected, - state.timestamp, - "".into(), - &buttons, - Some(&pose), - data.hand.clone(), - data.display_id, - )), - global, - ); - - let cx = global.get_cx(); - rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - unsafe { - let _ = Float64Array::create(*cx, CreateWith::Slice(&state.axes), array.handle_mut()); - } - gamepad.axes.set(array.get()); - - gamepad - } } impl GamepadMethods for Gamepad { @@ -145,44 +105,19 @@ impl GamepadMethods for Gamepad { } // https://w3c.github.io/gamepad/extensions.html#gamepadhand-enum - fn Hand(&self) -> DOMString { - let value = match self.hand { - WebVRGamepadHand::Unknown => "", - WebVRGamepadHand::Left => "left", - WebVRGamepadHand::Right => "right", - }; - value.into() + fn Hand(&self) -> GamepadHand { + self.hand } // https://w3c.github.io/gamepad/extensions.html#dom-gamepad-pose - fn GetPose(&self) -> Option<DomRoot<VRPose>> { + fn GetPose(&self) -> Option<DomRoot<GamepadPose>> { self.pose.as_ref().map(|p| DomRoot::from_ref(&**p)) } - - // https://w3c.github.io/webvr/spec/1.1/#gamepad-getvrdisplays-attribute - fn DisplayId(&self) -> u32 { - self.display_id - } } +// TODO: support gamepad discovery +#[allow(dead_code)] impl Gamepad { - #[allow(unsafe_code)] - pub fn update_from_vr(&self, state: &WebVRGamepadState) { - self.timestamp.set(state.timestamp); - unsafe { - let cx = self.global().get_cx(); - typedarray!(in(*cx) let axes: Float64Array = self.axes.get()); - if let Ok(mut array) = axes { - array.update(&state.axes); - } - } - self.buttons.sync_from_vr(&state.buttons); - if let Some(ref pose) = self.pose { - pose.update(&state.pose); - } - self.update_connected(state.connected); - } - pub fn gamepad_id(&self) -> u32 { self.gamepad_id } diff --git a/components/script/dom/gamepadbutton.rs b/components/script/dom/gamepadbutton.rs index 6bcbcc2a724..e40e7fb4f05 100644 --- a/components/script/dom/gamepadbutton.rs +++ b/components/script/dom/gamepadbutton.rs @@ -18,6 +18,8 @@ pub struct GamepadButton { value: Cell<f64>, } +// TODO: support gamepad discovery +#[allow(dead_code)] impl GamepadButton { pub fn new_inherited(pressed: bool, touched: bool) -> GamepadButton { Self { @@ -53,6 +55,8 @@ impl GamepadButtonMethods for GamepadButton { } } +// TODO: support gamepad discovery +#[allow(dead_code)] impl GamepadButton { pub fn update(&self, pressed: bool, touched: bool) { self.pressed.set(pressed); diff --git a/components/script/dom/gamepadbuttonlist.rs b/components/script/dom/gamepadbuttonlist.rs index 496302de9f9..4d9e86c45ef 100644 --- a/components/script/dom/gamepadbuttonlist.rs +++ b/components/script/dom/gamepadbuttonlist.rs @@ -3,12 +3,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::GamepadButtonListBinding::GamepadButtonListMethods; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::{Dom, DomRoot, DomSlice}; +use crate::dom::bindings::reflector::Reflector; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::gamepadbutton::GamepadButton; -use crate::dom::globalscope::GlobalScope; use dom_struct::dom_struct; -use webvr_traits::WebVRGamepadButton; // https://w3c.github.io/gamepad/#gamepadbutton-interface #[dom_struct] @@ -17,6 +15,8 @@ pub struct GamepadButtonList { list: Vec<Dom<GamepadButton>>, } +// TODO: support gamepad discovery +#[allow(dead_code)] impl GamepadButtonList { #[allow(unrooted_must_root)] fn new_inherited(list: &[&GamepadButton]) -> GamepadButtonList { @@ -25,22 +25,6 @@ impl GamepadButtonList { list: list.iter().map(|button| Dom::from_ref(*button)).collect(), } } - - pub fn new_from_vr( - global: &GlobalScope, - buttons: &[WebVRGamepadButton], - ) -> DomRoot<GamepadButtonList> { - rooted_vec!(let list <- buttons.iter() - .map(|btn| GamepadButton::new(&global, btn.pressed, btn.touched))); - - reflect_dom_object(Box::new(GamepadButtonList::new_inherited(list.r())), global) - } - - pub fn sync_from_vr(&self, vr_buttons: &[WebVRGamepadButton]) { - for (gp_btn, btn) in self.list.iter().zip(vr_buttons.iter()) { - gp_btn.update(btn.pressed, btn.touched); - } - } } impl GamepadButtonListMethods for GamepadButtonList { diff --git a/components/script/dom/gamepadlist.rs b/components/script/dom/gamepadlist.rs index 34479e6bb7c..ed551df4c35 100644 --- a/components/script/dom/gamepadlist.rs +++ b/components/script/dom/gamepadlist.rs @@ -17,6 +17,8 @@ pub struct GamepadList { list: DomRefCell<Vec<Dom<Gamepad>>>, } +// TODO: support gamepad discovery +#[allow(dead_code)] impl GamepadList { fn new_inherited(list: &[&Gamepad]) -> GamepadList { GamepadList { diff --git a/components/script/dom/vrpose.rs b/components/script/dom/gamepadpose.rs index 209e02fde81..10d770ea68a 100644 --- a/components/script/dom/vrpose.rs +++ b/components/script/dom/gamepadpose.rs @@ -2,8 +2,8 @@ * 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::dom::bindings::codegen::Bindings::VRPoseBinding::VRPoseMethods; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::codegen::Bindings::GamepadPoseBinding::GamepadPoseMethods; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::JSContext; @@ -12,10 +12,9 @@ use js::jsapi::{Heap, JSObject}; use js::typedarray::{CreateWith, Float32Array}; use std::ptr; use std::ptr::NonNull; -use webvr_traits::webvr; #[dom_struct] -pub struct VRPose { +pub struct GamepadPose { reflector_: Reflector, #[ignore_malloc_size_of = "mozjs"] position: Heap<*mut JSObject>, @@ -31,6 +30,8 @@ pub struct VRPose { angular_acc: Heap<*mut JSObject>, } +// TODO: support gamepad discovery +#[allow(dead_code)] #[allow(unsafe_code)] fn update_or_create_typed_array(cx: JSContext, src: Option<&[f32]>, dst: &Heap<*mut JSObject>) { match src { @@ -67,9 +68,11 @@ fn heap_to_option(heap: &Heap<*mut JSObject>) -> Option<NonNull<JSObject>> { } } -impl VRPose { - fn new_inherited() -> VRPose { - VRPose { +// TODO: support gamepad discovery +#[allow(dead_code)] +impl GamepadPose { + fn new_inherited() -> GamepadPose { + GamepadPose { reflector_: Reflector::new(), position: Heap::default(), orientation: Heap::default(), @@ -80,71 +83,48 @@ impl VRPose { } } - pub fn new(global: &GlobalScope, pose: &webvr::VRPose) -> DomRoot<VRPose> { - let root = reflect_dom_object(Box::new(VRPose::new_inherited()), global); - root.update(&pose); - root - } - - #[allow(unsafe_code)] - pub fn update(&self, pose: &webvr::VRPose) { - let cx = self.global().get_cx(); - update_or_create_typed_array(cx, pose.position.as_ref().map(|v| &v[..]), &self.position); - update_or_create_typed_array( - cx, - pose.orientation.as_ref().map(|v| &v[..]), - &self.orientation, - ); - update_or_create_typed_array( - cx, - pose.linear_velocity.as_ref().map(|v| &v[..]), - &self.linear_vel, - ); - update_or_create_typed_array( - cx, - pose.angular_velocity.as_ref().map(|v| &v[..]), - &self.angular_vel, - ); - update_or_create_typed_array( - cx, - pose.linear_acceleration.as_ref().map(|v| &v[..]), - &self.linear_acc, - ); - update_or_create_typed_array( - cx, - pose.angular_acceleration.as_ref().map(|v| &v[..]), - &self.angular_acc, - ); + pub fn new(global: &GlobalScope) -> DomRoot<GamepadPose> { + reflect_dom_object(Box::new(GamepadPose::new_inherited()), global) } } -impl VRPoseMethods for VRPose { - // https://w3c.github.io/webvr/#dom-vrpose-position +impl GamepadPoseMethods for GamepadPose { + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-position fn GetPosition(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.position) } - // https://w3c.github.io/webvr/#dom-vrpose-linearvelocity + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-hasposition + fn HasPosition(&self) -> bool { + !self.position.get().is_null() + } + + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-linearvelocity fn GetLinearVelocity(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.linear_vel) } - // https://w3c.github.io/webvr/#dom-vrpose-linearacceleration + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-linearacceleration fn GetLinearAcceleration(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.linear_acc) } - // https://w3c.github.io/webvr/#dom-vrpose-orientation + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-orientation fn GetOrientation(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.orientation) } - // https://w3c.github.io/webvr/#dom-vrpose-angularvelocity + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-orientation + fn HasOrientation(&self) -> bool { + !self.orientation.get().is_null() + } + + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-angularvelocity fn GetAngularVelocity(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.angular_vel) } - // https://w3c.github.io/webvr/#dom-vrpose-angularacceleration + // https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-angularacceleration fn GetAngularAcceleration(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.angular_acc) } diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs index 3969cb8bdd0..b27c02208be 100644 --- a/components/script/dom/macros.rs +++ b/components/script/dom/macros.rs @@ -527,13 +527,6 @@ macro_rules! window_event_handlers( event_handler!(unhandledrejection, GetOnunhandledrejection, SetOnunhandledrejection); event_handler!(unload, GetOnunload, SetOnunload); - event_handler!(vrdisplayconnect, GetOnvrdisplayconnect, SetOnvrdisplayconnect); - event_handler!(vrdisplaydisconnect, GetOnvrdisplaydisconnect, SetOnvrdisplaydisconnect); - event_handler!(vrdisplayactivate, GetOnvrdisplayactivate, SetOnvrdisplayactivate); - event_handler!(vrdisplaydeactivate, GetOnvrdisplaydeactivate, SetOnvrdisplaydeactivate); - event_handler!(vrdisplayblur, GetOnvrdisplayblur, SetOnvrdisplayblur); - event_handler!(vrdisplayfocus, GetOnvrdisplayfocus, SetOnvrdisplayfocus); - event_handler!(vrdisplaypresentchange, GetOnvrdisplaypresentchange, SetOnvrdisplaypresentchange); ); (ForwardToWindow) => ( window_owned_event_handler!(afterprint, GetOnafterprint, @@ -560,14 +553,6 @@ macro_rules! window_event_handlers( window_owned_event_handler!(unhandledrejection, GetOnunhandledrejection, SetOnunhandledrejection); window_owned_event_handler!(unload, GetOnunload, SetOnunload); - - window_owned_event_handler!(vrdisplayconnect, GetOnvrdisplayconnect, SetOnvrdisplayconnect); - window_owned_event_handler!(vrdisplaydisconnect, GetOnvrdisplaydisconnect, SetOnvrdisplaydisconnect); - window_owned_event_handler!(vrdisplayactivate, GetOnvrdisplayactivate, SetOnvrdisplayactivate); - window_owned_event_handler!(vrdisplaydeactivate, GetOnvrdisplaydeactivate, SetOnvrdisplaydeactivate); - window_owned_event_handler!(vrdisplayblur, GetOnvrdisplayblur, SetOnvrdisplayblur); - window_owned_event_handler!(vrdisplayfocus, GetOnvrdisplayfocus, SetOnvrdisplayfocus); - window_owned_event_handler!(vrdisplaypresentchange, GetOnvrdisplaypresentchange, SetOnvrdisplaypresentchange); ); ); diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 6cd85a3db60..dcc9af258cd 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -316,6 +316,7 @@ pub mod gamepadbutton; pub mod gamepadbuttonlist; pub mod gamepadevent; pub mod gamepadlist; +pub mod gamepadpose; pub mod globalscope; pub mod gpu; pub mod gpuadapter; @@ -532,14 +533,6 @@ pub mod vertexarrayobject; pub mod videotrack; pub mod videotracklist; pub mod virtualmethods; -pub mod vrdisplay; -pub mod vrdisplaycapabilities; -pub mod vrdisplayevent; -pub mod vreyeparameters; -pub mod vrfieldofview; -pub mod vrframedata; -pub mod vrpose; -pub mod vrstageparameters; pub mod vttcue; pub mod vttregion; pub mod webgl_extensions; diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 731960518ea..f7747f37973 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods; -use crate::dom::bindings::error::Error; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::str::DOMString; @@ -16,13 +15,10 @@ use crate::dom::mimetypearray::MimeTypeArray; use crate::dom::navigatorinfo; use crate::dom::permissions::Permissions; use crate::dom::pluginarray::PluginArray; -use crate::dom::promise::Promise; use crate::dom::serviceworkercontainer::ServiceWorkerContainer; use crate::dom::window::Window; use crate::dom::xrsystem::XRSystem; -use crate::realms::InRealm; use dom_struct::dom_struct; -use std::rc::Rc; #[dom_struct] pub struct Navigator { @@ -159,9 +155,7 @@ impl NavigatorMethods for Navigator { .gamepads .or_init(|| GamepadList::new(&self.global(), &[])); - let vr_gamepads = self.Xr().get_gamepads(); - root.add_if_not_exists(&vr_gamepads); - // TODO: Add not VR related gamepads + // TODO: Add gamepads root } // https://w3c.github.io/permissions/#navigator-and-workernavigator-extension @@ -170,17 +164,6 @@ impl NavigatorMethods for Navigator { .or_init(|| Permissions::new(&self.global())) } - // https://w3c.github.io/webvr/spec/1.1/#navigator-getvrdisplays-attribute - fn GetVRDisplays(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(&self.global(), comp); - let displays = self.Xr().get_displays(); - match displays { - Ok(displays) => promise.resolve_native(&displays), - Err(_) => promise.reject_error(Error::Security), - } - promise - } - /// https://immersive-web.github.io/webxr/#dom-navigator-xr fn Xr(&self) -> DomRoot<XRSystem> { self.xr diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs deleted file mode 100644 index 2d59aa6a844..00000000000 --- a/components/script/dom/vrdisplay.rs +++ /dev/null @@ -1,840 +0,0 @@ -/* 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::dom::bindings::callback::ExceptionHandling; -use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods; -use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods; -use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods; -use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VREye; -use crate::dom::bindings::codegen::Bindings::VRLayerBinding::VRLayer; -use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; -use crate::dom::bindings::codegen::Bindings::WindowBinding::FrameRequestCallback; -use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; -use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateInit; -use crate::dom::bindings::error::Error; -use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::num::Finite; -use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; -use crate::dom::bindings::root::{DomRoot, MutDom, MutNullableDom}; -use crate::dom::bindings::str::DOMString; -use crate::dom::event::Event; -use crate::dom::eventtarget::EventTarget; -use crate::dom::promise::Promise; -use crate::dom::vrdisplaycapabilities::VRDisplayCapabilities; -use crate::dom::vrdisplayevent::VRDisplayEvent; -use crate::dom::vreyeparameters::VREyeParameters; -use crate::dom::vrframedata::VRFrameData; -use crate::dom::vrpose::VRPose; -use crate::dom::vrstageparameters::VRStageParameters; -use crate::dom::webglrenderingcontext::{WebGLMessageSender, WebGLRenderingContext}; -use crate::dom::window::Window; -use crate::realms::InRealm; -use crate::script_runtime::CommonScriptMsg; -use crate::script_runtime::ScriptThreadEventCategory::WebVREvent; -use crate::task_source::{TaskSource, TaskSourceName}; -use canvas_traits::webgl::{webgl_channel, WebGLReceiver, WebVRCommand}; -use crossbeam_channel::{unbounded, Sender}; -use dom_struct::dom_struct; -use ipc_channel::ipc::IpcSender; -use msg::constellation_msg::PipelineId; -use profile_traits::ipc; -use std::cell::Cell; -use std::mem; -use std::rc::Rc; -use std::thread; -use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVRFrameData, WebVRPoseInformation}; -use webvr_traits::{WebVRLayer, WebVRMsg}; - -#[dom_struct] -pub struct VRDisplay { - eventtarget: EventTarget, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - display: DomRefCell<WebVRDisplayData>, - depth_near: Cell<f64>, - depth_far: Cell<f64>, - presenting: Cell<bool>, - has_raf_thread: Cell<bool>, - left_eye_params: MutDom<VREyeParameters>, - right_eye_params: MutDom<VREyeParameters>, - capabilities: MutDom<VRDisplayCapabilities>, - stage_params: MutNullableDom<VRStageParameters>, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - frame_data: DomRefCell<WebVRFrameData>, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - layer: DomRefCell<WebVRLayer>, - layer_ctx: MutNullableDom<WebGLRenderingContext>, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - next_raf_id: Cell<u32>, - /// List of request animation frame callbacks - #[ignore_malloc_size_of = "closures are hard"] - raf_callback_list: DomRefCell<Vec<(u32, Option<Rc<FrameRequestCallback>>)>>, - /// When there isn't any layer_ctx the RAF thread needs to be "woken up" - raf_wakeup_sender: DomRefCell<Option<Sender<()>>>, - #[ignore_malloc_size_of = "Rc is hard"] - pending_renderstate_updates: DomRefCell<Vec<(XRRenderStateInit, Rc<Promise>)>>, - // Compositor VRFrameData synchonization - frame_data_status: Cell<VRFrameDataStatus>, - #[ignore_malloc_size_of = "closures are hard"] - frame_data_receiver: DomRefCell<Option<WebGLReceiver<Result<WebVRPoseInformation, ()>>>>, - running_display_raf: Cell<bool>, - paused: Cell<bool>, - stopped_on_pause: Cell<bool>, - #[ignore_malloc_size_of = "channels are hard"] - webvr_thread: IpcSender<WebVRMsg>, - pipeline: PipelineId, -} - -unsafe_no_jsmanaged_fields!(WebVRDisplayData); -unsafe_no_jsmanaged_fields!(WebVRFrameData); -unsafe_no_jsmanaged_fields!(WebVRLayer); -unsafe_no_jsmanaged_fields!(VRFrameDataStatus); - -#[derive(Clone, Copy, Eq, MallocSizeOf, PartialEq)] -enum VRFrameDataStatus { - Waiting, - Synced, - Exit, -} - -#[derive(Clone, MallocSizeOf)] -struct VRRAFUpdate { - depth_near: f64, - depth_far: f64, - /// WebGL API sender - api_sender: Option<WebGLMessageSender>, - /// Number uniquely identifying the WebGL context - /// so that we may setup/tear down VR compositors as things change - context_id: usize, -} - -type VRRAFUpdateSender = Sender<Result<VRRAFUpdate, ()>>; - -impl VRDisplay { - fn new_inherited(global: &Window, display: WebVRDisplayData) -> VRDisplay { - let stage = match display.stage_parameters { - Some(ref params) => Some(VRStageParameters::new(params.clone(), &global)), - None => None, - }; - - VRDisplay { - eventtarget: EventTarget::new_inherited(), - display: DomRefCell::new(display.clone()), - depth_near: Cell::new(0.01), - depth_far: Cell::new(10000.0), - presenting: Cell::new(false), - has_raf_thread: Cell::new(false), - left_eye_params: MutDom::new(&*VREyeParameters::new( - display.left_eye_parameters.clone(), - &global, - )), - right_eye_params: MutDom::new(&*VREyeParameters::new( - display.right_eye_parameters.clone(), - &global, - )), - capabilities: MutDom::new(&*VRDisplayCapabilities::new( - display.capabilities.clone(), - &global, - )), - stage_params: MutNullableDom::new(stage.as_deref()), - frame_data: DomRefCell::new(Default::default()), - layer: DomRefCell::new(Default::default()), - layer_ctx: MutNullableDom::default(), - next_raf_id: Cell::new(1), - raf_callback_list: DomRefCell::new(vec![]), - raf_wakeup_sender: DomRefCell::new(None), - pending_renderstate_updates: DomRefCell::new(vec![]), - frame_data_status: Cell::new(VRFrameDataStatus::Waiting), - frame_data_receiver: DomRefCell::new(None), - running_display_raf: Cell::new(false), - // Some VR implementations (e.g. Daydream) can be paused in some life cycle situations - // such as showing and hiding the controller pairing screen. - paused: Cell::new(false), - // This flag is set when the Display was presenting when it received a VR Pause event. - // When the VR Resume event is received and the flag is set, VR presentation automatically restarts. - stopped_on_pause: Cell::new(false), - webvr_thread: global.webvr_thread().expect("webvr is disabled"), - pipeline: global.pipeline_id(), - } - } - - pub fn new(global: &Window, display: WebVRDisplayData) -> DomRoot<VRDisplay> { - reflect_dom_object(Box::new(VRDisplay::new_inherited(&global, display)), global) - } -} - -impl Drop for VRDisplay { - fn drop(&mut self) { - if self.presenting.get() { - self.force_stop_present(); - } - } -} - -impl VRDisplayMethods for VRDisplay { - // https://w3c.github.io/webvr/#dom-vrdisplay-isconnected - fn IsConnected(&self) -> bool { - self.display.borrow().connected - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-ispresenting - fn IsPresenting(&self) -> bool { - self.presenting.get() - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-capabilities - fn Capabilities(&self) -> DomRoot<VRDisplayCapabilities> { - DomRoot::from_ref(&*self.capabilities.get()) - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-stageparameters - fn GetStageParameters(&self) -> Option<DomRoot<VRStageParameters>> { - self.stage_params.get().map(|s| DomRoot::from_ref(&*s)) - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-geteyeparameters - fn GetEyeParameters(&self, eye: VREye) -> DomRoot<VREyeParameters> { - match eye { - VREye::Left => DomRoot::from_ref(&*self.left_eye_params.get()), - VREye::Right => DomRoot::from_ref(&*self.right_eye_params.get()), - } - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-displayid - fn DisplayId(&self) -> u32 { - self.display.borrow().display_id - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-displayname - fn DisplayName(&self) -> DOMString { - DOMString::from(self.display.borrow().display_name.clone()) - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-getframedata-framedata-framedata - fn GetFrameData(&self, frame_data: &VRFrameData) -> bool { - // If presenting we use a synced data with compositor for the whole frame. - // Frame data is only synced with compositor when GetFrameData is called from - // inside the VRDisplay.requestAnimationFrame. This is checked using the running_display_raf property. - // This check avoids data race conditions when calling GetFrameData from outside of the - // VRDisplay.requestAnimationFrame callbacks and fixes a possible deadlock during the interval - // when the requestAnimationFrame is moved from window to VRDisplay. - if self.presenting.get() && self.running_display_raf.get() { - if self.frame_data_status.get() == VRFrameDataStatus::Waiting { - self.sync_frame_data(); - } - frame_data.update(&self.frame_data.borrow()); - return true; - } - - // If not presenting we fetch inmediante VRFrameData - let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); - self.webvr_thread - .send(WebVRMsg::GetFrameData( - self.global().pipeline_id(), - self.DisplayId(), - self.depth_near.get(), - self.depth_far.get(), - sender, - )) - .unwrap(); - return match receiver.recv().unwrap() { - Ok(data) => { - frame_data.update(&data); - true - }, - Err(e) => { - error!("WebVR::GetFrameData: {:?}", e); - false - }, - }; - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-getpose - fn GetPose(&self) -> DomRoot<VRPose> { - VRPose::new(&self.global(), &self.frame_data.borrow().pose) - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-resetpose - fn ResetPose(&self) { - let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); - self.webvr_thread - .send(WebVRMsg::ResetPose( - self.global().pipeline_id(), - self.DisplayId(), - sender, - )) - .unwrap(); - if let Ok(data) = receiver.recv().unwrap() { - // Some VRDisplay data might change after calling ResetPose() - *self.display.borrow_mut() = data; - } - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-depthnear - fn DepthNear(&self) -> Finite<f64> { - Finite::wrap(self.depth_near.get()) - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-depthnear - fn SetDepthNear(&self, value: Finite<f64>) { - self.depth_near.set(*value); - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-depthfar - fn DepthFar(&self) -> Finite<f64> { - Finite::wrap(self.depth_far.get()) - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-depthfar - fn SetDepthFar(&self, value: Finite<f64>) { - self.depth_far.set(*value); - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-requestanimationframe - fn RequestAnimationFrame(&self, callback: Rc<FrameRequestCallback>) -> u32 { - if self.presenting.get() { - let raf_id = self.next_raf_id.get(); - self.next_raf_id.set(raf_id + 1); - self.raf_callback_list - .borrow_mut() - .push((raf_id, Some(callback))); - raf_id - } else { - // WebVR spec: When a VRDisplay is not presenting it should - // fallback to window.requestAnimationFrame. - self.global().as_window().RequestAnimationFrame(callback) - } - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-cancelanimationframe - fn CancelAnimationFrame(&self, handle: u32) { - if self.presenting.get() { - let mut list = self.raf_callback_list.borrow_mut(); - if let Some(pair) = list.iter_mut().find(|pair| pair.0 == handle) { - pair.1 = None; - } - } else { - // WebVR spec: When a VRDisplay is not presenting it should - // fallback to window.cancelAnimationFrame. - self.global().as_window().CancelAnimationFrame(handle); - } - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-requestpresent - fn RequestPresent(&self, layers: Vec<VRLayer>, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(&self.global(), comp); - // TODO: WebVR spec: this method must be called in response to a user gesture - - // WebVR spec: If canPresent is false the promise MUST be rejected - if !self.display.borrow().capabilities.can_present { - let msg = "VRDisplay canPresent is false".to_string(); - promise.reject_native(&msg); - return promise; - } - - // Current WebVRSpec only allows 1 VRLayer if the VRDevice can present. - // Future revisions of this spec may allow multiple layers to enable more complex rendering effects - // such as compositing WebGL and DOM elements together. - // That functionality is not allowed by this revision of the spec. - if layers.len() != 1 { - let msg = "The number of layers must be 1".to_string(); - promise.reject_native(&msg); - return promise; - } - - // Parse and validate received VRLayer - let layer = validate_layer(&layers[0]); - - let layer_bounds; - let layer_ctx; - - match layer { - Ok((bounds, ctx)) => { - layer_bounds = bounds; - layer_ctx = ctx; - }, - Err(msg) => { - let msg = msg.to_string(); - promise.reject_native(&msg); - return promise; - }, - }; - - // WebVR spec: Repeat calls while already presenting will update the VRLayers being displayed. - if self.presenting.get() { - *self.layer.borrow_mut() = layer_bounds; - self.layer_ctx.set(Some(&layer_ctx)); - promise.resolve_native(&()); - return promise; - } - - let xr = self.global().as_window().Navigator().Xr(); - - if xr.pending_or_active_session() { - // WebVR spec doesn't mandate anything here, however - // the WebXR spec expects there to be only one immersive XR session at a time, - // and WebVR is deprecated - promise.reject_error(Error::InvalidState); - return promise; - } - - self.request_present(layer_bounds, Some(&layer_ctx), Some(promise.clone()), |p| { - p.resolve_native(&()) - }); - promise - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-exitpresent - fn ExitPresent(&self, comp: InRealm) -> Rc<Promise> { - let promise = Promise::new_in_current_realm(&self.global(), comp); - - // WebVR spec: If the VRDisplay is not presenting the promise MUST be rejected. - if !self.presenting.get() { - let msg = "VRDisplay is not presenting".to_string(); - promise.reject_native(&msg); - return promise; - } - - // Exit present - let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); - self.webvr_thread - .send(WebVRMsg::ExitPresent( - self.global().pipeline_id(), - self.display.borrow().display_id, - Some(sender), - )) - .unwrap(); - match receiver.recv().unwrap() { - Ok(()) => { - self.stop_present(); - promise.resolve_native(&()); - }, - Err(e) => { - promise.reject_native(&e); - }, - } - - promise - } - - // https://w3c.github.io/webvr/#dom-vrdisplay-submitframe - fn SubmitFrame(&self) { - if !self.presenting.get() { - warn!("VRDisplay not presenting"); - return; - } - - let display_id = self.display.borrow().display_id; - let layer = self.layer.borrow(); - let msg = WebVRCommand::SubmitFrame(display_id, layer.left_bounds, layer.right_bounds); - self.layer_ctx - .get() - .expect("SubmitFrame can only be called when there is a webgl layer") - .send_vr_command(msg); - } - - // https://w3c.github.io/webvr/spec/1.1/#dom-vrdisplay-getlayers - fn GetLayers(&self) -> Vec<VRLayer> { - // WebVR spec: MUST return an empty array if the VRDisplay is not currently presenting - if !self.presenting.get() { - return Vec::new(); - } - - let layer = self.layer.borrow(); - - vec![VRLayer { - leftBounds: Some(bounds_to_vec(&layer.left_bounds)), - rightBounds: Some(bounds_to_vec(&layer.right_bounds)), - source: self.layer_ctx.get().map(|ctx| ctx.Canvas()), - }] - } -} - -impl VRDisplay { - pub fn update_display(&self, display: &WebVRDisplayData) { - *self.display.borrow_mut() = display.clone(); - if let Some(ref stage) = display.stage_parameters { - if self.stage_params.get().is_none() { - let params = Some(VRStageParameters::new( - stage.clone(), - &self.global().as_window(), - )); - self.stage_params.set(params.as_deref()); - } else { - self.stage_params.get().unwrap().update(&stage); - } - } else { - self.stage_params.set(None); - } - } - - pub fn request_present<F>( - &self, - layer_bounds: WebVRLayer, - ctx: Option<&WebGLRenderingContext>, - promise: Option<Rc<Promise>>, - resolve: F, - ) where - F: FnOnce(Rc<Promise>) + Send + 'static, - { - // Request Present - let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); - self.webvr_thread - .send(WebVRMsg::RequestPresent( - self.global().pipeline_id(), - self.display.borrow().display_id, - sender, - )) - .unwrap(); - let promise = promise.map(TrustedPromise::new); - let this = Trusted::new(self); - let ctx = ctx.map(|c| Trusted::new(c)); - let global = self.global(); - let window = global.as_window(); - let (task_source, canceller) = window - .task_manager() - .dom_manipulation_task_source_with_canceller(); - thread::spawn(move || { - let recv = receiver.recv().unwrap(); - let _ = task_source.queue_with_canceller( - task!(vr_presenting: move || { - let this = this.root(); - let promise = promise.map(|p| p.root()); - let ctx = ctx.map(|c| c.root()); - match recv { - Ok(()) => { - *this.layer.borrow_mut() = layer_bounds; - this.layer_ctx.set(ctx.as_deref()); - this.init_present(); - promise.map(resolve); - }, - Err(e) => { - promise.map(|p| p.reject_native(&e)); - }, - } - }), - &canceller, - ); - }); - } - - pub fn handle_webvr_event(&self, event: &WebVRDisplayEvent) { - match *event { - WebVRDisplayEvent::Connect(ref display) => { - self.update_display(&display); - }, - WebVRDisplayEvent::Disconnect(_id) => { - self.display.borrow_mut().connected = false; - }, - WebVRDisplayEvent::Activate(ref display, _) | - WebVRDisplayEvent::Deactivate(ref display, _) | - WebVRDisplayEvent::Blur(ref display) | - WebVRDisplayEvent::Focus(ref display) => { - self.update_display(&display); - self.notify_event(&event); - }, - WebVRDisplayEvent::PresentChange(ref display, presenting) => { - self.update_display(&display); - self.presenting.set(presenting); - self.notify_event(&event); - }, - WebVRDisplayEvent::Change(ref display) => { - // Change event doesn't exist in WebVR spec. - // So we update display data but don't notify JS. - self.update_display(&display); - }, - WebVRDisplayEvent::Pause(_) => { - if self.paused.get() { - return; - } - self.paused.set(true); - if self.presenting.get() { - self.stop_present(); - self.stopped_on_pause.set(true); - } - }, - WebVRDisplayEvent::Resume(_) => { - self.paused.set(false); - if self.stopped_on_pause.get() { - self.stopped_on_pause.set(false); - self.init_present(); - } - }, - WebVRDisplayEvent::Exit(_) => { - self.stopped_on_pause.set(false); - if self.presenting.get() { - self.stop_present(); - } - }, - }; - } - - fn notify_event(&self, event: &WebVRDisplayEvent) { - let root = DomRoot::from_ref(&*self); - let event = VRDisplayEvent::new_from_webvr(&self.global(), &root, &event); - event - .upcast::<Event>() - .fire(self.global().upcast::<EventTarget>()); - } - - fn api_sender(&self) -> Option<WebGLMessageSender> { - self.layer_ctx.get().map(|c| c.webgl_sender()) - } - - fn context_id(&self) -> usize { - self.layer_ctx - .get() - .map(|c| &*c as *const WebGLRenderingContext as usize) - .unwrap_or(0) - } - - fn vr_raf_update(&self) -> VRRAFUpdate { - VRRAFUpdate { - depth_near: self.depth_near.get(), - depth_far: self.depth_far.get(), - api_sender: self.api_sender(), - context_id: self.context_id(), - } - } - - fn init_present(&self) { - self.presenting.set(true); - if self.has_raf_thread.get() { - return; - } - self.has_raf_thread.set(true); - let (sync_sender, sync_receiver) = webgl_channel().unwrap(); - *self.frame_data_receiver.borrow_mut() = Some(sync_receiver); - - let display_id = self.display.borrow().display_id; - let mut api_sender = self.api_sender(); - let mut context_id = self.context_id(); - let js_sender = self.global().script_chan(); - let address = Trusted::new(&*self); - let mut near = self.depth_near.get(); - let mut far = self.depth_far.get(); - let pipeline_id = self.global().pipeline_id(); - - let (raf_sender, raf_receiver) = unbounded(); - let (wakeup_sender, wakeup_receiver) = unbounded(); - *self.raf_wakeup_sender.borrow_mut() = Some(wakeup_sender); - - // The render loop at native headset frame rate is implemented using a dedicated thread. - // Every loop iteration syncs pose data with the HMD, submits the pixels to the display and waits for Vsync. - // Both the requestAnimationFrame call of a VRDisplay in the JavaScript thread and the VRSyncPoses call - // in the Webrender thread are executed in parallel. This allows to get some JavaScript code executed ahead. - // while the render thread is syncing the VRFrameData to be used for the current frame. - // This thread runs until the user calls ExitPresent, the tab is closed or some unexpected error happened. - thread::Builder::new() - .name("WebVR_RAF".into()) - .spawn(move || { - // Initialize compositor - if let Some(ref api_sender) = api_sender { - api_sender - .send_vr(WebVRCommand::Create(display_id)) - .unwrap(); - } - loop { - if let Some(ref api_sender) = api_sender { - // Run RAF callbacks on JavaScript thread - let this = address.clone(); - let sender = raf_sender.clone(); - let task = Box::new(task!(handle_vrdisplay_raf: move || { - this.root().handle_raf(&sender); - })); - // NOTE: WebVR spec doesn't specify what task source we should use. Is - // dom-manipulation a good choice long term? - js_sender - .send(CommonScriptMsg::Task( - WebVREvent, - task, - Some(pipeline_id), - TaskSourceName::DOMManipulation, - )) - .unwrap(); - - // Run Sync Poses in parallell on Render thread - let msg = WebVRCommand::SyncPoses( - display_id, - near, - far, - false, - sync_sender.clone(), - ); - api_sender.send_vr(msg).unwrap(); - } else { - let _ = wakeup_receiver.recv(); - let sender = raf_sender.clone(); - let this = address.clone(); - let task = Box::new(task!(flush_renderstate_queue: move || { - let this = this.root(); - sender.send(Ok(this.vr_raf_update())).unwrap(); - })); - js_sender - .send(CommonScriptMsg::Task( - WebVREvent, - task, - Some(pipeline_id), - TaskSourceName::DOMManipulation, - )) - .unwrap(); - } - - // Wait until both SyncPoses & RAF ends - if let Ok(update) = raf_receiver.recv().unwrap() { - near = update.depth_near; - far = update.depth_far; - if update.context_id != context_id { - if let Some(ref api_sender) = update.api_sender { - api_sender - .send_vr(WebVRCommand::Create(display_id)) - .unwrap(); - } - if let Some(ref api_sender) = api_sender { - // shut down old vr compositor - api_sender - .send_vr(WebVRCommand::Release(display_id)) - .unwrap(); - } - context_id = update.context_id; - } - - api_sender = update.api_sender; - } else { - // Stop thread - // ExitPresent called or some error happened - return; - } - } - }) - .expect("Thread spawning failed"); - } - - fn stop_present(&self) { - self.presenting.set(false); - *self.frame_data_receiver.borrow_mut() = None; - self.has_raf_thread.set(false); - if let Some(api_sender) = self.api_sender() { - let display_id = self.display.borrow().display_id; - api_sender - .send_vr(WebVRCommand::Release(display_id)) - .unwrap(); - } - } - - // Only called when the JSContext is destroyed while presenting. - // In this case we don't want to wait for WebVR Thread response. - fn force_stop_present(&self) { - self.webvr_thread - .send(WebVRMsg::ExitPresent( - self.global().pipeline_id(), - self.display.borrow().display_id, - None, - )) - .unwrap(); - self.stop_present(); - } - - fn sync_frame_data(&self) { - let status = if let Some(receiver) = self.frame_data_receiver.borrow().as_ref() { - match receiver.recv().unwrap() { - Ok(pose) => { - *self.frame_data.borrow_mut() = pose.frame.block(); - VRFrameDataStatus::Synced - }, - Err(()) => VRFrameDataStatus::Exit, - } - } else { - VRFrameDataStatus::Exit - }; - - self.frame_data_status.set(status); - } - - fn handle_raf(&self, end_sender: &VRRAFUpdateSender) { - self.frame_data_status.set(VRFrameDataStatus::Waiting); - - let now = self.global().as_window().Performance().Now(); - - self.running_display_raf.set(true); - let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]); - // Call registered VRDisplay.requestAnimationFrame callbacks. - for (_, callback) in callbacks.drain(..) { - if let Some(callback) = callback { - let _ = callback.Call__(Finite::wrap(*now), ExceptionHandling::Report); - } - } - - self.running_display_raf.set(false); - if self.frame_data_status.get() == VRFrameDataStatus::Waiting { - // User didn't call getFrameData while presenting. - // We automatically reads the pending VRFrameData to avoid overflowing the IPC-Channel buffers. - // Show a warning as the WebVR Spec recommends. - warn!("WebVR: You should call GetFrameData while presenting"); - self.sync_frame_data(); - } - - match self.frame_data_status.get() { - VRFrameDataStatus::Synced => { - // Sync succeeded. Notify RAF thread. - end_sender.send(Ok(self.vr_raf_update())).unwrap(); - }, - VRFrameDataStatus::Exit | VRFrameDataStatus::Waiting => { - // ExitPresent called or some error ocurred. - // Notify VRDisplay RAF thread to stop. - end_sender.send(Err(())).unwrap(); - }, - } - } -} - -// WebVR Spec: If the number of values in the leftBounds/rightBounds arrays -// is not 0 or 4 for any of the passed layers the promise is rejected -fn parse_bounds(src: &Option<Vec<Finite<f32>>>, dst: &mut [f32; 4]) -> Result<(), &'static str> { - match *src { - Some(ref values) => { - if values.len() == 0 { - return Ok(()); - } - if values.len() != 4 { - return Err( - "The number of values in the leftBounds/rightBounds arrays must be 0 or 4", - ); - } - for i in 0..4 { - dst[i] = *values[i]; - } - Ok(()) - }, - None => Ok(()), - } -} - -fn validate_layer( - layer: &VRLayer, -) -> Result<(WebVRLayer, DomRoot<WebGLRenderingContext>), &'static str> { - let ctx = layer - .source - .as_ref() - .map(|ref s| s.get_base_webgl_context()) - .unwrap_or(None); - if let Some(ctx) = ctx { - let mut data = WebVRLayer::default(); - parse_bounds(&layer.leftBounds, &mut data.left_bounds)?; - parse_bounds(&layer.rightBounds, &mut data.right_bounds)?; - Ok((data, ctx)) - } else { - Err("VRLayer source must be a WebGL Context") - } -} - -fn bounds_to_vec(src: &[f32; 4]) -> Vec<Finite<f32>> { - vec![ - Finite::wrap(src[0]), - Finite::wrap(src[1]), - Finite::wrap(src[2]), - Finite::wrap(src[3]), - ] -} diff --git a/components/script/dom/vrdisplaycapabilities.rs b/components/script/dom/vrdisplaycapabilities.rs deleted file mode 100644 index d4908b88eb1..00000000000 --- a/components/script/dom/vrdisplaycapabilities.rs +++ /dev/null @@ -1,70 +0,0 @@ -/* 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::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::VRDisplayCapabilitiesBinding::VRDisplayCapabilitiesMethods; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; -use crate::dom::window::Window; -use dom_struct::dom_struct; -use webvr_traits::WebVRDisplayCapabilities; - -#[dom_struct] -pub struct VRDisplayCapabilities { - reflector_: Reflector, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - capabilities: DomRefCell<WebVRDisplayCapabilities>, -} - -unsafe_no_jsmanaged_fields!(WebVRDisplayCapabilities); - -impl VRDisplayCapabilities { - fn new_inherited(capabilities: WebVRDisplayCapabilities) -> VRDisplayCapabilities { - VRDisplayCapabilities { - reflector_: Reflector::new(), - capabilities: DomRefCell::new(capabilities), - } - } - - pub fn new( - capabilities: WebVRDisplayCapabilities, - global: &Window, - ) -> DomRoot<VRDisplayCapabilities> { - reflect_dom_object( - Box::new(VRDisplayCapabilities::new_inherited(capabilities)), - global, - ) - } -} - -impl VRDisplayCapabilitiesMethods for VRDisplayCapabilities { - // https://w3c.github.io/webvr/#dom-vrdisplaycapabilities-hasposition - fn HasPosition(&self) -> bool { - self.capabilities.borrow().has_position - } - - // https://w3c.github.io/webvr/#dom-vrdisplaycapabilities-hasorientation - fn HasOrientation(&self) -> bool { - self.capabilities.borrow().has_orientation - } - - // https://w3c.github.io/webvr/#dom-vrdisplaycapabilities-hasexternaldisplay - fn HasExternalDisplay(&self) -> bool { - self.capabilities.borrow().has_external_display - } - - // https://w3c.github.io/webvr/#dom-vrdisplaycapabilities-canpresent - fn CanPresent(&self) -> bool { - self.capabilities.borrow().can_present - } - - // https://w3c.github.io/webvr/#dom-vrdisplaycapabilities-maxlayers - fn MaxLayers(&self) -> u32 { - if self.CanPresent() { - 1 - } else { - 0 - } - } -} diff --git a/components/script/dom/vrdisplayevent.rs b/components/script/dom/vrdisplayevent.rs deleted file mode 100644 index 00a7ab4012e..00000000000 --- a/components/script/dom/vrdisplayevent.rs +++ /dev/null @@ -1,125 +0,0 @@ -/* 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::dom::bindings::codegen::Bindings::EventBinding::EventBinding::EventMethods; -use crate::dom::bindings::codegen::Bindings::VRDisplayEventBinding; -use crate::dom::bindings::codegen::Bindings::VRDisplayEventBinding::VRDisplayEventMethods; -use crate::dom::bindings::codegen::Bindings::VRDisplayEventBinding::VRDisplayEventReason; -use crate::dom::bindings::error::Fallible; -use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; -use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::bindings::str::DOMString; -use crate::dom::event::Event; -use crate::dom::globalscope::GlobalScope; -use crate::dom::vrdisplay::VRDisplay; -use crate::dom::window::Window; -use dom_struct::dom_struct; -use servo_atoms::Atom; -use webvr_traits::{WebVRDisplayEvent, WebVRDisplayEventReason}; - -#[dom_struct] -pub struct VRDisplayEvent { - event: Event, - display: Dom<VRDisplay>, - reason: Option<VRDisplayEventReason>, -} - -impl VRDisplayEvent { - fn new_inherited(display: &VRDisplay, reason: Option<VRDisplayEventReason>) -> VRDisplayEvent { - VRDisplayEvent { - event: Event::new_inherited(), - display: Dom::from_ref(display), - reason: reason.clone(), - } - } - - pub fn new( - global: &GlobalScope, - type_: Atom, - bubbles: bool, - cancelable: bool, - display: &VRDisplay, - reason: Option<VRDisplayEventReason>, - ) -> DomRoot<VRDisplayEvent> { - let ev = reflect_dom_object( - Box::new(VRDisplayEvent::new_inherited(&display, reason)), - global, - ); - { - let event = ev.upcast::<Event>(); - event.init_event(type_, bubbles, cancelable); - } - ev - } - - pub fn new_from_webvr( - global: &GlobalScope, - display: &VRDisplay, - event: &WebVRDisplayEvent, - ) -> DomRoot<VRDisplayEvent> { - let (name, reason) = match *event { - WebVRDisplayEvent::Connect(_) => ("vrdisplayconnect", None), - WebVRDisplayEvent::Disconnect(_) => ("vrdisplaydisconnect", None), - WebVRDisplayEvent::Activate(_, reason) => ("vrdisplayactivate", Some(reason)), - WebVRDisplayEvent::Deactivate(_, reason) => ("vrdisplaydeactivate", Some(reason)), - WebVRDisplayEvent::Blur(_) => ("vrdisplayblur", None), - WebVRDisplayEvent::Focus(_) => ("vrdisplayfocus", None), - WebVRDisplayEvent::PresentChange(_, _) => ("vrdisplaypresentchange", None), - WebVRDisplayEvent::Change(_) | - WebVRDisplayEvent::Pause(_) | - WebVRDisplayEvent::Resume(_) | - WebVRDisplayEvent::Exit(_) => panic!("{:?} event not available in WebVR", event), - }; - - // map to JS enum values - let reason = reason.map(|r| match r { - WebVRDisplayEventReason::Navigation => VRDisplayEventReason::Navigation, - WebVRDisplayEventReason::Mounted => VRDisplayEventReason::Mounted, - WebVRDisplayEventReason::Unmounted => VRDisplayEventReason::Unmounted, - }); - - VRDisplayEvent::new( - &global, - Atom::from(DOMString::from(name)), - false, - false, - &display, - reason, - ) - } - - #[allow(non_snake_case)] - pub fn Constructor( - window: &Window, - type_: DOMString, - init: &VRDisplayEventBinding::VRDisplayEventInit, - ) -> Fallible<DomRoot<VRDisplayEvent>> { - Ok(VRDisplayEvent::new( - &window.global(), - Atom::from(type_), - init.parent.bubbles, - init.parent.cancelable, - &init.display, - init.reason, - )) - } -} - -impl VRDisplayEventMethods for VRDisplayEvent { - // https://w3c.github.io/webvr/#dom-vrdisplayevent-display - fn Display(&self) -> DomRoot<VRDisplay> { - DomRoot::from_ref(&*self.display) - } - - // https://w3c.github.io/webvr/#enumdef-vrdisplayeventreason - fn GetReason(&self) -> Option<VRDisplayEventReason> { - self.reason - } - - // https://dom.spec.whatwg.org/#dom-event-istrusted - fn IsTrusted(&self) -> bool { - self.event.IsTrusted() - } -} diff --git a/components/script/dom/vreyeparameters.rs b/components/script/dom/vreyeparameters.rs deleted file mode 100644 index ae18fbb5416..00000000000 --- a/components/script/dom/vreyeparameters.rs +++ /dev/null @@ -1,87 +0,0 @@ -/* 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::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::VREyeParametersBinding::VREyeParametersMethods; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::vrfieldofview::VRFieldOfView; -use crate::dom::window::Window; -use crate::script_runtime::JSContext; -use dom_struct::dom_struct; -use js::jsapi::{Heap, JSObject}; -use js::typedarray::{CreateWith, Float32Array}; -use std::default::Default; -use std::ptr; -use std::ptr::NonNull; -use webvr_traits::WebVREyeParameters; - -#[dom_struct] -pub struct VREyeParameters { - reflector_: Reflector, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - parameters: DomRefCell<WebVREyeParameters>, - #[ignore_malloc_size_of = "mozjs"] - offset: Heap<*mut JSObject>, - fov: Dom<VRFieldOfView>, -} - -unsafe_no_jsmanaged_fields!(WebVREyeParameters); - -impl VREyeParameters { - fn new_inherited(parameters: WebVREyeParameters, fov: &VRFieldOfView) -> VREyeParameters { - VREyeParameters { - reflector_: Reflector::new(), - parameters: DomRefCell::new(parameters), - offset: Heap::default(), - fov: Dom::from_ref(&*fov), - } - } - - #[allow(unsafe_code)] - pub fn new(parameters: WebVREyeParameters, global: &Window) -> DomRoot<VREyeParameters> { - let fov = VRFieldOfView::new(&global, parameters.field_of_view.clone()); - - let cx = global.get_cx(); - rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - unsafe { - let _ = Float32Array::create( - *cx, - CreateWith::Slice(¶meters.offset), - array.handle_mut(), - ); - } - - let eye_parameters = reflect_dom_object( - Box::new(VREyeParameters::new_inherited(parameters, &fov)), - global, - ); - eye_parameters.offset.set(array.get()); - - eye_parameters - } -} - -impl VREyeParametersMethods for VREyeParameters { - #[allow(unsafe_code)] - // https://w3c.github.io/webvr/#dom-vreyeparameters-offset - fn Offset(&self, _cx: JSContext) -> NonNull<JSObject> { - unsafe { NonNull::new_unchecked(self.offset.get()) } - } - - // https://w3c.github.io/webvr/#dom-vreyeparameters-fieldofview - fn FieldOfView(&self) -> DomRoot<VRFieldOfView> { - DomRoot::from_ref(&*self.fov) - } - - // https://w3c.github.io/webvr/#dom-vreyeparameters-renderwidth - fn RenderWidth(&self) -> u32 { - self.parameters.borrow().render_width - } - - // https://w3c.github.io/webvr/#dom-vreyeparameters-renderheight - fn RenderHeight(&self) -> u32 { - self.parameters.borrow().render_height - } -} diff --git a/components/script/dom/vrfieldofview.rs b/components/script/dom/vrfieldofview.rs deleted file mode 100644 index 5a82c2aedf2..00000000000 --- a/components/script/dom/vrfieldofview.rs +++ /dev/null @@ -1,56 +0,0 @@ -/* 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::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::VRFieldOfViewBinding::VRFieldOfViewMethods; -use crate::dom::bindings::num::Finite; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; -use crate::dom::window::Window; -use dom_struct::dom_struct; -use webvr_traits::WebVRFieldOfView; - -#[dom_struct] -pub struct VRFieldOfView { - reflector_: Reflector, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - fov: DomRefCell<WebVRFieldOfView>, -} - -unsafe_no_jsmanaged_fields!(WebVRFieldOfView); - -impl VRFieldOfView { - fn new_inherited(fov: WebVRFieldOfView) -> VRFieldOfView { - VRFieldOfView { - reflector_: Reflector::new(), - fov: DomRefCell::new(fov), - } - } - - pub fn new(global: &Window, fov: WebVRFieldOfView) -> DomRoot<VRFieldOfView> { - reflect_dom_object(Box::new(VRFieldOfView::new_inherited(fov)), global) - } -} - -impl VRFieldOfViewMethods for VRFieldOfView { - // https://w3c.github.io/webvr/#interface-interface-vrfieldofview - fn UpDegrees(&self) -> Finite<f64> { - Finite::wrap(self.fov.borrow().up_degrees) - } - - // https://w3c.github.io/webvr/#interface-interface-vrfieldofview - fn RightDegrees(&self) -> Finite<f64> { - Finite::wrap(self.fov.borrow().right_degrees) - } - - // https://w3c.github.io/webvr/#interface-interface-vrfieldofview - fn DownDegrees(&self) -> Finite<f64> { - Finite::wrap(self.fov.borrow().down_degrees) - } - - // https://w3c.github.io/webvr/#interface-interface-vrfieldofview - fn LeftDegrees(&self) -> Finite<f64> { - Finite::wrap(self.fov.borrow().left_degrees) - } -} diff --git a/components/script/dom/vrframedata.rs b/components/script/dom/vrframedata.rs deleted file mode 100644 index bd81d0a41bf..00000000000 --- a/components/script/dom/vrframedata.rs +++ /dev/null @@ -1,150 +0,0 @@ -/* 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::dom::bindings::codegen::Bindings::PerformanceBinding::DOMHighResTimeStamp; -use crate::dom::bindings::codegen::Bindings::VRFrameDataBinding::VRFrameDataMethods; -use crate::dom::bindings::error::Fallible; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; -use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::globalscope::GlobalScope; -use crate::dom::performance::reduce_timing_resolution; -use crate::dom::vrpose::VRPose; -use crate::dom::window::Window; -use crate::script_runtime::JSContext; -use dom_struct::dom_struct; -use js::jsapi::{Heap, JSObject}; -use js::typedarray::{CreateWith, Float32Array}; -use std::cell::Cell; -use std::ptr; -use std::ptr::NonNull; -use webvr_traits::WebVRFrameData; - -#[dom_struct] -pub struct VRFrameData { - reflector_: Reflector, - #[ignore_malloc_size_of = "mozjs"] - left_proj: Heap<*mut JSObject>, - #[ignore_malloc_size_of = "mozjs"] - left_view: Heap<*mut JSObject>, - #[ignore_malloc_size_of = "mozjs"] - right_proj: Heap<*mut JSObject>, - #[ignore_malloc_size_of = "mozjs"] - right_view: Heap<*mut JSObject>, - pose: Dom<VRPose>, - timestamp: Cell<f64>, - first_timestamp: Cell<f64>, -} - -impl VRFrameData { - fn new_inherited(pose: &VRPose) -> VRFrameData { - VRFrameData { - reflector_: Reflector::new(), - left_proj: Heap::default(), - left_view: Heap::default(), - right_proj: Heap::default(), - right_view: Heap::default(), - pose: Dom::from_ref(&*pose), - timestamp: Cell::new(0.0), - first_timestamp: Cell::new(0.0), - } - } - - #[allow(unsafe_code)] - fn new(global: &GlobalScope) -> DomRoot<VRFrameData> { - let matrix = [ - 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0f32, - ]; - let pose = VRPose::new(&global, &Default::default()); - - let root = reflect_dom_object(Box::new(VRFrameData::new_inherited(&pose)), global); - let cx = global.get_cx(); - create_typed_array(cx, &matrix, &root.left_proj); - create_typed_array(cx, &matrix, &root.left_view); - create_typed_array(cx, &matrix, &root.right_proj); - create_typed_array(cx, &matrix, &root.right_view); - - root - } - - #[allow(non_snake_case)] - pub fn Constructor(window: &Window) -> Fallible<DomRoot<VRFrameData>> { - Ok(VRFrameData::new(&window.global())) - } -} - -/// FIXME(#22526) this should be in a better place -#[allow(unsafe_code)] -pub fn create_typed_array(cx: JSContext, src: &[f32], dst: &Heap<*mut JSObject>) { - rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - unsafe { - let _ = Float32Array::create(*cx, CreateWith::Slice(src), array.handle_mut()); - } - (*dst).set(array.get()); -} - -impl VRFrameData { - #[allow(unsafe_code)] - pub fn update(&self, data: &WebVRFrameData) { - unsafe { - let cx = self.global().get_cx(); - typedarray!(in(*cx) let left_proj_array: Float32Array = self.left_proj.get()); - if let Ok(mut array) = left_proj_array { - array.update(&data.left_projection_matrix); - } - typedarray!(in(*cx) let left_view_array: Float32Array = self.left_view.get()); - if let Ok(mut array) = left_view_array { - array.update(&data.left_view_matrix); - } - typedarray!(in(*cx) let right_proj_array: Float32Array = self.right_proj.get()); - if let Ok(mut array) = right_proj_array { - array.update(&data.right_projection_matrix); - } - typedarray!(in(*cx) let right_view_array: Float32Array = self.right_view.get()); - if let Ok(mut array) = right_view_array { - array.update(&data.right_view_matrix); - } - self.pose.update(&data.pose); - self.timestamp.set(data.timestamp); - if self.first_timestamp.get() == 0.0 { - self.first_timestamp.set(data.timestamp); - } - } - } -} - -impl VRFrameDataMethods for VRFrameData { - // https://w3c.github.io/webvr/#dom-vrframedata-timestamp - fn Timestamp(&self) -> DOMHighResTimeStamp { - reduce_timing_resolution(self.timestamp.get() - self.first_timestamp.get()) - } - - #[allow(unsafe_code)] - // https://w3c.github.io/webvr/#dom-vrframedata-leftprojectionmatrix - fn LeftProjectionMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { - unsafe { NonNull::new_unchecked(self.left_proj.get()) } - } - - #[allow(unsafe_code)] - // https://w3c.github.io/webvr/#dom-vrframedata-leftviewmatrix - fn LeftViewMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { - unsafe { NonNull::new_unchecked(self.left_view.get()) } - } - - #[allow(unsafe_code)] - // https://w3c.github.io/webvr/#dom-vrframedata-rightprojectionmatrix - fn RightProjectionMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { - unsafe { NonNull::new_unchecked(self.right_proj.get()) } - } - - #[allow(unsafe_code)] - // https://w3c.github.io/webvr/#dom-vrframedata-rightviewmatrix - fn RightViewMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { - unsafe { NonNull::new_unchecked(self.right_view.get()) } - } - - // https://w3c.github.io/webvr/#dom-vrframedata-pose - fn Pose(&self) -> DomRoot<VRPose> { - DomRoot::from_ref(&*self.pose) - } -} diff --git a/components/script/dom/vrstageparameters.rs b/components/script/dom/vrstageparameters.rs deleted file mode 100644 index 4cc3ac4ed7c..00000000000 --- a/components/script/dom/vrstageparameters.rs +++ /dev/null @@ -1,90 +0,0 @@ -/* 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::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::VRStageParametersBinding::VRStageParametersMethods; -use crate::dom::bindings::num::Finite; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; -use crate::dom::bindings::root::DomRoot; -use crate::dom::window::Window; -use crate::script_runtime::JSContext; -use dom_struct::dom_struct; -use js::jsapi::{Heap, JSObject}; -use js::typedarray::{CreateWith, Float32Array}; -use std::ptr; -use std::ptr::NonNull; -use webvr_traits::WebVRStageParameters; - -#[dom_struct] -pub struct VRStageParameters { - reflector_: Reflector, - #[ignore_malloc_size_of = "Defined in rust-webvr"] - parameters: DomRefCell<WebVRStageParameters>, - #[ignore_malloc_size_of = "mozjs"] - transform: Heap<*mut JSObject>, -} - -unsafe_no_jsmanaged_fields!(WebVRStageParameters); - -impl VRStageParameters { - fn new_inherited(parameters: WebVRStageParameters) -> VRStageParameters { - VRStageParameters { - reflector_: Reflector::new(), - parameters: DomRefCell::new(parameters), - transform: Heap::default(), - } - } - - #[allow(unsafe_code)] - pub fn new(parameters: WebVRStageParameters, global: &Window) -> DomRoot<VRStageParameters> { - let cx = global.get_cx(); - rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); - unsafe { - let _ = Float32Array::create( - *cx, - CreateWith::Slice(¶meters.sitting_to_standing_transform), - array.handle_mut(), - ); - } - - let stage_parameters = reflect_dom_object( - Box::new(VRStageParameters::new_inherited(parameters)), - global, - ); - - stage_parameters.transform.set(array.get()); - - stage_parameters - } - - #[allow(unsafe_code)] - pub fn update(&self, parameters: &WebVRStageParameters) { - unsafe { - let cx = self.global().get_cx(); - typedarray!(in(*cx) let array: Float32Array = self.transform.get()); - if let Ok(mut array) = array { - array.update(¶meters.sitting_to_standing_transform); - } - } - *self.parameters.borrow_mut() = parameters.clone(); - } -} - -impl VRStageParametersMethods for VRStageParameters { - #[allow(unsafe_code)] - // https://w3c.github.io/webvr/#dom-vrstageparameters-sittingtostandingtransform - fn SittingToStandingTransform(&self, _cx: JSContext) -> NonNull<JSObject> { - unsafe { NonNull::new_unchecked(self.transform.get()) } - } - - // https://w3c.github.io/webvr/#dom-vrstageparameters-sizex - fn SizeX(&self) -> Finite<f32> { - Finite::wrap(self.parameters.borrow().size_x) - } - - // https://w3c.github.io/webvr/#dom-vrstageparameters-sizez - fn SizeZ(&self) -> Finite<f32> { - Finite::wrap(self.parameters.borrow().size_z) - } -} diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index d4327f6216a..e73921cabfb 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -60,7 +60,7 @@ use canvas_traits::webgl::{ Parameter, TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand, WebGLCommandBacktrace, WebGLContextId, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender, WebGLOpaqueFramebufferId, WebGLProgramId, WebGLResult, WebGLSLVersion, - WebGLSendResult, WebGLSender, WebGLVersion, WebVRCommand, YAxisTreatment, + WebGLSendResult, WebGLSender, WebGLVersion, YAxisTreatment, }; use dom_struct::dom_struct; use embedder_traits::EventLoopWaker; @@ -383,11 +383,6 @@ impl WebGLRenderingContext { let _ = self.webgl_sender.send_swap_buffers(id); } - #[inline] - pub fn send_vr_command(&self, command: WebVRCommand) { - self.webgl_sender.send_vr(command).unwrap(); - } - pub fn webgl_error(&self, err: WebGLError) { // TODO(emilio): Add useful debug messages to this warn!( @@ -4716,10 +4711,6 @@ impl WebGLMessageSender { self.wake_after_send(|| self.sender.send(msg, backtrace)) } - pub fn send_vr(&self, command: WebVRCommand) -> WebGLSendResult { - self.wake_after_send(|| self.sender.send_vr(command)) - } - pub fn send_swap_buffers(&self, id: Option<WebGLOpaqueFramebufferId>) -> WebGLSendResult { self.wake_after_send(|| self.sender.send_swap_buffers(id)) } diff --git a/components/script/dom/webidls/EventHandler.webidl b/components/script/dom/webidls/EventHandler.webidl index 842e1ebc7e8..99be904979b 100644 --- a/components/script/dom/webidls/EventHandler.webidl +++ b/components/script/dom/webidls/EventHandler.webidl @@ -122,17 +122,6 @@ interface mixin WindowEventHandlers { attribute EventHandler onunload; }; -// https://w3c.github.io/webvr/spec/1.1/#interface-window -partial interface mixin WindowEventHandlers { - attribute EventHandler onvrdisplayconnect; - attribute EventHandler onvrdisplaydisconnect; - attribute EventHandler onvrdisplayactivate; - attribute EventHandler onvrdisplaydeactivate; - attribute EventHandler onvrdisplayblur; - attribute EventHandler onvrdisplayfocus; - attribute EventHandler onvrdisplaypresentchange; -}; - // https://html.spec.whatwg.org/multipage/#documentandelementeventhandlers [Exposed=Window] interface mixin DocumentAndElementEventHandlers { diff --git a/components/script/dom/webidls/Gamepad.webidl b/components/script/dom/webidls/Gamepad.webidl index 224e6c5511d..925eaf2a544 100644 --- a/components/script/dom/webidls/Gamepad.webidl +++ b/components/script/dom/webidls/Gamepad.webidl @@ -14,13 +14,16 @@ interface Gamepad { [SameObject] readonly attribute GamepadButtonList buttons; }; -// https://w3c.github.io/gamepad/extensions.html#dom-gamepad +// https://w3c.github.io/gamepad/extensions.html#partial-gamepad-interface partial interface Gamepad { - readonly attribute DOMString hand; - readonly attribute VRPose? pose; + readonly attribute GamepadHand hand; + // readonly attribute FrozenArray<GamepadHapticActuator> hapticActuators; + readonly attribute GamepadPose? pose; }; -// https://w3c.github.io/webvr/spec/1.1/#interface-gamepad -partial interface Gamepad { - readonly attribute unsigned long displayId; +// https://w3c.github.io/gamepad/extensions.html#gamepadhand-enum +enum GamepadHand { + "", /* unknown, both hands, or not applicable */ + "left", + "right" }; diff --git a/components/script/dom/webidls/VRPose.webidl b/components/script/dom/webidls/GamepadPose.webidl index 7fb19c60da1..5afa9f3251e 100644 --- a/components/script/dom/webidls/VRPose.webidl +++ b/components/script/dom/webidls/GamepadPose.webidl @@ -2,9 +2,12 @@ * 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/. */ -// https://w3c.github.io/webvr/#interface-vrpose -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRPose { +// https://w3c.github.io/gamepad/extensions.html#gamepadpose-interface +[Exposed=Window, Pref="dom.gamepad.enabled"] +interface GamepadPose { + readonly attribute boolean hasOrientation; + readonly attribute boolean hasPosition; + readonly attribute Float32Array? position; readonly attribute Float32Array? linearVelocity; readonly attribute Float32Array? linearAcceleration; diff --git a/components/script/dom/webidls/Navigator.webidl b/components/script/dom/webidls/Navigator.webidl index b51e2ba52f0..77a54993cf2 100644 --- a/components/script/dom/webidls/Navigator.webidl +++ b/components/script/dom/webidls/Navigator.webidl @@ -60,11 +60,6 @@ interface mixin NavigatorCookies { readonly attribute boolean cookieEnabled; }; -// https://w3c.github.io/webvr/spec/1.1/#interface-navigator -partial interface Navigator { - [Pref="dom.webvr.enabled"] Promise<sequence<VRDisplay>> getVRDisplays(); -}; - // https://w3c.github.io/permissions/#navigator-and-workernavigator-extension [Exposed=(Window)] partial interface Navigator { diff --git a/components/script/dom/webidls/VRDisplay.webidl b/components/script/dom/webidls/VRDisplay.webidl deleted file mode 100644 index 0cb636e1a32..00000000000 --- a/components/script/dom/webidls/VRDisplay.webidl +++ /dev/null @@ -1,131 +0,0 @@ -/* 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/. */ - -enum VREye { - "left", - "right" -}; - - -// https://w3c.github.io/webvr/#interface-vrdisplay -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRDisplay : EventTarget { - readonly attribute boolean isConnected; - readonly attribute boolean isPresenting; - - /** - * Dictionary of capabilities describing the VRDisplay. - */ - [SameObject] readonly attribute VRDisplayCapabilities capabilities; - - /** - * If this VRDisplay supports room-scale experiences, the optional - * stage attribute contains details on the room-scale parameters. - * The stageParameters attribute can not change between null - * and non-null once the VRDisplay is enumerated; however, - * the values within VRStageParameters may change after - * any call to VRDisplay.submitFrame as the user may re-configure - * their environment at any time. - */ - readonly attribute VRStageParameters? stageParameters; - - /** - * Return the current VREyeParameters for the given eye. - */ - VREyeParameters getEyeParameters(VREye whichEye); - - /** - * An identifier for this distinct VRDisplay. Used as an - * association point in the Gamepad API. - */ - readonly attribute unsigned long displayId; - - /** - * A display name, a user-readable name identifying it. - */ - readonly attribute DOMString displayName; - - /** - * Populates the passed VRFrameData with the information required to render - * the current frame. - */ - boolean getFrameData(VRFrameData frameData); - - /** - * Return a VRPose containing the future predicted pose of the VRDisplay - * when the current frame will be presented. The value returned will not - * change until JavaScript has returned control to the browser. - * - * The VRPose will contain the position, orientation, velocity, - * and acceleration of each of these properties. - */ - [NewObject] VRPose getPose(); - - /** - * Reset the pose for this display, treating its current position and - * orientation as the "origin/zero" values. VRPose.position, - * VRPose.orientation, and VRStageParameters.sittingToStandingTransform may be - * updated when calling resetPose(). This should be called in only - * sitting-space experiences. - */ - void resetPose(); - - /** - * z-depth defining the near plane of the eye view frustum - * enables mapping of values in the render target depth - * attachment to scene coordinates. Initially set to 0.01. - */ - attribute double depthNear; - - /** - * z-depth defining the far plane of the eye view frustum - * enables mapping of values in the render target depth - * attachment to scene coordinates. Initially set to 10000.0. - */ - attribute double depthFar; - - /** - * The callback passed to `requestAnimationFrame` will be called - * any time a new frame should be rendered. When the VRDisplay is - * presenting the callback will be called at the native refresh - * rate of the HMD. When not presenting this function acts - * identically to how window.requestAnimationFrame acts. Content should - * make no assumptions of frame rate or vsync behavior as the HMD runs - * asynchronously from other displays and at differing refresh rates. - */ - unsigned long requestAnimationFrame(FrameRequestCallback callback); - - /** - * Passing the value returned by `requestAnimationFrame` to - * `cancelAnimationFrame` will unregister the callback. - */ - void cancelAnimationFrame(unsigned long handle); - - /** - * Begin presenting to the VRDisplay. Must be called in response to a user gesture. - * Repeat calls while already presenting will update the VRLayers being displayed. - * If the number of values in the leftBounds/rightBounds arrays is not 0 or 4 for - * any of the passed layers the promise is rejected. - * If the source of any of the layers is not present (null), the promise is rejected. - */ - Promise<void> requestPresent(sequence<VRLayer> layers); - - /** - * Stops presenting to the VRDisplay. - */ - Promise<void> exitPresent(); - - /** - * Get the layers currently being presented. - */ - sequence<VRLayer> getLayers(); - - /** - * The VRLayer provided to the VRDisplay will be captured and presented - * in the HMD. Calling this function has the same effect on the source - * canvas as any other operation that uses its source image, and canvases - * created without preserveDrawingBuffer set to true will be cleared. - */ - void submitFrame(); -}; diff --git a/components/script/dom/webidls/VRDisplayCapabilities.webidl b/components/script/dom/webidls/VRDisplayCapabilities.webidl deleted file mode 100644 index 7bb915dfa52..00000000000 --- a/components/script/dom/webidls/VRDisplayCapabilities.webidl +++ /dev/null @@ -1,13 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vrdisplaycapabilities -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRDisplayCapabilities { - readonly attribute boolean hasPosition; - readonly attribute boolean hasOrientation; - readonly attribute boolean hasExternalDisplay; - readonly attribute boolean canPresent; - readonly attribute unsigned long maxLayers; -}; diff --git a/components/script/dom/webidls/VRDisplayEvent.webidl b/components/script/dom/webidls/VRDisplayEvent.webidl deleted file mode 100644 index a10b9ca8624..00000000000 --- a/components/script/dom/webidls/VRDisplayEvent.webidl +++ /dev/null @@ -1,24 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vrdisplayevent - -enum VRDisplayEventReason { - "navigation", - "mounted", - "unmounted", - "requested" -}; - -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRDisplayEvent : Event { - [Throws] constructor(DOMString type, VRDisplayEventInit eventInitDict); - readonly attribute VRDisplay display; - readonly attribute VRDisplayEventReason? reason; -}; - -dictionary VRDisplayEventInit : EventInit { - required VRDisplay display; - VRDisplayEventReason reason; -}; diff --git a/components/script/dom/webidls/VREyeParameters.webidl b/components/script/dom/webidls/VREyeParameters.webidl deleted file mode 100644 index f9fd71c8e99..00000000000 --- a/components/script/dom/webidls/VREyeParameters.webidl +++ /dev/null @@ -1,13 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vreyeparameters - -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VREyeParameters { - readonly attribute Float32Array offset; - [SameObject] readonly attribute VRFieldOfView fieldOfView; - readonly attribute unsigned long renderWidth; - readonly attribute unsigned long renderHeight; -}; diff --git a/components/script/dom/webidls/VRFieldOfView.webidl b/components/script/dom/webidls/VRFieldOfView.webidl deleted file mode 100644 index bdd96758358..00000000000 --- a/components/script/dom/webidls/VRFieldOfView.webidl +++ /dev/null @@ -1,13 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vrfieldofview - -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRFieldOfView { - readonly attribute double upDegrees; - readonly attribute double rightDegrees; - readonly attribute double downDegrees; - readonly attribute double leftDegrees; -}; diff --git a/components/script/dom/webidls/VRFrameData.webidl b/components/script/dom/webidls/VRFrameData.webidl deleted file mode 100644 index 4c7c4695a8c..00000000000 --- a/components/script/dom/webidls/VRFrameData.webidl +++ /dev/null @@ -1,16 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vrframedata - -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRFrameData { - [Throws] constructor(); - readonly attribute DOMHighResTimeStamp timestamp; - readonly attribute Float32Array leftProjectionMatrix; - readonly attribute Float32Array leftViewMatrix; - readonly attribute Float32Array rightProjectionMatrix; - readonly attribute Float32Array rightViewMatrix; - readonly attribute VRPose pose; -}; diff --git a/components/script/dom/webidls/VRLayer.webidl b/components/script/dom/webidls/VRLayer.webidl deleted file mode 100644 index 2b95ab2e4ff..00000000000 --- a/components/script/dom/webidls/VRLayer.webidl +++ /dev/null @@ -1,13 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vrlayer - -//typedef (HTMLCanvasElement or OffscreenCanvas) VRSource; - -dictionary VRLayer { - HTMLCanvasElement source; - sequence<float> leftBounds; - sequence<float> rightBounds; -}; diff --git a/components/script/dom/webidls/VRStageParameters.webidl b/components/script/dom/webidls/VRStageParameters.webidl deleted file mode 100644 index 5816dd55db5..00000000000 --- a/components/script/dom/webidls/VRStageParameters.webidl +++ /dev/null @@ -1,11 +0,0 @@ -/* 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/. */ - -// https://w3c.github.io/webvr/#interface-vrstageparameters -[Exposed=Window, Pref="dom.webvr.enabled"] -interface VRStageParameters { - readonly attribute Float32Array sittingToStandingTransform; - readonly attribute float sizeX; - readonly attribute float sizeZ; -}; diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index ee7d38b57e1..9f37ec2240a 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -139,7 +139,6 @@ use style_traits::{CSSPixel, DevicePixel, ParsingMode}; use url::Position; use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel}; use webrender_api::{DocumentId, ExternalScrollId}; -use webvr_traits::WebVRMsg; /// Current state of the window object #[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)] @@ -268,10 +267,6 @@ pub struct Window { #[ignore_malloc_size_of = "channels are hard"] webgl_chan: Option<WebGLChan>, - /// A handle for communicating messages to the webvr thread, if available. - #[ignore_malloc_size_of = "channels are hard"] - webvr_chan: Option<IpcSender<WebVRMsg>>, - #[ignore_malloc_size_of = "defined in webxr"] webxr_registry: webxr_api::Registry, @@ -468,10 +463,6 @@ impl Window { .map(|chan| WebGLCommandSender::new(chan.clone(), self.get_event_loop_waker())) } - pub fn webvr_thread(&self) -> Option<IpcSender<WebVRMsg>> { - self.webvr_chan.clone() - } - pub fn webxr_registry(&self) -> webxr_api::Registry { self.webxr_registry.clone() } @@ -2272,7 +2263,6 @@ impl Window { navigation_start: u64, navigation_start_precise: u64, webgl_chan: Option<WebGLChan>, - webvr_chan: Option<IpcSender<WebVRMsg>>, webxr_registry: webxr_api::Registry, microtask_queue: Rc<MicrotaskQueue>, webrender_document: DocumentId, @@ -2350,7 +2340,6 @@ impl Window { media_query_lists: DOMTracker::new(), test_runner: Default::default(), webgl_chan, - webvr_chan, webxr_registry, pending_layout_images: Default::default(), unminified_js_dir: Default::default(), diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs index 6de10312ec3..27a9085bded 100644 --- a/components/script/dom/xrframe.rs +++ b/components/script/dom/xrframe.rs @@ -21,7 +21,7 @@ use webxr_api::Frame; pub struct XRFrame { reflector_: Reflector, session: Dom<XRSession>, - #[ignore_malloc_size_of = "defined in rust-webvr"] + #[ignore_malloc_size_of = "defined in webxr_api"] data: Frame, active: Cell<bool>, animation_frame: Cell<bool>, diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index fad59c0aa11..ac752d5a3dd 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -9,9 +9,9 @@ use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::bindings::utils::create_typed_array; use crate::dom::dompointreadonly::DOMPointReadOnly; use crate::dom::globalscope::GlobalScope; -use crate::dom::vrframedata::create_typed_array; use crate::dom::window::Window; use crate::dom::xrsession::ApiRigidTransform; use crate::script_runtime::JSContext; diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 78d4a5e89a0..0e2a44f09cb 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -3,23 +3,17 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionInit; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::{XRSessionMode, XRSystemMethods}; use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible}; use crate::dom::bindings::error::Error; -use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::trace::RootedTraceableBox; -use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; use crate::dom::gamepad::Gamepad; -use crate::dom::gamepadevent::GamepadEventType; use crate::dom::promise::Promise; -use crate::dom::vrdisplay::VRDisplay; -use crate::dom::vrdisplayevent::VRDisplayEvent; use crate::dom::window::Window; use crate::dom::xrsession::XRSession; use crate::dom::xrtest::XRTest; @@ -27,55 +21,43 @@ use crate::realms::InRealm; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; -use ipc_channel::ipc::{self as ipc_crate, IpcReceiver, IpcSender}; +use ipc_channel::ipc::{self as ipc_crate, IpcReceiver}; use ipc_channel::router::ROUTER; use msg::constellation_msg::PipelineId; use profile_traits::ipc; use std::cell::Cell; use std::rc::Rc; -use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg}; -use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState}; use webxr_api::{Error as XRError, Frame, Session, SessionInit, SessionMode}; #[dom_struct] pub struct XRSystem { eventtarget: EventTarget, - displays: DomRefCell<Vec<Dom<VRDisplay>>>, gamepads: DomRefCell<Vec<Dom<Gamepad>>>, pending_immersive_session: Cell<bool>, active_immersive_session: MutNullableDom<XRSession>, active_inline_sessions: DomRefCell<Vec<Dom<XRSession>>>, test: MutNullableDom<XRTest>, pipeline: PipelineId, - #[ignore_malloc_size_of = "channels are hard"] - webvr_thread: Option<IpcSender<WebVRMsg>>, } impl XRSystem { - fn new_inherited(pipeline: PipelineId, webvr_thread: Option<IpcSender<WebVRMsg>>) -> XRSystem { + fn new_inherited(pipeline: PipelineId) -> XRSystem { XRSystem { eventtarget: EventTarget::new_inherited(), - displays: DomRefCell::new(Vec::new()), gamepads: DomRefCell::new(Vec::new()), pending_immersive_session: Cell::new(false), active_immersive_session: Default::default(), active_inline_sessions: DomRefCell::new(Vec::new()), test: Default::default(), pipeline, - webvr_thread, } } pub fn new(window: &Window) -> DomRoot<XRSystem> { - let root = reflect_dom_object( - Box::new(XRSystem::new_inherited( - window.pipeline_id(), - window.webvr_thread(), - )), + reflect_dom_object( + Box::new(XRSystem::new_inherited(window.pipeline_id())), window, - ); - root.register(); - root + ) } pub fn pending_or_active_session(&self) -> bool { @@ -107,12 +89,6 @@ impl XRSystem { } } -impl Drop for XRSystem { - fn drop(&mut self) { - self.unregister(); - } -} - impl Into<SessionMode> for XRSessionMode { fn into(self) -> SessionMode { match self { @@ -309,202 +285,4 @@ impl XRSystem { // This must be called _after_ the promise is resolved session.setup_initial_inputs(); } - - pub fn get_displays(&self) -> Result<Vec<DomRoot<VRDisplay>>, ()> { - if let Some(ref webvr_thread) = self.webvr_thread { - let (sender, receiver) = - ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); - webvr_thread.send(WebVRMsg::GetDisplays(sender)).unwrap(); - - // FIXME(#22505) we should not block here and instead produce a promise - match receiver.recv().unwrap() { - Ok(displays) => { - // Sync displays - for display in displays { - self.sync_display(&display); - } - }, - Err(_) => return Err(()), - } - } else { - // WebVR spec: The Promise MUST be rejected if WebVR is not enabled/supported. - return Err(()); - } - - // convert from Dom to DomRoot - Ok(self - .displays - .borrow() - .iter() - .map(|d| DomRoot::from_ref(&**d)) - .collect()) - } - - fn find_display(&self, display_id: u32) -> Option<DomRoot<VRDisplay>> { - self.displays - .borrow() - .iter() - .find(|d| d.DisplayId() == display_id) - .map(|d| DomRoot::from_ref(&**d)) - } - - fn register(&self) { - if let Some(ref webvr_thread) = self.webvr_thread { - let msg = WebVRMsg::RegisterContext(self.global().pipeline_id()); - webvr_thread.send(msg).unwrap(); - } - } - - fn unregister(&self) { - if let Some(ref webvr_thread) = self.webvr_thread { - let msg = WebVRMsg::UnregisterContext(self.pipeline); - webvr_thread.send(msg).unwrap(); - } - } - - fn sync_display(&self, display: &WebVRDisplayData) -> DomRoot<VRDisplay> { - if let Some(existing) = self.find_display(display.display_id) { - existing.update_display(&display); - existing - } else { - let root = VRDisplay::new(&self.global().as_window(), display.clone()); - self.displays.borrow_mut().push(Dom::from_ref(&*root)); - root - } - } - - fn handle_display_event(&self, event: WebVRDisplayEvent) { - match event { - WebVRDisplayEvent::Connect(ref display) => { - let display = self.sync_display(&display); - display.handle_webvr_event(&event); - self.notify_display_event(&display, &event); - }, - WebVRDisplayEvent::Disconnect(id) => { - if let Some(display) = self.find_display(id) { - display.handle_webvr_event(&event); - self.notify_display_event(&display, &event); - } - }, - WebVRDisplayEvent::Activate(ref display, _) | - WebVRDisplayEvent::Deactivate(ref display, _) | - WebVRDisplayEvent::Blur(ref display) | - WebVRDisplayEvent::Focus(ref display) | - WebVRDisplayEvent::PresentChange(ref display, _) | - WebVRDisplayEvent::Change(ref display) => { - let display = self.sync_display(&display); - display.handle_webvr_event(&event); - }, - WebVRDisplayEvent::Pause(id) | - WebVRDisplayEvent::Resume(id) | - WebVRDisplayEvent::Exit(id) => { - if let Some(display) = self.find_display(id) { - display.handle_webvr_event(&event); - } - }, - }; - } - - fn handle_gamepad_event(&self, event: WebVRGamepadEvent) { - match event { - WebVRGamepadEvent::Connect(data, state) => { - if let Some(gamepad) = self.find_gamepad(state.gamepad_id) { - gamepad.update_from_vr(&state); - } else { - // new gamepad - self.sync_gamepad(Some(data), &state); - } - }, - WebVRGamepadEvent::Disconnect(id) => { - if let Some(gamepad) = self.find_gamepad(id) { - gamepad.update_connected(false); - } - }, - }; - } - - pub fn handle_webvr_event(&self, event: WebVREvent) { - match event { - WebVREvent::Display(event) => { - self.handle_display_event(event); - }, - WebVREvent::Gamepad(event) => { - self.handle_gamepad_event(event); - }, - }; - } - - pub fn handle_webvr_events(&self, events: Vec<WebVREvent>) { - for event in events { - self.handle_webvr_event(event); - } - } - - fn notify_display_event(&self, display: &VRDisplay, event: &WebVRDisplayEvent) { - let event = VRDisplayEvent::new_from_webvr(&self.global(), &display, &event); - event - .upcast::<Event>() - .fire(self.global().upcast::<EventTarget>()); - } -} - -// Gamepad -impl XRSystem { - fn find_gamepad(&self, gamepad_id: u32) -> Option<DomRoot<Gamepad>> { - self.gamepads - .borrow() - .iter() - .find(|g| g.gamepad_id() == gamepad_id) - .map(|g| DomRoot::from_ref(&**g)) - } - - fn sync_gamepad(&self, data: Option<WebVRGamepadData>, state: &WebVRGamepadState) { - if let Some(existing) = self.find_gamepad(state.gamepad_id) { - existing.update_from_vr(&state); - } else { - let index = self.gamepads.borrow().len(); - let data = data.unwrap_or_default(); - let root = Gamepad::new_from_vr(&self.global(), index as i32, &data, &state); - self.gamepads.borrow_mut().push(Dom::from_ref(&*root)); - if state.connected { - root.notify_event(GamepadEventType::Connected); - } - } - } - - // Gamepads are synced immediately in response to the API call. - // The current approach allows the to sample gamepad state multiple times per frame. This - // guarantees that the gamepads always have a valid state and can be very useful for - // motion capture or drawing applications. - pub fn get_gamepads(&self) -> Vec<DomRoot<Gamepad>> { - if let Some(ref wevbr_sender) = self.webvr_thread { - let (sender, receiver) = - ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); - let synced_ids = self - .gamepads - .borrow() - .iter() - .map(|g| g.gamepad_id()) - .collect(); - wevbr_sender - .send(WebVRMsg::GetGamepads(synced_ids, sender)) - .unwrap(); - match receiver.recv().unwrap() { - Ok(gamepads) => { - // Sync displays - for gamepad in gamepads { - self.sync_gamepad(gamepad.0, &gamepad.1); - } - }, - Err(_) => {}, - } - } - - // We can add other not VR related gamepad providers here - self.gamepads - .borrow() - .iter() - .map(|g| DomRoot::from_ref(&**g)) - .collect() - } } diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index 38fc3e82f24..14309dfc99c 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -5,8 +5,8 @@ use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::utils::create_typed_array; use crate::dom::globalscope::GlobalScope; -use crate::dom::vrframedata::create_typed_array; use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrsession::{cast_transform, ApiViewerPose, XRSession}; use crate::script_runtime::JSContext; |