From 376426a9362a43d14d79ce838cf9834698bebe2a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 14:17:14 -0800 Subject: [PATCH 01/25] Move VR interface to XR The WebVR spec no longer has a navigator.vr, but there is a navigator.XR in the XR spec. Instead of duplicating work I've combined the two. --- components/script/dom/mod.rs | 2 +- components/script/dom/navigator.rs | 17 ++++++------- components/script/dom/webidls/VR.webidl | 11 --------- components/script/dom/webidls/XR.webidl | 30 +++++++++++++++++++++++ components/script/dom/{vr.rs => xr.rs} | 32 +++++++++++-------------- components/script/script_thread.rs | 5 ++-- 6 files changed, 55 insertions(+), 42 deletions(-) delete mode 100644 components/script/dom/webidls/VR.webidl create mode 100644 components/script/dom/webidls/XR.webidl rename components/script/dom/{vr.rs => xr.rs} (93%) diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index e38a5e924ac..cc734b2543e 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -479,7 +479,6 @@ pub mod validation; pub mod validitystate; pub mod values; pub mod virtualmethods; -pub mod vr; pub mod vrdisplay; pub mod vrdisplaycapabilities; pub mod vrdisplayevent; @@ -518,3 +517,4 @@ pub mod xmldocument; pub mod xmlhttprequest; pub mod xmlhttprequesteventtarget; pub mod xmlhttprequestupload; +pub mod xr; diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 04669ca25d9..fccc49aac9d 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -4,7 +4,6 @@ use crate::dom::bindings::codegen::Bindings::NavigatorBinding; use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods; -use crate::dom::bindings::codegen::Bindings::VRBinding::VRBinding::VRMethods; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::bindings::str::DOMString; @@ -16,8 +15,8 @@ use crate::dom::permissions::Permissions; use crate::dom::pluginarray::PluginArray; use crate::dom::promise::Promise; use crate::dom::serviceworkercontainer::ServiceWorkerContainer; -use crate::dom::vr::VR; use crate::dom::window::Window; +use crate::dom::xr::XR; use dom_struct::dom_struct; use std::rc::Rc; @@ -28,7 +27,7 @@ pub struct Navigator { plugins: MutNullableDom, mime_types: MutNullableDom, service_worker: MutNullableDom, - vr: MutNullableDom, + xr: MutNullableDom, gamepads: MutNullableDom, permissions: MutNullableDom, } @@ -41,7 +40,7 @@ impl Navigator { plugins: Default::default(), mime_types: Default::default(), service_worker: Default::default(), - vr: Default::default(), + xr: Default::default(), gamepads: Default::default(), permissions: Default::default(), } @@ -135,7 +134,7 @@ impl NavigatorMethods for Navigator { .gamepads .or_init(|| GamepadList::new(&self.global(), &[])); - let vr_gamepads = self.Vr().get_gamepads(); + let vr_gamepads = self.Xr().get_gamepads(); root.add_if_not_exists(&vr_gamepads); // TODO: Add not VR related gamepads root @@ -149,12 +148,10 @@ impl NavigatorMethods for Navigator { // https://w3c.github.io/webvr/spec/1.1/#navigator-getvrdisplays-attribute #[allow(unrooted_must_root)] fn GetVRDisplays(&self) -> Rc { - self.Vr().GetDisplays() + self.Xr().get_displays() } -} -impl Navigator { - pub fn Vr(&self) -> DomRoot { - self.vr.or_init(|| VR::new(&self.global())) + fn Xr(&self) -> DomRoot { + self.xr.or_init(|| XR::new(&self.global())) } } diff --git a/components/script/dom/webidls/VR.webidl b/components/script/dom/webidls/VR.webidl deleted file mode 100644 index 536bce29338..00000000000 --- a/components/script/dom/webidls/VR.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-navigator -[NoInterfaceObject] -interface VR { - [Pref="dom.webvr.enabled"] - Promise> getDisplays(); - //readonly attribute FrozenArray activeVRDisplays; -}; diff --git a/components/script/dom/webidls/XR.webidl b/components/script/dom/webidls/XR.webidl new file mode 100644 index 00000000000..9c973c39f6f --- /dev/null +++ b/components/script/dom/webidls/XR.webidl @@ -0,0 +1,30 @@ +/* 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://immersive-web.github.io/webxr/#xr-interface +[SecureContext, Exposed=Window] +interface XR: EventTarget { + // Methods + // Promise supportsSessionMode(XRSessionMode mode); + // Promise requestSession(optional XRSessionCreationOptions parameters); + + // Events + // attribute EventHandler ondevicechange; +}; + +[SecureContext] +partial interface Navigator { + [SameObject, Pref="dom.webvr.enabled"] readonly attribute XR xr; +}; + +enum XRSessionMode { + "inline", + "immersive-vr", + "immersive-ar" +}; + +dictionary XRSessionCreationOptions { + XRSessionMode mode = "inline"; + // XRPresentationContext outputContext; +}; diff --git a/components/script/dom/vr.rs b/components/script/dom/xr.rs similarity index 93% rename from components/script/dom/vr.rs rename to components/script/dom/xr.rs index 6686e0d917e..29d77b38a67 100644 --- a/components/script/dom/vr.rs +++ b/components/script/dom/xr.rs @@ -3,12 +3,11 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::VRBinding; -use crate::dom::bindings::codegen::Bindings::VRBinding::VRMethods; +use crate::dom::bindings::codegen::Bindings::XRBinding; use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods; use crate::dom::bindings::error::Error; use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; @@ -26,38 +25,37 @@ use webvr_traits::{WebVRDisplayData, WebVRDisplayEvent, WebVREvent, WebVRMsg}; use webvr_traits::{WebVRGamepadData, WebVRGamepadEvent, WebVRGamepadState}; #[dom_struct] -pub struct VR { - reflector_: Reflector, +pub struct XR { + eventtarget: EventTarget, displays: DomRefCell>>, gamepads: DomRefCell>>, } -impl VR { - fn new_inherited() -> VR { - VR { - reflector_: Reflector::new(), +impl XR { + fn new_inherited() -> XR { + XR { + eventtarget: EventTarget::new_inherited(), displays: DomRefCell::new(Vec::new()), gamepads: DomRefCell::new(Vec::new()), } } - pub fn new(global: &GlobalScope) -> DomRoot { - let root = reflect_dom_object(Box::new(VR::new_inherited()), global, VRBinding::Wrap); + pub fn new(global: &GlobalScope) -> DomRoot { + let root = reflect_dom_object(Box::new(XR::new_inherited()), global, XRBinding::Wrap); root.register(); root } } -impl Drop for VR { +impl Drop for XR { fn drop(&mut self) { self.unregister(); } } -impl VRMethods for VR { +impl XR { #[allow(unrooted_must_root)] - // https://w3c.github.io/webvr/#interface-navigator - fn GetDisplays(&self) -> Rc { + pub fn get_displays(&self) -> Rc { let promise = Promise::new(&self.global()); if let Some(webvr_thread) = self.webvr_thread() { @@ -93,9 +91,7 @@ impl VRMethods for VR { promise } -} -impl VR { fn webvr_thread(&self) -> Option> { self.global().as_window().webvr_thread() } @@ -209,7 +205,7 @@ impl VR { } // Gamepad -impl VR { +impl XR { fn find_gamepad(&self, gamepad_id: u32) -> Option> { self.gamepads .borrow() diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 50f6135ff52..2da35702834 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -26,6 +26,7 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::{ DocumentMethods, DocumentReadyState, }; use crate::dom::bindings::codegen::Bindings::EventBinding::EventInit; +use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods; use crate::dom::bindings::codegen::Bindings::TransitionEventBinding::TransitionEventInit; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use crate::dom::bindings::conversions::{ @@ -3278,8 +3279,8 @@ impl ScriptThread { fn handle_webvr_events(&self, pipeline_id: PipelineId, events: Vec) { let window = self.documents.borrow().find_window(pipeline_id); if let Some(window) = window { - let vr = window.Navigator().Vr(); - vr.handle_webvr_events(events); + let xr = window.Navigator().Xr(); + xr.handle_webvr_events(events); } } From ebf9ccc9de3c9616f22ab08a1db5f39e7029f8dd Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 14:55:43 -0800 Subject: [PATCH 02/25] Basic XRSession interface --- components/script/dom/mod.rs | 1 + .../script/dom/webidls/XRSession.webidl | 41 +++++++++++++++++++ components/script/dom/xr.rs | 2 +- components/script/dom/xrsession.rs | 31 ++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 components/script/dom/webidls/XRSession.webidl create mode 100644 components/script/dom/xrsession.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index cc734b2543e..dac70366544 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -518,3 +518,4 @@ pub mod xmlhttprequest; pub mod xmlhttprequesteventtarget; pub mod xmlhttprequestupload; pub mod xr; +pub mod xrsession; diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl new file mode 100644 index 00000000000..d18b6e18a16 --- /dev/null +++ b/components/script/dom/webidls/XRSession.webidl @@ -0,0 +1,41 @@ +/* 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://immersive-web.github.io/webxr/#xrsession-interface + +enum XREnvironmentBlendMode { + "opaque", + "additive", + "alpha-blend", +}; + +[SecureContext, Exposed=Window] interface XRSession : EventTarget { + // // Attributes + // readonly attribute XRSessionMode mode; + // readonly attribute XRPresentationContext outputContext; + // readonly attribute XREnvironmentBlendMode environmentBlendMode; + + // attribute double depthNear; + // attribute double depthFar; + // attribute XRLayer baseLayer; + + // // Methods + // Promise requestReferenceSpace(XRReferenceSpaceType type, optional XRReferenceSpaceOptions options); + + // FrozenArray getInputSources(); + + // long requestAnimationFrame(XRFrameRequestCallback callback); + // void cancelAnimationFrame(long handle); + + // Promise end(); + + // // Events + // attribute EventHandler onblur; + // attribute EventHandler onfocus; + // attribute EventHandler onend; + // attribute EventHandler onselect; + // attribute EventHandler oninputsourceschange; + // attribute EventHandler onselectstart; + // attribute EventHandler onselectend; +}; \ No newline at end of file diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index 29d77b38a67..e64be23663e 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -3,8 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::XRBinding; use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods; +use crate::dom::bindings::codegen::Bindings::XRBinding; use crate::dom::bindings::error::Error; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs new file mode 100644 index 00000000000..b0ebe383ae7 --- /dev/null +++ b/components/script/dom/xrsession.rs @@ -0,0 +1,31 @@ +/* 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::XRSessionBinding; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::eventtarget::EventTarget; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRSession { + eventtarget: EventTarget, +} + +impl XRSession { + fn new_inherited() -> XRSession { + XRSession { + eventtarget: EventTarget::new_inherited(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRSession::new_inherited()), + global, + XRSessionBinding::Wrap, + ) + } +} From 29e9672d4df867777073ad417dce0e7dd620fb0e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 15:16:01 -0800 Subject: [PATCH 03/25] Basic XRFrame interface --- components/script/dom/mod.rs | 3 ++ components/script/dom/webidls/XRFrame.webidl | 12 ++++++ components/script/dom/webidls/XRLayer.webidl | 7 ++++ .../script/dom/webidls/XRWebGLLayer.webidl | 41 +++++++++++++++++++ components/script/dom/xrframe.rs | 30 ++++++++++++++ components/script/dom/xrlayer.rs | 30 ++++++++++++++ components/script/dom/xrwebgllayer.rs | 31 ++++++++++++++ 7 files changed, 154 insertions(+) create mode 100644 components/script/dom/webidls/XRFrame.webidl create mode 100644 components/script/dom/webidls/XRLayer.webidl create mode 100644 components/script/dom/webidls/XRWebGLLayer.webidl create mode 100644 components/script/dom/xrframe.rs create mode 100644 components/script/dom/xrlayer.rs create mode 100644 components/script/dom/xrwebgllayer.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index dac70366544..56b501bdac9 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -518,4 +518,7 @@ pub mod xmlhttprequest; pub mod xmlhttprequesteventtarget; pub mod xmlhttprequestupload; pub mod xr; +pub mod xrframe; +pub mod xrlayer; pub mod xrsession; +pub mod xrwebgllayer; diff --git a/components/script/dom/webidls/XRFrame.webidl b/components/script/dom/webidls/XRFrame.webidl new file mode 100644 index 00000000000..e35f8a44bf0 --- /dev/null +++ b/components/script/dom/webidls/XRFrame.webidl @@ -0,0 +1,12 @@ +/* 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://immersive-web.github.io/webxr/#xrframe-interface + +[SecureContext, Exposed=Window] interface XRFrame { + // readonly attribute XRSession session; + + // XRViewerPose? getViewerPose(optional XRReferenceSpace referenceSpace); + // XRInputPose? getInputPose(XRInputSource inputSource, optional XRReferenceSpace referenceSpace); +}; \ No newline at end of file diff --git a/components/script/dom/webidls/XRLayer.webidl b/components/script/dom/webidls/XRLayer.webidl new file mode 100644 index 00000000000..829b1436a27 --- /dev/null +++ b/components/script/dom/webidls/XRLayer.webidl @@ -0,0 +1,7 @@ +/* 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://immersive-web.github.io/webxr/#xrlayer-interface + +[SecureContext, Exposed=Window] interface XRLayer {}; diff --git a/components/script/dom/webidls/XRWebGLLayer.webidl b/components/script/dom/webidls/XRWebGLLayer.webidl new file mode 100644 index 00000000000..7a9bddf1687 --- /dev/null +++ b/components/script/dom/webidls/XRWebGLLayer.webidl @@ -0,0 +1,41 @@ +/* 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://immersive-web.github.io/webxr/#xrwebgllayer-interface + +typedef (WebGLRenderingContext or + WebGL2RenderingContext) XRWebGLRenderingContext; + +dictionary XRWebGLLayerInit { + boolean antialias = true; + boolean depth = true; + boolean stencil = false; + boolean alpha = true; + double framebufferScaleFactor = 1.0; +}; + +[SecureContext, Exposed=Window] +// [Constructor(XRSession session, +// XRWebGLRenderingContext context, +// optional XRWebGLLayerInit layerInit)] +interface XRWebGLLayer : XRLayer { + // // Attributes + // readonly attribute XRWebGLRenderingContext context; + + // readonly attribute boolean antialias; + // readonly attribute boolean depth; + // readonly attribute boolean stencil; + // readonly attribute boolean alpha; + + // readonly attribute WebGLFramebuffer framebuffer; + // readonly attribute unsigned long framebufferWidth; + // readonly attribute unsigned long framebufferHeight; + + // // Methods + // XRViewport? getViewport(XRView view); + // void requestViewportScaling(double viewportScaleFactor); + + // // Static Methods + // static double getNativeFramebufferScaleFactor(XRSession session); +}; \ No newline at end of file diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs new file mode 100644 index 00000000000..b7b8f7e0964 --- /dev/null +++ b/components/script/dom/xrframe.rs @@ -0,0 +1,30 @@ +/* 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::XRFrameBinding; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRFrame { + reflector_: Reflector, +} + +impl XRFrame { + fn new_inherited() -> XRFrame { + XRFrame { + reflector_: Reflector::new(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRFrame::new_inherited()), + global, + XRFrameBinding::Wrap, + ) + } +} diff --git a/components/script/dom/xrlayer.rs b/components/script/dom/xrlayer.rs new file mode 100644 index 00000000000..85e00d3ad1a --- /dev/null +++ b/components/script/dom/xrlayer.rs @@ -0,0 +1,30 @@ +/* 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::XRLayerBinding; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRLayer { + reflector_: Reflector, +} + +impl XRLayer { + pub fn new_inherited() -> XRLayer { + XRLayer { + reflector_: Reflector::new(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRLayer::new_inherited()), + global, + XRLayerBinding::Wrap, + ) + } +} diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs new file mode 100644 index 00000000000..2c550c4fef4 --- /dev/null +++ b/components/script/dom/xrwebgllayer.rs @@ -0,0 +1,31 @@ +/* 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::XRWebGLLayerBinding; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrlayer::XRLayer; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRWebGLLayer { + xrlayer: XRLayer, +} + +impl XRWebGLLayer { + pub fn new_inherited() -> XRWebGLLayer { + XRWebGLLayer { + xrlayer: XRLayer::new_inherited(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRWebGLLayer::new_inherited()), + global, + XRWebGLLayerBinding::Wrap, + ) + } +} From 90e0ceb7ce083e54fb7e749e929ab979cc66fe06 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 15:36:37 -0800 Subject: [PATCH 04/25] Basic XRSpace interface --- components/script/dom/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 56b501bdac9..d2416b113c8 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -521,4 +521,5 @@ pub mod xr; pub mod xrframe; pub mod xrlayer; pub mod xrsession; +pub mod xrspace; pub mod xrwebgllayer; From 581470016f1cc7d6d183e983056ec8e4882a0b19 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 15:46:39 -0800 Subject: [PATCH 05/25] Basic XRReferenceSpace interface --- components/script/dom/mod.rs | 2 ++ .../dom/webidls/XRReferenceSpace.webidl | 20 ++++++++++++ components/script/dom/webidls/XRSpace.webidl | 7 +++++ .../webidls/XRStationaryReferenceSpace.webidl | 20 ++++++++++++ components/script/dom/xrreferencespace.rs | 31 +++++++++++++++++++ components/script/dom/xrspace.rs | 31 +++++++++++++++++++ .../script/dom/xrstationaryreferencespace.rs | 31 +++++++++++++++++++ 7 files changed, 142 insertions(+) create mode 100644 components/script/dom/webidls/XRReferenceSpace.webidl create mode 100644 components/script/dom/webidls/XRSpace.webidl create mode 100644 components/script/dom/webidls/XRStationaryReferenceSpace.webidl create mode 100644 components/script/dom/xrreferencespace.rs create mode 100644 components/script/dom/xrspace.rs create mode 100644 components/script/dom/xrstationaryreferencespace.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index d2416b113c8..8bc483739b3 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -520,6 +520,8 @@ pub mod xmlhttprequestupload; pub mod xr; pub mod xrframe; pub mod xrlayer; +pub mod xrreferencespace; pub mod xrsession; pub mod xrspace; +pub mod xrstationaryreferencespace; pub mod xrwebgllayer; diff --git a/components/script/dom/webidls/XRReferenceSpace.webidl b/components/script/dom/webidls/XRReferenceSpace.webidl new file mode 100644 index 00000000000..5b18050dda2 --- /dev/null +++ b/components/script/dom/webidls/XRReferenceSpace.webidl @@ -0,0 +1,20 @@ +/* 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://immersive-web.github.io/webxr/#xrreferencespace-interface + +enum XRReferenceSpaceType { + "stationary", + "bounded", + "unbounded" +}; + +dictionary XRReferenceSpaceOptions { + required XRReferenceSpaceType type; +}; + +[SecureContext, Exposed=Window] interface XRReferenceSpace : XRSpace { + // attribute XRRigidTransform originOffset; + // attribute EventHandler onreset; +}; diff --git a/components/script/dom/webidls/XRSpace.webidl b/components/script/dom/webidls/XRSpace.webidl new file mode 100644 index 00000000000..9ad1d399429 --- /dev/null +++ b/components/script/dom/webidls/XRSpace.webidl @@ -0,0 +1,7 @@ +/* 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/. */ + +[SecureContext, Exposed=Window] interface XRSpace : EventTarget { + // XRRigidTransform? getTransformTo(XRSpace other); +}; \ No newline at end of file diff --git a/components/script/dom/webidls/XRStationaryReferenceSpace.webidl b/components/script/dom/webidls/XRStationaryReferenceSpace.webidl new file mode 100644 index 00000000000..a6b8954b885 --- /dev/null +++ b/components/script/dom/webidls/XRStationaryReferenceSpace.webidl @@ -0,0 +1,20 @@ +/* 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://immersive-web.github.io/webxr/#xrstationaryreferencespace-interface + +enum XRStationaryReferenceSpaceSubtype { + "eye-level", + "floor-level", + "position-disabled" +}; + +dictionary XRStationaryReferenceSpaceOptions : XRReferenceSpaceOptions { + required XRStationaryReferenceSpaceSubtype subtype; +}; + +[SecureContext, Exposed=Window] +interface XRStationaryReferenceSpace: XRReferenceSpace { + // readonly attribute XRStationaryReferenceSpaceSubtype subtype; +}; \ No newline at end of file diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs new file mode 100644 index 00000000000..0a2e1bee3d9 --- /dev/null +++ b/components/script/dom/xrreferencespace.rs @@ -0,0 +1,31 @@ +/* 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::XRReferenceSpaceBinding; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrspace::XRSpace; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRReferenceSpace { + xrspace: XRSpace, +} + +impl XRReferenceSpace { + pub fn new_inherited() -> XRReferenceSpace { + XRReferenceSpace { + xrspace: XRSpace::new_inherited(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRReferenceSpace::new_inherited()), + global, + XRReferenceSpaceBinding::Wrap, + ) + } +} diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs new file mode 100644 index 00000000000..c0def208f64 --- /dev/null +++ b/components/script/dom/xrspace.rs @@ -0,0 +1,31 @@ +/* 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::XRSpaceBinding; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::eventtarget::EventTarget; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRSpace { + eventtarget: EventTarget, +} + +impl XRSpace { + pub fn new_inherited() -> XRSpace { + XRSpace { + eventtarget: EventTarget::new_inherited(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRSpace::new_inherited()), + global, + XRSpaceBinding::Wrap, + ) + } +} diff --git a/components/script/dom/xrstationaryreferencespace.rs b/components/script/dom/xrstationaryreferencespace.rs new file mode 100644 index 00000000000..65dc5dd93cf --- /dev/null +++ b/components/script/dom/xrstationaryreferencespace.rs @@ -0,0 +1,31 @@ +/* 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::XRStationaryReferenceSpaceBinding; +use crate::dom::bindings::reflector::reflect_dom_object; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use crate::dom::xrreferencespace::XRReferenceSpace; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRStationaryReferenceSpace { + xrreferencespace: XRReferenceSpace, +} + +impl XRStationaryReferenceSpace { + pub fn new_inherited() -> XRStationaryReferenceSpace { + XRStationaryReferenceSpace { + xrreferencespace: XRReferenceSpace::new_inherited(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRStationaryReferenceSpace::new_inherited()), + global, + XRStationaryReferenceSpaceBinding::Wrap, + ) + } +} From 31feb1eca2fb4570664446efc604ca82344a3868 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 16:44:53 -0800 Subject: [PATCH 06/25] Basic XRViewerPose interface --- components/script/dom/mod.rs | 1 + .../script/dom/webidls/XRViewerPose.webidl | 10 +++++++ components/script/dom/xrviewerpose.rs | 30 +++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 components/script/dom/webidls/XRViewerPose.webidl create mode 100644 components/script/dom/xrviewerpose.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 8bc483739b3..89c36a7a08e 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -524,4 +524,5 @@ pub mod xrreferencespace; pub mod xrsession; pub mod xrspace; pub mod xrstationaryreferencespace; +pub mod xrviewerpose; pub mod xrwebgllayer; diff --git a/components/script/dom/webidls/XRViewerPose.webidl b/components/script/dom/webidls/XRViewerPose.webidl new file mode 100644 index 00000000000..ff87930e320 --- /dev/null +++ b/components/script/dom/webidls/XRViewerPose.webidl @@ -0,0 +1,10 @@ +/* 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://immersive-web.github.io/webxr/#xrviewerpose-interface + +[SecureContext, Exposed=Window] interface XRViewerPose { + // readonly attribute XRRigidTransform transform; + // readonly attribute FrozenArray views; +}; \ No newline at end of file diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs new file mode 100644 index 00000000000..9fc06c671dd --- /dev/null +++ b/components/script/dom/xrviewerpose.rs @@ -0,0 +1,30 @@ +/* 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::XRViewerPoseBinding; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRViewerPose { + reflector_: Reflector, +} + +impl XRViewerPose { + fn new_inherited() -> XRViewerPose { + XRViewerPose { + reflector_: Reflector::new(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRViewerPose::new_inherited()), + global, + XRViewerPoseBinding::Wrap, + ) + } +} From 73c530344cdae436eddcfb282ebd657758d21566 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 16:48:44 -0800 Subject: [PATCH 07/25] Basic XRView interface --- components/script/dom/mod.rs | 1 + components/script/dom/webidls/XRView.webidl | 17 ++++++++++++ components/script/dom/xrview.rs | 30 +++++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 components/script/dom/webidls/XRView.webidl create mode 100644 components/script/dom/xrview.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 89c36a7a08e..aae84c5bdd5 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -524,5 +524,6 @@ pub mod xrreferencespace; pub mod xrsession; pub mod xrspace; pub mod xrstationaryreferencespace; +pub mod xrview; pub mod xrviewerpose; pub mod xrwebgllayer; diff --git a/components/script/dom/webidls/XRView.webidl b/components/script/dom/webidls/XRView.webidl new file mode 100644 index 00000000000..17c804009de --- /dev/null +++ b/components/script/dom/webidls/XRView.webidl @@ -0,0 +1,17 @@ +/* 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://immersive-web.github.io/webxr/#xrview-interface + +enum XREye { + "left", + "right" +}; + +[SecureContext, Exposed=Window] interface XRView { + // readonly attribute XREye eye; + // readonly attribute Float32Array projectionMatrix; + // readonly attribute Float32Array viewMatrix; + // readonly attribute XRRigidTransform transform; +}; \ No newline at end of file diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs new file mode 100644 index 00000000000..c8f420b016c --- /dev/null +++ b/components/script/dom/xrview.rs @@ -0,0 +1,30 @@ +/* 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::XRViewBinding; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRView { + reflector_: Reflector, +} + +impl XRView { + fn new_inherited() -> XRView { + XRView { + reflector_: Reflector::new(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRView::new_inherited()), + global, + XRViewBinding::Wrap, + ) + } +} From 520bb23048361248c758bb4417d2ba681b861a0e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 16:50:27 -0800 Subject: [PATCH 08/25] Basic XRRigidTransform interface --- components/script/dom/mod.rs | 1 + .../dom/webidls/XRRigidTransform.webidl | 13 ++++++++ components/script/dom/xrrigidtransform.rs | 30 +++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 components/script/dom/webidls/XRRigidTransform.webidl create mode 100644 components/script/dom/xrrigidtransform.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index aae84c5bdd5..3ecb76bba66 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -521,6 +521,7 @@ pub mod xr; pub mod xrframe; pub mod xrlayer; pub mod xrreferencespace; +pub mod xrrigidtransform; pub mod xrsession; pub mod xrspace; pub mod xrstationaryreferencespace; diff --git a/components/script/dom/webidls/XRRigidTransform.webidl b/components/script/dom/webidls/XRRigidTransform.webidl new file mode 100644 index 00000000000..d7ad6ac97b4 --- /dev/null +++ b/components/script/dom/webidls/XRRigidTransform.webidl @@ -0,0 +1,13 @@ +/* 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://immersive-web.github.io/webxr/#xrrigidtransform-interface + +[SecureContext, Exposed=Window] +// [Constructor(optional DOMPointInit position, optional DOMPointInit orientation)] +interface XRRigidTransform { + // readonly attribute DOMPointReadOnly position; + // readonly attribute DOMPointReadOnly orientation; + // readonly attribute Float32Array matrix; +}; \ No newline at end of file diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs new file mode 100644 index 00000000000..b14bb0a02bf --- /dev/null +++ b/components/script/dom/xrrigidtransform.rs @@ -0,0 +1,30 @@ +/* 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::XRRigidTransformBinding; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRRigidTransform { + reflector_: Reflector, +} + +impl XRRigidTransform { + fn new_inherited() -> XRRigidTransform { + XRRigidTransform { + reflector_: Reflector::new(), + } + } + + pub fn new(global: &GlobalScope) -> DomRoot { + reflect_dom_object( + Box::new(XRRigidTransform::new_inherited()), + global, + XRRigidTransformBinding::Wrap, + ) + } +} From d5911816e1bd0bbfc64c33bebce45b117550b16f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 19 Dec 2018 17:33:52 -0800 Subject: [PATCH 09/25] Fill in XR.requestSession --- components/script/dom/navigator.rs | 9 ++- components/script/dom/webidls/XR.webidl | 4 +- .../script/dom/webidls/XRSession.webidl | 6 +- components/script/dom/xr.rs | 69 +++++++++++++++---- components/script/dom/xrsession.rs | 41 +++++++++-- 5 files changed, 104 insertions(+), 25 deletions(-) diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index fccc49aac9d..7ef74da204d 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -4,6 +4,7 @@ use crate::dom::bindings::codegen::Bindings::NavigatorBinding; 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; @@ -148,7 +149,13 @@ impl NavigatorMethods for Navigator { // https://w3c.github.io/webvr/spec/1.1/#navigator-getvrdisplays-attribute #[allow(unrooted_must_root)] fn GetVRDisplays(&self) -> Rc { - self.Xr().get_displays() + let promise = Promise::new(&self.global()); + let displays = self.Xr().get_displays(); + match displays { + Ok(displays) => promise.resolve_native(&displays), + Err(e) => promise.reject_error(Error::Security), + } + promise } fn Xr(&self) -> DomRoot { diff --git a/components/script/dom/webidls/XR.webidl b/components/script/dom/webidls/XR.webidl index 9c973c39f6f..435558aa5e8 100644 --- a/components/script/dom/webidls/XR.webidl +++ b/components/script/dom/webidls/XR.webidl @@ -6,8 +6,8 @@ [SecureContext, Exposed=Window] interface XR: EventTarget { // Methods - // Promise supportsSessionMode(XRSessionMode mode); - // Promise requestSession(optional XRSessionCreationOptions parameters); + Promise supportsSessionMode(XRSessionMode mode); + Promise requestSession(optional XRSessionCreationOptions parameters); // Events // attribute EventHandler ondevicechange; diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index d18b6e18a16..4945880697a 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -12,12 +12,12 @@ enum XREnvironmentBlendMode { [SecureContext, Exposed=Window] interface XRSession : EventTarget { // // Attributes - // readonly attribute XRSessionMode mode; + readonly attribute XRSessionMode mode; // readonly attribute XRPresentationContext outputContext; // readonly attribute XREnvironmentBlendMode environmentBlendMode; - // attribute double depthNear; - // attribute double depthFar; + attribute double depthNear; + attribute double depthFar; // attribute XRLayer baseLayer; // // Methods diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index e64be23663e..d5571ac60c7 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -5,6 +5,8 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods; use crate::dom::bindings::codegen::Bindings::XRBinding; +use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionCreationOptions; +use crate::dom::bindings::codegen::Bindings::XRBinding::{XRMethods, XRSessionMode}; use crate::dom::bindings::error::Error; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; @@ -17,6 +19,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::dom::vrdisplay::VRDisplay; use crate::dom::vrdisplayevent::VRDisplayEvent; +use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; use ipc_channel::ipc::IpcSender; use profile_traits::ipc; @@ -53,15 +56,59 @@ impl Drop for XR { } } +impl XRMethods for XR { + #[allow(unrooted_must_root)] + fn SupportsSessionMode(&self, mode: XRSessionMode) -> Rc { + // XXXManishearth this should select an XR device first + let promise = Promise::new(&self.global()); + if mode == XRSessionMode::Immersive_vr { + promise.resolve_native(&()); + } else { + // XXXManishearth support other modes + promise.reject_error(Error::NotSupported); + } + + promise + } + + #[allow(unrooted_must_root)] + fn RequestSession(&self, options: &XRSessionCreationOptions) -> Rc { + let promise = Promise::new(&self.global()); + if options.mode != XRSessionMode::Immersive_vr { + promise.reject_error(Error::NotSupported); + return promise; + } + + let displays = self.get_displays(); + + let displays = match displays { + Ok(d) => d, + Err(_) => { + promise.reject_native(&()); + return promise; + }, + }; + + if displays.is_empty() { + promise.reject_error(Error::Security); + } + + let session = XRSession::new(&self.global(), &displays[0]); + promise.resolve_native(&session); + + promise + } +} + impl XR { #[allow(unrooted_must_root)] - pub fn get_displays(&self) -> Rc { - let promise = Promise::new(&self.global()); - + pub fn get_displays(&self) -> Result>, ()> { if let Some(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 @@ -69,27 +116,19 @@ impl XR { self.sync_display(&display); } }, - Err(e) => { - promise.reject_native(&e); - return promise; - }, + Err(e) => return Err(()), } } else { // WebVR spec: The Promise MUST be rejected if WebVR is not enabled/supported. - promise.reject_error(Error::Security); - return promise; + return Err(()); } // convert from Dom to DomRoot - let displays: Vec> = self - .displays + Ok(self.displays .borrow() .iter() .map(|d| DomRoot::from_ref(&**d)) - .collect(); - promise.resolve_native(&displays); - - promise + .collect()) } fn webvr_thread(&self) -> Option> { diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index b0ebe383ae7..bbb4626b5e8 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -2,30 +2,63 @@ * 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::XRBinding::XRSessionMode; use crate::dom::bindings::codegen::Bindings::XRSessionBinding; +use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; +use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::vrdisplay::VRDisplay; use dom_struct::dom_struct; +use std::cell::Cell; #[dom_struct] pub struct XRSession { eventtarget: EventTarget, + display: Dom, + depth_near: Cell, + depth_far: Cell, } impl XRSession { - fn new_inherited() -> XRSession { + fn new_inherited(display: &VRDisplay) -> XRSession { XRSession { eventtarget: EventTarget::new_inherited(), + display: Dom::from_ref(display), + depth_near: Cell::new(0.1), + depth_far: Cell::new(1000.), } } - pub fn new(global: &GlobalScope) -> DomRoot { + pub fn new(global: &GlobalScope, display: &VRDisplay) -> DomRoot { reflect_dom_object( - Box::new(XRSession::new_inherited()), + Box::new(XRSession::new_inherited(display)), global, XRSessionBinding::Wrap, ) } } + +impl XRSessionMethods for XRSession { + fn DepthNear(&self) -> Finite { + Finite::wrap(self.depth_near.get()) + } + + fn DepthFar(&self) -> Finite { + Finite::wrap(self.depth_far.get()) + } + + fn SetDepthNear(&self, d: Finite) { + self.depth_near.set(*d) + } + + fn SetDepthFar(&self, d: Finite) { + self.depth_far.set(*d) + } + + fn Mode(&self) -> XRSessionMode { + XRSessionMode::Immersive_vr + } +} From 682c89a18cd5f370362a4f80a19ae0114c2c451c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 20 Dec 2018 15:44:26 -0800 Subject: [PATCH 10/25] allow setting base layer --- components/script/dom/vrdisplay.rs | 7 +++++-- components/script/dom/webidls/XRSession.webidl | 2 +- components/script/dom/xrsession.rs | 13 ++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 9785106c252..152601c4f71 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -74,6 +74,8 @@ pub struct VRDisplay { running_display_raf: Cell, paused: Cell, stopped_on_pause: Cell, + /// Whether or not this is XR mode + xr: Cell, } unsafe_no_jsmanaged_fields!(WebVRDisplayData); @@ -129,6 +131,7 @@ impl VRDisplay { // 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), + xr: Cell::new(false), } } @@ -551,8 +554,8 @@ impl VRDisplay { let this = address.clone(); let sender = raf_sender.clone(); let task = Box::new(task!(handle_vrdisplay_raf: move || { - this.root().handle_raf(&sender); - })); + 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 diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index 4945880697a..b0785764a18 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -18,7 +18,7 @@ enum XREnvironmentBlendMode { attribute double depthNear; attribute double depthFar; - // attribute XRLayer baseLayer; + attribute XRLayer? baseLayer; // // Methods // Promise requestReferenceSpace(XRReferenceSpaceType type, optional XRReferenceSpaceOptions options); diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index bbb4626b5e8..40ccb90fbd3 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -7,10 +7,11 @@ use crate::dom::bindings::codegen::Bindings::XRSessionBinding; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::vrdisplay::VRDisplay; +use crate::dom::xrlayer::XRLayer; use dom_struct::dom_struct; use std::cell::Cell; @@ -20,6 +21,7 @@ pub struct XRSession { display: Dom, depth_near: Cell, depth_far: Cell, + base_layer: MutNullableDom, } impl XRSession { @@ -29,6 +31,7 @@ impl XRSession { display: Dom::from_ref(display), depth_near: Cell::new(0.1), depth_far: Cell::new(1000.), + base_layer: Default::default(), } } @@ -61,4 +64,12 @@ impl XRSessionMethods for XRSession { fn Mode(&self) -> XRSessionMode { XRSessionMode::Immersive_vr } + + fn SetBaseLayer(&self, layer: Option<&XRLayer>) { + self.base_layer.set(layer) + } + + fn GetBaseLayer(&self) -> Option> { + self.base_layer.get() + } } From 70e8a1920011de2ef697bb7d3fff127e263703da Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 20 Dec 2018 16:49:14 -0800 Subject: [PATCH 11/25] Fill in some of XRWebGLLayer --- .../script/dom/webidls/XRWebGLLayer.webidl | 25 ++++---- components/script/dom/xrwebgllayer.rs | 61 +++++++++++++++++-- 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/components/script/dom/webidls/XRWebGLLayer.webidl b/components/script/dom/webidls/XRWebGLLayer.webidl index 7a9bddf1687..8f66ac625d9 100644 --- a/components/script/dom/webidls/XRWebGLLayer.webidl +++ b/components/script/dom/webidls/XRWebGLLayer.webidl @@ -4,29 +4,30 @@ // https://immersive-web.github.io/webxr/#xrwebgllayer-interface -typedef (WebGLRenderingContext or - WebGL2RenderingContext) XRWebGLRenderingContext; +// typedef (WebGLRenderingContext or +// WebGL2RenderingContext) XRWebGLRenderingContext; + +typedef WebGLRenderingContext XRWebGLRenderingContext; dictionary XRWebGLLayerInit { boolean antialias = true; boolean depth = true; boolean stencil = false; boolean alpha = true; - double framebufferScaleFactor = 1.0; + // double framebufferScaleFactor = 1.0; }; -[SecureContext, Exposed=Window] -// [Constructor(XRSession session, -// XRWebGLRenderingContext context, -// optional XRWebGLLayerInit layerInit)] +[SecureContext, Exposed=Window, Constructor(XRSession session, + XRWebGLRenderingContext context, + optional XRWebGLLayerInit layerInit)] interface XRWebGLLayer : XRLayer { // // Attributes - // readonly attribute XRWebGLRenderingContext context; + readonly attribute XRWebGLRenderingContext context; - // readonly attribute boolean antialias; - // readonly attribute boolean depth; - // readonly attribute boolean stencil; - // readonly attribute boolean alpha; + readonly attribute boolean antialias; + readonly attribute boolean depth; + readonly attribute boolean stencil; + readonly attribute boolean alpha; // readonly attribute WebGLFramebuffer framebuffer; // readonly attribute unsigned long framebufferWidth; diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs index 2c550c4fef4..a34e6913d9e 100644 --- a/components/script/dom/xrwebgllayer.rs +++ b/components/script/dom/xrwebgllayer.rs @@ -3,29 +3,80 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding; -use crate::dom::bindings::reflector::reflect_dom_object; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerInit; +use crate::dom::bindings::error::Fallible; +use crate::dom::bindings::reflector::{DomObject, reflect_dom_object}; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::window::Window; use crate::dom::xrlayer::XRLayer; +use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; +use std::cell::Cell; + #[dom_struct] pub struct XRWebGLLayer { xrlayer: XRLayer, + antialias: Cell, + depth: Cell, + stencil: Cell, + alpha: Cell, + context: Dom, + session: Dom, } impl XRWebGLLayer { - pub fn new_inherited() -> XRWebGLLayer { + pub fn new_inherited(session: &XRSession, context: &WebGLRenderingContext, + init: &XRWebGLLayerInit) -> XRWebGLLayer { XRWebGLLayer { xrlayer: XRLayer::new_inherited(), + antialias: Cell::new(init.antialias), + depth: Cell::new(init.depth), + stencil: Cell::new(init.stencil), + alpha: Cell::new(init.alpha), + context: Dom::from_ref(context), + session: Dom::from_ref(session), } } - pub fn new(global: &GlobalScope) -> DomRoot { + pub fn new(global: &GlobalScope, session: &XRSession, context: &WebGLRenderingContext, + init: &XRWebGLLayerInit) -> DomRoot { reflect_dom_object( - Box::new(XRWebGLLayer::new_inherited()), + Box::new(XRWebGLLayer::new_inherited(session, context, init)), global, XRWebGLLayerBinding::Wrap, ) } + + pub fn Constructor(global: &Window, session: &XRSession, + context: &WebGLRenderingContext, + init: &XRWebGLLayerInit) -> Fallible> { + Ok(XRWebGLLayer::new(&global.global(), session, context, init)) + } } + +impl XRWebGLLayerMethods for XRWebGLLayer { + fn Depth(&self) -> bool { + self.depth.get() + } + + fn Stencil(&self) -> bool { + self.stencil.get() + } + + fn Antialias(&self) -> bool { + self.antialias.get() + } + + fn Alpha(&self) -> bool { + self.alpha.get() + } + + fn Context(&self) -> DomRoot { + DomRoot::from_ref(&self.context) + } +} + From e259ff727ee815cbd3d4d87fbd2e17564f9c9e3d Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 20 Dec 2018 15:57:52 -0800 Subject: [PATCH 12/25] Simple presentation --- components/script/dom/vrdisplay.rs | 29 +++++++++++++++++++++++++++++ components/script/dom/xr.rs | 3 +++ components/script/dom/xrsession.rs | 12 +++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 152601c4f71..bd7b68f0154 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -664,6 +664,35 @@ impl VRDisplay { } } +// XR stuff +// XXXManishearth eventually we should share as much logic as possible +impl VRDisplay { + pub fn xr_present(&self, ctx: &WebGLRenderingContext) { + let layer_bounds = WebVRLayer::default(); + self.xr.set(true); + if self.presenting.get() { + *self.layer.borrow_mut() = layer_bounds; + self.layer_ctx.set(Some(&ctx)); + return; + } + + // 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(); + + if let Ok(()) = receiver.recv().unwrap() { + *self.layer.borrow_mut() = layer_bounds; + self.layer_ctx.set(Some(&ctx)); + self.init_present(); + } + } +} + // 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>>, dst: &mut [f32; 4]) -> Result<(), &'static str> { diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index d5571ac60c7..37154c34c6b 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -89,12 +89,15 @@ impl XRMethods for XR { }, }; + // XXXManishearth filter for displays which can_present if displays.is_empty() { promise.reject_error(Error::Security); } let session = XRSession::new(&self.global(), &displays[0]); promise.resolve_native(&session); + // whether or not we should initiate presentation is unclear + // https://github.com/immersive-web/webxr/issues/453 promise } diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 40ccb90fbd3..c652b80a3f9 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -5,6 +5,8 @@ use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode; use crate::dom::bindings::codegen::Bindings::XRSessionBinding; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; +use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; @@ -12,6 +14,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::vrdisplay::VRDisplay; use crate::dom::xrlayer::XRLayer; +use crate::dom::xrwebgllayer::XRWebGLLayer; use dom_struct::dom_struct; use std::cell::Cell; @@ -66,7 +69,14 @@ impl XRSessionMethods for XRSession { } fn SetBaseLayer(&self, layer: Option<&XRLayer>) { - self.base_layer.set(layer) + self.base_layer.set(layer); + if let Some(layer) = layer { + let layer = layer.downcast::().unwrap(); + self.display.xr_present(&layer.Context()); + } else { + // steps unknown + // https://github.com/immersive-web/webxr/issues/453 + } } fn GetBaseLayer(&self) -> Option> { From 7e043a33f17c5a084bb6e34ab3497932a285028a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 21 Dec 2018 14:26:11 -0800 Subject: [PATCH 13/25] Support fetching viewport info --- components/script/dom/mod.rs | 1 + .../script/dom/webglrenderingcontext.rs | 7 +++ .../script/dom/webidls/XRSession.webidl | 2 + components/script/dom/webidls/XRView.webidl | 2 +- .../script/dom/webidls/XRViewport.webidl | 12 ++++ .../script/dom/webidls/XRWebGLLayer.webidl | 2 +- components/script/dom/xrview.rs | 25 ++++++-- components/script/dom/xrviewport.rs | 59 +++++++++++++++++++ components/script/dom/xrwebgllayer.rs | 21 +++++++ 9 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 components/script/dom/webidls/XRViewport.webidl create mode 100644 components/script/dom/xrviewport.rs diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 3ecb76bba66..253dc2b54bb 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -527,4 +527,5 @@ pub mod xrspace; pub mod xrstationaryreferencespace; pub mod xrview; pub mod xrviewerpose; +pub mod xrviewport; pub mod xrwebgllayer; diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index c7896b42436..376da84486d 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -157,6 +157,7 @@ pub struct WebGLRenderingContext { current_scissor: Cell<(i32, i32, u32, u32)>, #[ignore_malloc_size_of = "Because it's small"] current_clear_color: Cell<(f32, f32, f32, f32)>, + size: Cell>, extension_manager: WebGLExtensions, capabilities: Capabilities, default_vao: DomOnceCell, @@ -211,6 +212,7 @@ impl WebGLRenderingContext { current_program: MutNullableDom::new(None), current_vertex_attrib_0: Cell::new((0f32, 0f32, 0f32, 1f32)), current_scissor: Cell::new((0, 0, size.width, size.height)), + size: Cell::new(size), current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0)), extension_manager: WebGLExtensions::new(webgl_version), capabilities: Default::default(), @@ -266,6 +268,7 @@ impl WebGLRenderingContext { pub fn recreate(&self, size: Size2D) { let (sender, receiver) = webgl_channel().unwrap(); self.webgl_sender.send_resize(size, sender).unwrap(); + self.size.set(size); if let Err(msg) = receiver.recv().unwrap() { error!("Error resizing WebGLContext: {}", msg); @@ -340,6 +343,10 @@ impl WebGLRenderingContext { } } + pub fn size(&self) -> Size2D { + self.size.get() + } + // Helper function for validating framebuffer completeness in // calls touching the framebuffer. From the GLES 2.0.25 spec, // page 119: diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index b0785764a18..546a7dcab2f 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -10,6 +10,8 @@ enum XREnvironmentBlendMode { "alpha-blend", }; +callback XRFrameRequestCallback = void (DOMHighResTimeStamp time, XRFrame frame); + [SecureContext, Exposed=Window] interface XRSession : EventTarget { // // Attributes readonly attribute XRSessionMode mode; diff --git a/components/script/dom/webidls/XRView.webidl b/components/script/dom/webidls/XRView.webidl index 17c804009de..9d0c894f8a3 100644 --- a/components/script/dom/webidls/XRView.webidl +++ b/components/script/dom/webidls/XRView.webidl @@ -10,7 +10,7 @@ enum XREye { }; [SecureContext, Exposed=Window] interface XRView { - // readonly attribute XREye eye; + readonly attribute XREye eye; // readonly attribute Float32Array projectionMatrix; // readonly attribute Float32Array viewMatrix; // readonly attribute XRRigidTransform transform; diff --git a/components/script/dom/webidls/XRViewport.webidl b/components/script/dom/webidls/XRViewport.webidl new file mode 100644 index 00000000000..fb68099fa86 --- /dev/null +++ b/components/script/dom/webidls/XRViewport.webidl @@ -0,0 +1,12 @@ +/* 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://immersive-web.github.io/webxr/#xrviewport-interface + +[SecureContext, Exposed=Window] interface XRViewport { + readonly attribute long x; + readonly attribute long y; + readonly attribute long width; + readonly attribute long height; +}; \ No newline at end of file diff --git a/components/script/dom/webidls/XRWebGLLayer.webidl b/components/script/dom/webidls/XRWebGLLayer.webidl index 8f66ac625d9..9f208ddc5f9 100644 --- a/components/script/dom/webidls/XRWebGLLayer.webidl +++ b/components/script/dom/webidls/XRWebGLLayer.webidl @@ -34,7 +34,7 @@ interface XRWebGLLayer : XRLayer { // readonly attribute unsigned long framebufferHeight; // // Methods - // XRViewport? getViewport(XRView view); + XRViewport? getViewport(XRView view); // void requestViewportScaling(double viewportScaleFactor); // // Static Methods diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index c8f420b016c..f9d538cb946 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -3,28 +3,45 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::XRViewBinding; +use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; +use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; #[dom_struct] pub struct XRView { reflector_: Reflector, + session: Dom, + eye: XREye, } impl XRView { - fn new_inherited() -> XRView { + fn new_inherited(session: &XRSession, eye: XREye) -> XRView { XRView { reflector_: Reflector::new(), + session: Dom::from_ref(session), + eye } } - pub fn new(global: &GlobalScope) -> DomRoot { + pub fn new(global: &GlobalScope, session: &XRSession, eye: XREye) -> DomRoot { reflect_dom_object( - Box::new(XRView::new_inherited()), + Box::new(XRView::new_inherited(session, eye)), global, XRViewBinding::Wrap, ) } + + pub fn session(&self) -> &XRSession { + &self.session + } } + +impl XRViewMethods for XRView { + /// https://immersive-web.github.io/webxr/#dom-xrview-eye + fn Eye(&self) -> XREye { + self.eye + } +} \ No newline at end of file diff --git a/components/script/dom/xrviewport.rs b/components/script/dom/xrviewport.rs new file mode 100644 index 00000000000..a49aaf3bf2f --- /dev/null +++ b/components/script/dom/xrviewport.rs @@ -0,0 +1,59 @@ +/* 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::XRViewportBinding; +use crate::dom::bindings::codegen::Bindings::XRViewportBinding::XRViewportMethods; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct XRViewport { + reflector_: Reflector, + x: u32, + y: u32, + width: u32, + height: u32, +} + +impl XRViewport { + fn new_inherited(x: u32, y: u32, width: u32, height: u32) -> XRViewport { + XRViewport { + reflector_: Reflector::new(), + x, y, width, height + } + } + + pub fn new(global: &GlobalScope, + x: u32, y: u32, width: u32, height: u32) -> DomRoot { + reflect_dom_object( + Box::new(XRViewport::new_inherited(x, y, width, height)), + global, + XRViewportBinding::Wrap, + ) + } +} + +impl XRViewportMethods for XRViewport { + /// https://immersive-web.github.io/webxr/#dom-xrviewport-x + fn X(&self) -> i32 { + self.x as i32 + } + + /// https://immersive-web.github.io/webxr/#dom-xrviewport-y + fn Y(&self) -> i32 { + self.y as i32 + } + + /// https://immersive-web.github.io/webxr/#dom-xrviewport-width + fn Width(&self) -> i32 { + self.height as i32 + } + + /// https://immersive-web.github.io/webxr/#dom-xrviewport-height + fn Height(&self) -> i32 { + self.height as i32 + } +} \ No newline at end of file diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs index a34e6913d9e..3aef06642ce 100644 --- a/components/script/dom/xrwebgllayer.rs +++ b/components/script/dom/xrwebgllayer.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerInit; @@ -13,6 +14,8 @@ use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::window::Window; use crate::dom::xrlayer::XRLayer; use crate::dom::xrsession::XRSession; +use crate::dom::xrview::XRView; +use crate::dom::xrviewport::XRViewport; use dom_struct::dom_struct; use std::cell::Cell; @@ -78,5 +81,23 @@ impl XRWebGLLayerMethods for XRWebGLLayer { fn Context(&self) -> DomRoot { DomRoot::from_ref(&self.context) } + + fn GetViewport(&self, view: &XRView) -> Option> { + if self.session != view.session() { + return None; + } + + let size = self.context.size(); + + let x = if view.Eye() == XREye::Left { + 0 + } else { + size.width / 2 + }; + // XXXManishearth this assumes the WebVR default of canvases being cut in half + // which need not be generally true for all devices, and will not work in + // inline VR mode + Some(XRViewport::new(&self.global(), x, 0, size.width / 2, size.height)) + } } From 28dff81dbf3f24ae470e1a0004f0813a3247e08f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 21 Dec 2018 15:20:51 -0800 Subject: [PATCH 14/25] Fill in XR frame/pose/view implementations --- components/script/dom/navigator.rs | 2 +- components/script/dom/vrdisplay.rs | 3 +- components/script/dom/vrframedata.rs | 3 +- components/script/dom/webidls/XRFrame.webidl | 4 +- components/script/dom/webidls/XRView.webidl | 4 +- .../script/dom/webidls/XRViewerPose.webidl | 2 + components/script/dom/xr.rs | 5 +- components/script/dom/xrframe.rs | 45 ++++++++++++++++-- components/script/dom/xrview.rs | 46 +++++++++++++++++-- components/script/dom/xrviewerpose.rs | 23 ++++++++-- components/script/dom/xrviewport.rs | 16 +++++-- components/script/dom/xrwebgllayer.rs | 37 ++++++++++----- 12 files changed, 152 insertions(+), 38 deletions(-) diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 7ef74da204d..0253bb306f0 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -153,7 +153,7 @@ impl NavigatorMethods for Navigator { let displays = self.Xr().get_displays(); match displays { Ok(displays) => promise.resolve_native(&displays), - Err(e) => promise.reject_error(Error::Security), + Err(_) => promise.reject_error(Error::Security), } promise } diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index bd7b68f0154..39bea7170dc 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -683,7 +683,8 @@ impl VRDisplay { self.global().pipeline_id(), self.display.borrow().display_id, sender, - )).unwrap(); + )) + .unwrap(); if let Ok(()) = receiver.recv().unwrap() { *self.layer.borrow_mut() = layer_bounds; diff --git a/components/script/dom/vrframedata.rs b/components/script/dom/vrframedata.rs index 2ae20323d02..ebd0c8cc24f 100644 --- a/components/script/dom/vrframedata.rs +++ b/components/script/dom/vrframedata.rs @@ -71,8 +71,9 @@ impl VRFrameData { } } +/// FIXME(#22526) this should be in a better place #[allow(unsafe_code)] -fn create_typed_array(cx: *mut JSContext, src: &[f32], dst: &Heap<*mut JSObject>) { +pub fn create_typed_array(cx: *mut JSContext, src: &[f32], dst: &Heap<*mut JSObject>) { rooted!(in (cx) let mut array = ptr::null_mut::()); unsafe { let _ = Float32Array::create(cx, CreateWith::Slice(src), array.handle_mut()); diff --git a/components/script/dom/webidls/XRFrame.webidl b/components/script/dom/webidls/XRFrame.webidl index e35f8a44bf0..b490c104800 100644 --- a/components/script/dom/webidls/XRFrame.webidl +++ b/components/script/dom/webidls/XRFrame.webidl @@ -5,8 +5,8 @@ // https://immersive-web.github.io/webxr/#xrframe-interface [SecureContext, Exposed=Window] interface XRFrame { - // readonly attribute XRSession session; + readonly attribute XRSession session; - // XRViewerPose? getViewerPose(optional XRReferenceSpace referenceSpace); + XRViewerPose? getViewerPose(optional XRReferenceSpace referenceSpace); // XRInputPose? getInputPose(XRInputSource inputSource, optional XRReferenceSpace referenceSpace); }; \ No newline at end of file diff --git a/components/script/dom/webidls/XRView.webidl b/components/script/dom/webidls/XRView.webidl index 9d0c894f8a3..07827d69118 100644 --- a/components/script/dom/webidls/XRView.webidl +++ b/components/script/dom/webidls/XRView.webidl @@ -11,7 +11,7 @@ enum XREye { [SecureContext, Exposed=Window] interface XRView { readonly attribute XREye eye; - // readonly attribute Float32Array projectionMatrix; - // readonly attribute Float32Array viewMatrix; + readonly attribute Float32Array projectionMatrix; + readonly attribute Float32Array viewMatrix; // readonly attribute XRRigidTransform transform; }; \ No newline at end of file diff --git a/components/script/dom/webidls/XRViewerPose.webidl b/components/script/dom/webidls/XRViewerPose.webidl index ff87930e320..356d7f0d906 100644 --- a/components/script/dom/webidls/XRViewerPose.webidl +++ b/components/script/dom/webidls/XRViewerPose.webidl @@ -7,4 +7,6 @@ [SecureContext, Exposed=Window] interface XRViewerPose { // readonly attribute XRRigidTransform transform; // readonly attribute FrozenArray views; + // workaround until we have FrozenArray + sequence views(); }; \ No newline at end of file diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index 37154c34c6b..3f1e963666c 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -119,7 +119,7 @@ impl XR { self.sync_display(&display); } }, - Err(e) => return Err(()), + Err(_) => return Err(()), } } else { // WebVR spec: The Promise MUST be rejected if WebVR is not enabled/supported. @@ -127,7 +127,8 @@ impl XR { } // convert from Dom to DomRoot - Ok(self.displays + Ok(self + .displays .borrow() .iter() .map(|d| DomRoot::from_ref(&**d)) diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs index b7b8f7e0964..2430c1a3812 100644 --- a/components/script/dom/xrframe.rs +++ b/components/script/dom/xrframe.rs @@ -3,28 +3,63 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::XRFrameBinding; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::codegen::Bindings::XRFrameBinding::XRFrameMethods; +use crate::dom::bindings::codegen::Bindings::XRViewBinding::XREye; +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::xrreferencespace::XRReferenceSpace; +use crate::dom::xrsession::XRSession; +use crate::dom::xrview::XRView; +use crate::dom::xrviewerpose::XRViewerPose; use dom_struct::dom_struct; +use webvr_traits::WebVRFrameData; #[dom_struct] pub struct XRFrame { reflector_: Reflector, + session: Dom, + #[ignore_malloc_size_of = "defined in rust-webvr"] + data: WebVRFrameData, } impl XRFrame { - fn new_inherited() -> XRFrame { + fn new_inherited(session: &XRSession, data: WebVRFrameData) -> XRFrame { XRFrame { reflector_: Reflector::new(), + session: Dom::from_ref(session), + data, } } - pub fn new(global: &GlobalScope) -> DomRoot { + pub fn new( + global: &GlobalScope, + session: &XRSession, + data: WebVRFrameData, + ) -> DomRoot { reflect_dom_object( - Box::new(XRFrame::new_inherited()), + Box::new(XRFrame::new_inherited(session, data)), global, XRFrameBinding::Wrap, ) } } + +impl XRFrameMethods for XRFrame { + fn Session(&self) -> DomRoot { + DomRoot::from_ref(&self.session) + } + + fn GetViewerPose(&self, reference: Option<&XRReferenceSpace>) -> Option> { + // We assume the reference space is eye level for now + // since it's the only one 3DOF devices support + if reference.is_some() { + // it's not possible to obtain a reference + // space at all yet + return None; + } + let left = XRView::new(&self.global(), &self.session, XREye::Left, &self.data); + let right = XRView::new(&self.global(), &self.session, XREye::Right, &self.data); + Some(XRViewerPose::new(&self.global(), &left, &right)) + } +} diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index f9d538cb946..5fd7dfcae2e 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -7,14 +7,20 @@ use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethod use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; +use crate::dom::vrframedata::create_typed_array; use crate::dom::xrsession::XRSession; use dom_struct::dom_struct; +use js::jsapi::{Heap, JSContext, JSObject}; +use std::ptr::NonNull; +use webvr_traits::WebVRFrameData; #[dom_struct] pub struct XRView { reflector_: Reflector, session: Dom, eye: XREye, + proj: Heap<*mut JSObject>, + view: Heap<*mut JSObject>, } impl XRView { @@ -22,16 +28,34 @@ impl XRView { XRView { reflector_: Reflector::new(), session: Dom::from_ref(session), - eye + eye, + proj: Heap::default(), + view: Heap::default(), } } - pub fn new(global: &GlobalScope, session: &XRSession, eye: XREye) -> DomRoot { - reflect_dom_object( + pub fn new( + global: &GlobalScope, + session: &XRSession, + eye: XREye, + data: &WebVRFrameData, + ) -> DomRoot { + let ret = reflect_dom_object( Box::new(XRView::new_inherited(session, eye)), global, XRViewBinding::Wrap, - ) + ); + + let (proj, view) = if eye == XREye::Left { + (&data.left_projection_matrix, &data.left_view_matrix) + } else { + (&data.right_projection_matrix, &data.right_view_matrix) + }; + + let cx = global.get_cx(); + create_typed_array(cx, proj, &ret.proj); + create_typed_array(cx, view, &ret.view); + ret } pub fn session(&self) -> &XRSession { @@ -44,4 +68,16 @@ impl XRViewMethods for XRView { fn Eye(&self) -> XREye { self.eye } -} \ No newline at end of file + + #[allow(unsafe_code)] + /// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix + unsafe fn ProjectionMatrix(&self, _cx: *mut JSContext) -> NonNull { + NonNull::new_unchecked(self.proj.get()) + } + + #[allow(unsafe_code)] + /// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix + unsafe fn ViewMatrix(&self, _cx: *mut JSContext) -> NonNull { + NonNull::new_unchecked(self.view.get()) + } +} diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs index 9fc06c671dd..258308a211b 100644 --- a/components/script/dom/xrviewerpose.rs +++ b/components/script/dom/xrviewerpose.rs @@ -3,28 +3,43 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding; +use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding::XRViewerPoseMethods; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; +use crate::dom::xrview::XRView; use dom_struct::dom_struct; #[dom_struct] pub struct XRViewerPose { reflector_: Reflector, + left: Dom, + right: Dom, } impl XRViewerPose { - fn new_inherited() -> XRViewerPose { + fn new_inherited(left: &XRView, right: &XRView) -> XRViewerPose { XRViewerPose { reflector_: Reflector::new(), + left: Dom::from_ref(left), + right: Dom::from_ref(right), } } - pub fn new(global: &GlobalScope) -> DomRoot { + pub fn new(global: &GlobalScope, left: &XRView, right: &XRView) -> DomRoot { reflect_dom_object( - Box::new(XRViewerPose::new_inherited()), + Box::new(XRViewerPose::new_inherited(left, right)), global, XRViewerPoseBinding::Wrap, ) } } + +impl XRViewerPoseMethods for XRViewerPose { + fn Views(&self) -> Vec> { + vec![ + DomRoot::from_ref(&self.left), + DomRoot::from_ref(&self.right), + ] + } +} diff --git a/components/script/dom/xrviewport.rs b/components/script/dom/xrviewport.rs index a49aaf3bf2f..f540558a527 100644 --- a/components/script/dom/xrviewport.rs +++ b/components/script/dom/xrviewport.rs @@ -22,12 +22,20 @@ impl XRViewport { fn new_inherited(x: u32, y: u32, width: u32, height: u32) -> XRViewport { XRViewport { reflector_: Reflector::new(), - x, y, width, height + x, + y, + width, + height, } } - pub fn new(global: &GlobalScope, - x: u32, y: u32, width: u32, height: u32) -> DomRoot { + pub fn new( + global: &GlobalScope, + x: u32, + y: u32, + width: u32, + height: u32, + ) -> DomRoot { reflect_dom_object( Box::new(XRViewport::new_inherited(x, y, width, height)), global, @@ -56,4 +64,4 @@ impl XRViewportMethods for XRViewport { fn Height(&self) -> i32 { self.height as i32 } -} \ No newline at end of file +} diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs index 3aef06642ce..c9b6377e879 100644 --- a/components/script/dom/xrwebgllayer.rs +++ b/components/script/dom/xrwebgllayer.rs @@ -4,10 +4,10 @@ use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding; -use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerInit; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; use crate::dom::bindings::error::Fallible; -use crate::dom::bindings::reflector::{DomObject, reflect_dom_object}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::dom::webglrenderingcontext::WebGLRenderingContext; @@ -32,8 +32,11 @@ pub struct XRWebGLLayer { } impl XRWebGLLayer { - pub fn new_inherited(session: &XRSession, context: &WebGLRenderingContext, - init: &XRWebGLLayerInit) -> XRWebGLLayer { + pub fn new_inherited( + session: &XRSession, + context: &WebGLRenderingContext, + init: &XRWebGLLayerInit, + ) -> XRWebGLLayer { XRWebGLLayer { xrlayer: XRLayer::new_inherited(), antialias: Cell::new(init.antialias), @@ -45,8 +48,12 @@ impl XRWebGLLayer { } } - pub fn new(global: &GlobalScope, session: &XRSession, context: &WebGLRenderingContext, - init: &XRWebGLLayerInit) -> DomRoot { + pub fn new( + global: &GlobalScope, + session: &XRSession, + context: &WebGLRenderingContext, + init: &XRWebGLLayerInit, + ) -> DomRoot { reflect_dom_object( Box::new(XRWebGLLayer::new_inherited(session, context, init)), global, @@ -54,9 +61,12 @@ impl XRWebGLLayer { ) } - pub fn Constructor(global: &Window, session: &XRSession, - context: &WebGLRenderingContext, - init: &XRWebGLLayerInit) -> Fallible> { + pub fn Constructor( + global: &Window, + session: &XRSession, + context: &WebGLRenderingContext, + init: &XRWebGLLayerInit, + ) -> Fallible> { Ok(XRWebGLLayer::new(&global.global(), session, context, init)) } } @@ -97,7 +107,12 @@ impl XRWebGLLayerMethods for XRWebGLLayer { // XXXManishearth this assumes the WebVR default of canvases being cut in half // which need not be generally true for all devices, and will not work in // inline VR mode - Some(XRViewport::new(&self.global(), x, 0, size.width / 2, size.height)) + Some(XRViewport::new( + &self.global(), + x, + 0, + size.width / 2, + size.height, + )) } } - From 1b11a3063c42b67a45432a3bc5b999ac8856d5ee Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 21 Dec 2018 15:49:39 -0800 Subject: [PATCH 15/25] Support attaching RAF callbacks --- components/script/dom/vrdisplay.rs | 24 +++++++++++++++++-- .../script/dom/webidls/XRSession.webidl | 4 ++-- components/script/dom/xrsession.rs | 10 ++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 39bea7170dc..741cdd4818c 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -5,14 +5,15 @@ use canvas_traits::webgl::{webgl_channel, WebGLReceiver, WebVRCommand}; use crate::dom::bindings::callback::ExceptionHandling; use crate::dom::bindings::cell::DomRefCell; -use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceBinding::PerformanceMethods; +use crate::dom::bindings::codegen::Bindings::PerformanceBinding::PerformanceMethods; use crate::dom::bindings::codegen::Bindings::VRDisplayBinding; 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::WindowBinding::WindowMethods; +use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; +use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCallback; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; use crate::dom::bindings::refcounted::Trusted; @@ -67,6 +68,8 @@ pub struct VRDisplay { /// List of request animation frame callbacks #[ignore_malloc_size_of = "closures are hard"] raf_callback_list: DomRefCell>)>>, + #[ignore_malloc_size_of = "closures are hard"] + xr_raf_callback_list: DomRefCell>)>>, // Compositor VRFrameData synchonization frame_data_status: Cell, #[ignore_malloc_size_of = "closures are hard"] @@ -122,6 +125,7 @@ impl VRDisplay { layer_ctx: MutNullableDom::default(), next_raf_id: Cell::new(1), raf_callback_list: DomRefCell::new(vec![]), + xr_raf_callback_list: DomRefCell::new(vec![]), frame_data_status: Cell::new(VRFrameDataStatus::Waiting), frame_data_receiver: DomRefCell::new(None), running_display_raf: Cell::new(false), @@ -692,6 +696,22 @@ impl VRDisplay { self.init_present(); } } + + pub fn xr_raf(&self, callback: Rc) -> u32 { + let raf_id = self.next_raf_id.get(); + self.next_raf_id.set(raf_id + 1); + self.xr_raf_callback_list + .borrow_mut() + .push((raf_id, Some(callback))); + raf_id + } + + pub fn xr_cancel_raf(&self, handle: i32) { + let mut list = self.xr_raf_callback_list.borrow_mut(); + if let Some(pair) = list.iter_mut().find(|pair| pair.0 == handle as u32) { + pair.1 = None; + } + } } // WebVR Spec: If the number of values in the leftBounds/rightBounds arrays diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index 546a7dcab2f..6a3a2e52c1f 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -27,8 +27,8 @@ callback XRFrameRequestCallback = void (DOMHighResTimeStamp time, XRFrame frame) // FrozenArray getInputSources(); - // long requestAnimationFrame(XRFrameRequestCallback callback); - // void cancelAnimationFrame(long handle); + long requestAnimationFrame(XRFrameRequestCallback callback); + void cancelAnimationFrame(long handle); // Promise end(); diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index c652b80a3f9..ac19b825d4c 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -4,6 +4,7 @@ use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode; use crate::dom::bindings::codegen::Bindings::XRSessionBinding; +use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCallback; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; use crate::dom::bindings::inheritance::Castable; @@ -17,6 +18,7 @@ use crate::dom::xrlayer::XRLayer; use crate::dom::xrwebgllayer::XRWebGLLayer; use dom_struct::dom_struct; use std::cell::Cell; +use std::rc::Rc; #[dom_struct] pub struct XRSession { @@ -82,4 +84,12 @@ impl XRSessionMethods for XRSession { fn GetBaseLayer(&self) -> Option> { self.base_layer.get() } + + fn RequestAnimationFrame(&self, callback: Rc) -> i32 { + self.display.xr_raf(callback) as i32 + } + + fn CancelAnimationFrame(&self, frame: i32) { + self.display.xr_cancel_raf(frame) + } } From 4b2fa5ef0868ccdd6360175e60c5cc3ce4a53097 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 21 Dec 2018 16:04:19 -0800 Subject: [PATCH 16/25] Invoke XR RAFs appropriately --- components/script/dom/vrdisplay.rs | 58 ++++++++++++++++++++---------- components/script/dom/xrsession.rs | 2 +- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 741cdd4818c..012f4ccb9fc 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -31,6 +31,8 @@ use crate::dom::vrframedata::VRFrameData; use crate::dom::vrpose::VRPose; use crate::dom::vrstageparameters::VRStageParameters; use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::xrframe::XRFrame; +use crate::dom::xrsession::XRSession; use crate::script_runtime::CommonScriptMsg; use crate::script_runtime::ScriptThreadEventCategory::WebVREvent; use crate::task_source::TaskSourceName; @@ -77,8 +79,8 @@ pub struct VRDisplay { running_display_raf: Cell, paused: Cell, stopped_on_pause: Cell, - /// Whether or not this is XR mode - xr: Cell, + /// Whether or not this is XR mode, and the session + xr_session: MutNullableDom, } unsafe_no_jsmanaged_fields!(WebVRDisplayData); @@ -135,7 +137,7 @@ impl VRDisplay { // 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), - xr: Cell::new(false), + xr_session: MutNullableDom::default(), } } @@ -631,25 +633,43 @@ impl VRDisplay { fn handle_raf(&self, end_sender: &Sender>) { self.frame_data_status.set(VRFrameDataStatus::Waiting); - self.running_display_raf.set(true); + - let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]); let now = self.global().as_window().Performance().Now(); - // Call registered VRDisplay.requestAnimationFrame callbacks. - for (_, callback) in callbacks.drain(..) { - if let Some(callback) = callback { - let _ = callback.Call__(Finite::wrap(*now), ExceptionHandling::Report); + if let Some(session) = self.xr_session.get() { + let mut callbacks = mem::replace(&mut *self.xr_raf_callback_list.borrow_mut(), vec![]); + if callbacks.is_empty() { + return; } - } - - 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(); + let frame = XRFrame::new(&self.global(), &session, self.frame_data.borrow().clone()); + + for (_, callback) in callbacks.drain(..) { + if let Some(callback) = callback { + let _ = callback.Call__(Finite::wrap(*now), &frame, ExceptionHandling::Report); + } + } + // frame submission is automatic in XR + self.SubmitFrame(); + } else { + 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() { @@ -671,9 +691,9 @@ impl VRDisplay { // XR stuff // XXXManishearth eventually we should share as much logic as possible impl VRDisplay { - pub fn xr_present(&self, ctx: &WebGLRenderingContext) { + pub fn xr_present(&self, session: &XRSession, ctx: &WebGLRenderingContext) { let layer_bounds = WebVRLayer::default(); - self.xr.set(true); + self.xr_session.set(Some(session)); if self.presenting.get() { *self.layer.borrow_mut() = layer_bounds; self.layer_ctx.set(Some(&ctx)); diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index ac19b825d4c..3dc4797d3c5 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -74,7 +74,7 @@ impl XRSessionMethods for XRSession { self.base_layer.set(layer); if let Some(layer) = layer { let layer = layer.downcast::().unwrap(); - self.display.xr_present(&layer.Context()); + self.display.xr_present(&self, &layer.Context()); } else { // steps unknown // https://github.com/immersive-web/webxr/issues/453 From 241d93340b2cf375186e3c5b3aaf0ddb2b34501a Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 22 Dec 2018 22:15:41 -0800 Subject: [PATCH 17/25] Add dom.webxr.enabled pref --- components/script/dom/vrdisplay.rs | 1 - components/script/dom/webidls/XR.webidl | 4 ++-- components/script/dom/webidls/XRFrame.webidl | 5 +++-- components/script/dom/webidls/XRLayer.webidl | 3 ++- components/script/dom/webidls/XRReferenceSpace.webidl | 3 ++- components/script/dom/webidls/XRRigidTransform.webidl | 4 ++-- components/script/dom/webidls/XRSession.webidl | 4 ++-- components/script/dom/webidls/XRSpace.webidl | 5 +++-- .../script/dom/webidls/XRStationaryReferenceSpace.webidl | 4 ++-- components/script/dom/webidls/XRView.webidl | 5 +++-- components/script/dom/webidls/XRViewerPose.webidl | 5 +++-- components/script/dom/webidls/XRViewport.webidl | 5 +++-- components/script/dom/webidls/XRWebGLLayer.webidl | 5 +++-- resources/package-prefs.json | 3 ++- 14 files changed, 32 insertions(+), 24 deletions(-) diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 012f4ccb9fc..85fca5db45b 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -633,7 +633,6 @@ impl VRDisplay { fn handle_raf(&self, end_sender: &Sender>) { self.frame_data_status.set(VRFrameDataStatus::Waiting); - let now = self.global().as_window().Performance().Now(); diff --git a/components/script/dom/webidls/XR.webidl b/components/script/dom/webidls/XR.webidl index 435558aa5e8..4a6bca26a69 100644 --- a/components/script/dom/webidls/XR.webidl +++ b/components/script/dom/webidls/XR.webidl @@ -3,7 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ // https://immersive-web.github.io/webxr/#xr-interface -[SecureContext, Exposed=Window] +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XR: EventTarget { // Methods Promise supportsSessionMode(XRSessionMode mode); @@ -15,7 +15,7 @@ interface XR: EventTarget { [SecureContext] partial interface Navigator { - [SameObject, Pref="dom.webvr.enabled"] readonly attribute XR xr; + [SameObject, Pref="dom.webxr.enabled"] readonly attribute XR xr; }; enum XRSessionMode { diff --git a/components/script/dom/webidls/XRFrame.webidl b/components/script/dom/webidls/XRFrame.webidl index b490c104800..6c40306755d 100644 --- a/components/script/dom/webidls/XRFrame.webidl +++ b/components/script/dom/webidls/XRFrame.webidl @@ -4,9 +4,10 @@ // https://immersive-web.github.io/webxr/#xrframe-interface -[SecureContext, Exposed=Window] interface XRFrame { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRFrame { readonly attribute XRSession session; XRViewerPose? getViewerPose(optional XRReferenceSpace referenceSpace); // XRInputPose? getInputPose(XRInputSource inputSource, optional XRReferenceSpace referenceSpace); -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRLayer.webidl b/components/script/dom/webidls/XRLayer.webidl index 829b1436a27..69c65da6143 100644 --- a/components/script/dom/webidls/XRLayer.webidl +++ b/components/script/dom/webidls/XRLayer.webidl @@ -4,4 +4,5 @@ // https://immersive-web.github.io/webxr/#xrlayer-interface -[SecureContext, Exposed=Window] interface XRLayer {}; +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRLayer {}; diff --git a/components/script/dom/webidls/XRReferenceSpace.webidl b/components/script/dom/webidls/XRReferenceSpace.webidl index 5b18050dda2..fdedfe0bb4f 100644 --- a/components/script/dom/webidls/XRReferenceSpace.webidl +++ b/components/script/dom/webidls/XRReferenceSpace.webidl @@ -14,7 +14,8 @@ dictionary XRReferenceSpaceOptions { required XRReferenceSpaceType type; }; -[SecureContext, Exposed=Window] interface XRReferenceSpace : XRSpace { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRReferenceSpace : XRSpace { // attribute XRRigidTransform originOffset; // attribute EventHandler onreset; }; diff --git a/components/script/dom/webidls/XRRigidTransform.webidl b/components/script/dom/webidls/XRRigidTransform.webidl index d7ad6ac97b4..f7ccd0fb188 100644 --- a/components/script/dom/webidls/XRRigidTransform.webidl +++ b/components/script/dom/webidls/XRRigidTransform.webidl @@ -4,10 +4,10 @@ // https://immersive-web.github.io/webxr/#xrrigidtransform-interface -[SecureContext, Exposed=Window] +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] // [Constructor(optional DOMPointInit position, optional DOMPointInit orientation)] interface XRRigidTransform { // readonly attribute DOMPointReadOnly position; // readonly attribute DOMPointReadOnly orientation; // readonly attribute Float32Array matrix; -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index 6a3a2e52c1f..b16e9513e75 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -12,7 +12,7 @@ enum XREnvironmentBlendMode { callback XRFrameRequestCallback = void (DOMHighResTimeStamp time, XRFrame frame); -[SecureContext, Exposed=Window] interface XRSession : EventTarget { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRSession : EventTarget { // // Attributes readonly attribute XRSessionMode mode; // readonly attribute XRPresentationContext outputContext; @@ -40,4 +40,4 @@ callback XRFrameRequestCallback = void (DOMHighResTimeStamp time, XRFrame frame) // attribute EventHandler oninputsourceschange; // attribute EventHandler onselectstart; // attribute EventHandler onselectend; -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRSpace.webidl b/components/script/dom/webidls/XRSpace.webidl index 9ad1d399429..96c07f217a0 100644 --- a/components/script/dom/webidls/XRSpace.webidl +++ b/components/script/dom/webidls/XRSpace.webidl @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -[SecureContext, Exposed=Window] interface XRSpace : EventTarget { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRSpace : EventTarget { // XRRigidTransform? getTransformTo(XRSpace other); -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRStationaryReferenceSpace.webidl b/components/script/dom/webidls/XRStationaryReferenceSpace.webidl index a6b8954b885..3580ac94602 100644 --- a/components/script/dom/webidls/XRStationaryReferenceSpace.webidl +++ b/components/script/dom/webidls/XRStationaryReferenceSpace.webidl @@ -14,7 +14,7 @@ dictionary XRStationaryReferenceSpaceOptions : XRReferenceSpaceOptions { required XRStationaryReferenceSpaceSubtype subtype; }; -[SecureContext, Exposed=Window] +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRStationaryReferenceSpace: XRReferenceSpace { // readonly attribute XRStationaryReferenceSpaceSubtype subtype; -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRView.webidl b/components/script/dom/webidls/XRView.webidl index 07827d69118..ab81136c28d 100644 --- a/components/script/dom/webidls/XRView.webidl +++ b/components/script/dom/webidls/XRView.webidl @@ -9,9 +9,10 @@ enum XREye { "right" }; -[SecureContext, Exposed=Window] interface XRView { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRView { readonly attribute XREye eye; readonly attribute Float32Array projectionMatrix; readonly attribute Float32Array viewMatrix; // readonly attribute XRRigidTransform transform; -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRViewerPose.webidl b/components/script/dom/webidls/XRViewerPose.webidl index 356d7f0d906..caf9f96ba10 100644 --- a/components/script/dom/webidls/XRViewerPose.webidl +++ b/components/script/dom/webidls/XRViewerPose.webidl @@ -4,9 +4,10 @@ // https://immersive-web.github.io/webxr/#xrviewerpose-interface -[SecureContext, Exposed=Window] interface XRViewerPose { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRViewerPose { // readonly attribute XRRigidTransform transform; // readonly attribute FrozenArray views; // workaround until we have FrozenArray sequence views(); -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRViewport.webidl b/components/script/dom/webidls/XRViewport.webidl index fb68099fa86..325b52c9f8f 100644 --- a/components/script/dom/webidls/XRViewport.webidl +++ b/components/script/dom/webidls/XRViewport.webidl @@ -4,9 +4,10 @@ // https://immersive-web.github.io/webxr/#xrviewport-interface -[SecureContext, Exposed=Window] interface XRViewport { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRViewport { readonly attribute long x; readonly attribute long y; readonly attribute long width; readonly attribute long height; -}; \ No newline at end of file +}; diff --git a/components/script/dom/webidls/XRWebGLLayer.webidl b/components/script/dom/webidls/XRWebGLLayer.webidl index 9f208ddc5f9..163bfd24568 100644 --- a/components/script/dom/webidls/XRWebGLLayer.webidl +++ b/components/script/dom/webidls/XRWebGLLayer.webidl @@ -19,7 +19,8 @@ dictionary XRWebGLLayerInit { [SecureContext, Exposed=Window, Constructor(XRSession session, XRWebGLRenderingContext context, - optional XRWebGLLayerInit layerInit)] + optional XRWebGLLayerInit layerInit), + Pref="dom.webxr.enabled"] interface XRWebGLLayer : XRLayer { // // Attributes readonly attribute XRWebGLRenderingContext context; @@ -39,4 +40,4 @@ interface XRWebGLLayer : XRLayer { // // Static Methods // static double getNativeFramebufferScaleFactor(XRSession session); -}; \ No newline at end of file +}; diff --git a/resources/package-prefs.json b/resources/package-prefs.json index 7a64a1f1531..d419d7e4586 100644 --- a/resources/package-prefs.json +++ b/resources/package-prefs.json @@ -7,6 +7,7 @@ "windows": {}, "vr": { "_comment": "settings specific to VR builds", - "dom.webvr.enabled": true + "dom.webvr.enabled": true, + "dom.webxr.enabled": true } } From c6c6b518cbda150e50d2c78e79e537db1c6e6fb7 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 22 Dec 2018 22:23:40 -0800 Subject: [PATCH 18/25] Add spec links --- components/script/dom/navigator.rs | 1 + components/script/dom/webidls/XRSession.webidl | 6 ++++-- components/script/dom/webidls/XRSpace.webidl | 2 ++ components/script/dom/xr.rs | 2 ++ components/script/dom/xrframe.rs | 2 ++ components/script/dom/xrsession.rs | 9 +++++++++ components/script/dom/xrviewerpose.rs | 1 + components/script/dom/xrwebgllayer.rs | 6 ++++++ python/tidy/servo_tidy/tidy.py | 1 + 9 files changed, 28 insertions(+), 2 deletions(-) diff --git a/components/script/dom/navigator.rs b/components/script/dom/navigator.rs index 0253bb306f0..aa49701709a 100644 --- a/components/script/dom/navigator.rs +++ b/components/script/dom/navigator.rs @@ -158,6 +158,7 @@ impl NavigatorMethods for Navigator { promise } + /// https://immersive-web.github.io/webxr/#dom-navigator-xr fn Xr(&self) -> DomRoot { self.xr.or_init(|| XR::new(&self.global())) } diff --git a/components/script/dom/webidls/XRSession.webidl b/components/script/dom/webidls/XRSession.webidl index b16e9513e75..7cf25bf8c36 100644 --- a/components/script/dom/webidls/XRSession.webidl +++ b/components/script/dom/webidls/XRSession.webidl @@ -12,7 +12,8 @@ enum XREnvironmentBlendMode { callback XRFrameRequestCallback = void (DOMHighResTimeStamp time, XRFrame frame); -[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRSession : EventTarget { +[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] +interface XRSession : EventTarget { // // Attributes readonly attribute XRSessionMode mode; // readonly attribute XRPresentationContext outputContext; @@ -23,7 +24,8 @@ callback XRFrameRequestCallback = void (DOMHighResTimeStamp time, XRFrame frame) attribute XRLayer? baseLayer; // // Methods - // Promise requestReferenceSpace(XRReferenceSpaceType type, optional XRReferenceSpaceOptions options); + // Promise requestReferenceSpace(XRReferenceSpaceType type, + // optional XRReferenceSpaceOptions options); // FrozenArray getInputSources(); diff --git a/components/script/dom/webidls/XRSpace.webidl b/components/script/dom/webidls/XRSpace.webidl index 96c07f217a0..54401b051c8 100644 --- a/components/script/dom/webidls/XRSpace.webidl +++ b/components/script/dom/webidls/XRSpace.webidl @@ -2,6 +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/. */ +// https://immersive-web.github.io/webxr/#xrspace-interface + [SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRSpace : EventTarget { // XRRigidTransform? getTransformTo(XRSpace other); diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index 3f1e963666c..b381ef56aa1 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -58,6 +58,7 @@ impl Drop for XR { impl XRMethods for XR { #[allow(unrooted_must_root)] + /// https://immersive-web.github.io/webxr/#dom-xr-supportssessionmode fn SupportsSessionMode(&self, mode: XRSessionMode) -> Rc { // XXXManishearth this should select an XR device first let promise = Promise::new(&self.global()); @@ -72,6 +73,7 @@ impl XRMethods for XR { } #[allow(unrooted_must_root)] + /// https://immersive-web.github.io/webxr/#dom-xr-requestsession fn RequestSession(&self, options: &XRSessionCreationOptions) -> Rc { let promise = Promise::new(&self.global()); if options.mode != XRSessionMode::Immersive_vr { diff --git a/components/script/dom/xrframe.rs b/components/script/dom/xrframe.rs index 2430c1a3812..8343bb76420 100644 --- a/components/script/dom/xrframe.rs +++ b/components/script/dom/xrframe.rs @@ -46,10 +46,12 @@ impl XRFrame { } impl XRFrameMethods for XRFrame { + /// https://immersive-web.github.io/webxr/#dom-xrframe-session fn Session(&self) -> DomRoot { DomRoot::from_ref(&self.session) } + /// https://immersive-web.github.io/webxr/#dom-xrframe-getviewerpose fn GetViewerPose(&self, reference: Option<&XRReferenceSpace>) -> Option> { // We assume the reference space is eye level for now // since it's the only one 3DOF devices support diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 3dc4797d3c5..8432603e4e7 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -50,26 +50,32 @@ impl XRSession { } impl XRSessionMethods for XRSession { + /// https://immersive-web.github.io/webxr/#dom-xrsession-depthnear fn DepthNear(&self) -> Finite { Finite::wrap(self.depth_near.get()) } + /// https://immersive-web.github.io/webxr/#dom-xrsession-depthfar fn DepthFar(&self) -> Finite { Finite::wrap(self.depth_far.get()) } + /// https://immersive-web.github.io/webxr/#dom-xrsession-depthnear fn SetDepthNear(&self, d: Finite) { self.depth_near.set(*d) } + /// https://immersive-web.github.io/webxr/#dom-xrsession-depthfar fn SetDepthFar(&self, d: Finite) { self.depth_far.set(*d) } + /// https://immersive-web.github.io/webxr/#dom-xrsession-mode fn Mode(&self) -> XRSessionMode { XRSessionMode::Immersive_vr } + /// https://immersive-web.github.io/webxr/#dom-xrsession-baselayer fn SetBaseLayer(&self, layer: Option<&XRLayer>) { self.base_layer.set(layer); if let Some(layer) = layer { @@ -81,14 +87,17 @@ impl XRSessionMethods for XRSession { } } + /// https://immersive-web.github.io/webxr/#dom-xrsession-baselayer fn GetBaseLayer(&self) -> Option> { self.base_layer.get() } + /// https://immersive-web.github.io/webxr/#dom-xrsession-requestanimationframe fn RequestAnimationFrame(&self, callback: Rc) -> i32 { self.display.xr_raf(callback) as i32 } + /// https://immersive-web.github.io/webxr/#dom-xrsession-cancelanimationframe fn CancelAnimationFrame(&self, frame: i32) { self.display.xr_cancel_raf(frame) } diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs index 258308a211b..72420fc0530 100644 --- a/components/script/dom/xrviewerpose.rs +++ b/components/script/dom/xrviewerpose.rs @@ -36,6 +36,7 @@ impl XRViewerPose { } impl XRViewerPoseMethods for XRViewerPose { + /// https://immersive-web.github.io/webxr/#dom-xrviewerpose-views fn Views(&self) -> Vec> { vec![ DomRoot::from_ref(&self.left), diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs index c9b6377e879..7af8a6cedae 100644 --- a/components/script/dom/xrwebgllayer.rs +++ b/components/script/dom/xrwebgllayer.rs @@ -72,26 +72,32 @@ impl XRWebGLLayer { } impl XRWebGLLayerMethods for XRWebGLLayer { + /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-depth fn Depth(&self) -> bool { self.depth.get() } + /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-stencil fn Stencil(&self) -> bool { self.stencil.get() } + /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-antialias fn Antialias(&self) -> bool { self.antialias.get() } + /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-alpha fn Alpha(&self) -> bool { self.alpha.get() } + /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-context fn Context(&self) -> DomRoot { DomRoot::from_ref(&self.context) } + /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport fn GetViewport(&self, view: &XRView) -> Option> { if self.session != view.session() { return None; diff --git a/python/tidy/servo_tidy/tidy.py b/python/tidy/servo_tidy/tidy.py index deb86e289c2..a8c4246ce09 100644 --- a/python/tidy/servo_tidy/tidy.py +++ b/python/tidy/servo_tidy/tidy.py @@ -95,6 +95,7 @@ WEBIDL_STANDARDS = [ "//svgwg.org/svg2-draft", "//wicg.github.io", "//webaudio.github.io", + "//immersive-web.github.io/", # Not a URL "// This interface is entirely internal to Servo, and should not be" + " accessible to\n// web pages." From 64a64a8d6d9dc2f5dc173ab21813c578757dc094 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 22 Dec 2018 22:26:11 -0800 Subject: [PATCH 19/25] Properly support depthNear and depthFar --- components/script/dom/xrsession.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 8432603e4e7..449d4acf8fc 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::dom::bindings::codegen::Bindings::VRDisplayBinding::VRDisplayMethods; use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode; use crate::dom::bindings::codegen::Bindings::XRSessionBinding; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCallback; @@ -17,15 +18,12 @@ use crate::dom::vrdisplay::VRDisplay; use crate::dom::xrlayer::XRLayer; use crate::dom::xrwebgllayer::XRWebGLLayer; use dom_struct::dom_struct; -use std::cell::Cell; use std::rc::Rc; #[dom_struct] pub struct XRSession { eventtarget: EventTarget, display: Dom, - depth_near: Cell, - depth_far: Cell, base_layer: MutNullableDom, } @@ -34,8 +32,6 @@ impl XRSession { XRSession { eventtarget: EventTarget::new_inherited(), display: Dom::from_ref(display), - depth_near: Cell::new(0.1), - depth_far: Cell::new(1000.), base_layer: Default::default(), } } @@ -52,22 +48,22 @@ impl XRSession { impl XRSessionMethods for XRSession { /// https://immersive-web.github.io/webxr/#dom-xrsession-depthnear fn DepthNear(&self) -> Finite { - Finite::wrap(self.depth_near.get()) + self.display.DepthNear() } /// https://immersive-web.github.io/webxr/#dom-xrsession-depthfar fn DepthFar(&self) -> Finite { - Finite::wrap(self.depth_far.get()) + self.display.DepthFar() } /// https://immersive-web.github.io/webxr/#dom-xrsession-depthnear fn SetDepthNear(&self, d: Finite) { - self.depth_near.set(*d) + self.display.SetDepthNear(d) } /// https://immersive-web.github.io/webxr/#dom-xrsession-depthfar fn SetDepthFar(&self, d: Finite) { - self.depth_far.set(*d) + self.display.SetDepthFar(d) } /// https://immersive-web.github.io/webxr/#dom-xrsession-mode From feb2a2d3c90b2c54d7c8f8321ca049b0160d82fb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 22 Dec 2018 22:44:05 -0800 Subject: [PATCH 20/25] Switch viewerpose to an any attribute --- .../script/dom/webidls/XRViewerPose.webidl | 2 +- components/script/dom/xrviewerpose.rs | 38 ++++++++++++------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/components/script/dom/webidls/XRViewerPose.webidl b/components/script/dom/webidls/XRViewerPose.webidl index caf9f96ba10..cbce4f273e7 100644 --- a/components/script/dom/webidls/XRViewerPose.webidl +++ b/components/script/dom/webidls/XRViewerPose.webidl @@ -9,5 +9,5 @@ interface XRViewerPose { // readonly attribute XRRigidTransform transform; // readonly attribute FrozenArray views; // workaround until we have FrozenArray - sequence views(); + readonly attribute any views; }; diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs index 72420fc0530..af26b23aeb1 100644 --- a/components/script/dom/xrviewerpose.rs +++ b/components/script/dom/xrviewerpose.rs @@ -5,42 +5,52 @@ use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding; use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding::XRViewerPoseMethods; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; use crate::dom::xrview::XRView; use dom_struct::dom_struct; +use js::conversions::ToJSValConvertible; +use js::jsapi::{Heap, JSContext}; +use js::jsval::{JSVal, UndefinedValue}; #[dom_struct] pub struct XRViewerPose { reflector_: Reflector, - left: Dom, - right: Dom, + views: Heap, } impl XRViewerPose { - fn new_inherited(left: &XRView, right: &XRView) -> XRViewerPose { + fn new_inherited() -> XRViewerPose { XRViewerPose { reflector_: Reflector::new(), - left: Dom::from_ref(left), - right: Dom::from_ref(right), + views: Heap::default(), } } + #[allow(unsafe_code)] pub fn new(global: &GlobalScope, left: &XRView, right: &XRView) -> DomRoot { - reflect_dom_object( - Box::new(XRViewerPose::new_inherited(left, right)), + let pose = reflect_dom_object( + Box::new(XRViewerPose::new_inherited()), global, XRViewerPoseBinding::Wrap, - ) + ); + + unsafe { + let cx = global.get_cx(); + rooted!(in(cx) let mut jsval = UndefinedValue()); + let vec = vec![DomRoot::from_ref(left), DomRoot::from_ref(right)]; + vec.to_jsval(cx, jsval.handle_mut()); + pose.views.set(jsval.get()); + } + + pose } } impl XRViewerPoseMethods for XRViewerPose { /// https://immersive-web.github.io/webxr/#dom-xrviewerpose-views - fn Views(&self) -> Vec> { - vec![ - DomRoot::from_ref(&self.left), - DomRoot::from_ref(&self.right), - ] + #[allow(unsafe_code)] + unsafe fn Views(&self, _cx: *mut JSContext) -> JSVal { + self.views.get() } } From c3b93a967d0cf79bb19d78fbfb4f4b0f9e99d3ae Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sun, 23 Dec 2018 15:54:33 -0800 Subject: [PATCH 21/25] Silence unused warnings --- components/script/dom/xrlayer.rs | 13 +--------- components/script/dom/xrreferencespace.rs | 1 + components/script/dom/xrrigidtransform.rs | 1 + .../script/dom/xrstationaryreferencespace.rs | 1 + components/script/dom/xrwebgllayer.rs | 26 +++++++++---------- 5 files changed, 16 insertions(+), 26 deletions(-) diff --git a/components/script/dom/xrlayer.rs b/components/script/dom/xrlayer.rs index 85e00d3ad1a..d17704be28f 100644 --- a/components/script/dom/xrlayer.rs +++ b/components/script/dom/xrlayer.rs @@ -2,10 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::dom::bindings::codegen::Bindings::XRLayerBinding; -use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; -use crate::dom::bindings::root::DomRoot; -use crate::dom::globalscope::GlobalScope; +use crate::dom::bindings::reflector::Reflector; use dom_struct::dom_struct; #[dom_struct] @@ -19,12 +16,4 @@ impl XRLayer { reflector_: Reflector::new(), } } - - pub fn new(global: &GlobalScope) -> DomRoot { - reflect_dom_object( - Box::new(XRLayer::new_inherited()), - global, - XRLayerBinding::Wrap, - ) - } } diff --git a/components/script/dom/xrreferencespace.rs b/components/script/dom/xrreferencespace.rs index 0a2e1bee3d9..308b710d928 100644 --- a/components/script/dom/xrreferencespace.rs +++ b/components/script/dom/xrreferencespace.rs @@ -21,6 +21,7 @@ impl XRReferenceSpace { } } + #[allow(unused)] pub fn new(global: &GlobalScope) -> DomRoot { reflect_dom_object( Box::new(XRReferenceSpace::new_inherited()), diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index b14bb0a02bf..b147e274810 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -20,6 +20,7 @@ impl XRRigidTransform { } } + #[allow(unused)] pub fn new(global: &GlobalScope) -> DomRoot { reflect_dom_object( Box::new(XRRigidTransform::new_inherited()), diff --git a/components/script/dom/xrstationaryreferencespace.rs b/components/script/dom/xrstationaryreferencespace.rs index 65dc5dd93cf..92c0dce0196 100644 --- a/components/script/dom/xrstationaryreferencespace.rs +++ b/components/script/dom/xrstationaryreferencespace.rs @@ -14,6 +14,7 @@ pub struct XRStationaryReferenceSpace { xrreferencespace: XRReferenceSpace, } +#[allow(unused)] impl XRStationaryReferenceSpace { pub fn new_inherited() -> XRStationaryReferenceSpace { XRStationaryReferenceSpace { diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs index 7af8a6cedae..16653383a0b 100644 --- a/components/script/dom/xrwebgllayer.rs +++ b/components/script/dom/xrwebgllayer.rs @@ -18,15 +18,13 @@ use crate::dom::xrview::XRView; use crate::dom::xrviewport::XRViewport; use dom_struct::dom_struct; -use std::cell::Cell; - #[dom_struct] pub struct XRWebGLLayer { xrlayer: XRLayer, - antialias: Cell, - depth: Cell, - stencil: Cell, - alpha: Cell, + antialias: bool, + depth: bool, + stencil: bool, + alpha: bool, context: Dom, session: Dom, } @@ -39,10 +37,10 @@ impl XRWebGLLayer { ) -> XRWebGLLayer { XRWebGLLayer { xrlayer: XRLayer::new_inherited(), - antialias: Cell::new(init.antialias), - depth: Cell::new(init.depth), - stencil: Cell::new(init.stencil), - alpha: Cell::new(init.alpha), + antialias: init.antialias, + depth: init.depth, + stencil: init.stencil, + alpha: init.alpha, context: Dom::from_ref(context), session: Dom::from_ref(session), } @@ -74,22 +72,22 @@ impl XRWebGLLayer { impl XRWebGLLayerMethods for XRWebGLLayer { /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-depth fn Depth(&self) -> bool { - self.depth.get() + self.depth } /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-stencil fn Stencil(&self) -> bool { - self.stencil.get() + self.stencil } /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-antialias fn Antialias(&self) -> bool { - self.antialias.get() + self.antialias } /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-alpha fn Alpha(&self) -> bool { - self.alpha.get() + self.alpha } /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-context From 309bd63c70ee5040a4f30584ca3694fe1eb05afb Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 3 Jan 2019 15:43:31 -0800 Subject: [PATCH 22/25] Remove Cell in XRSpace --- components/script/dom/xrspace.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/components/script/dom/xrspace.rs b/components/script/dom/xrspace.rs index c0def208f64..00e20df2c22 100644 --- a/components/script/dom/xrspace.rs +++ b/components/script/dom/xrspace.rs @@ -21,6 +21,7 @@ impl XRSpace { } } + #[allow(unused)] pub fn new(global: &GlobalScope) -> DomRoot { reflect_dom_object( Box::new(XRSpace::new_inherited()), From cfa539751c995cfe19457d457bc84b390bd5456e Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 3 Jan 2019 15:47:16 -0800 Subject: [PATCH 23/25] Link to relevant issues --- components/script/dom/webglrenderingcontext.rs | 4 ++++ components/script/dom/webidls/XRViewerPose.webidl | 1 + 2 files changed, 5 insertions(+) diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 376da84486d..5abccee8fbf 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -212,6 +212,8 @@ impl WebGLRenderingContext { current_program: MutNullableDom::new(None), current_vertex_attrib_0: Cell::new((0f32, 0f32, 0f32, 1f32)), current_scissor: Cell::new((0, 0, size.width, size.height)), + // FIXME(#21718) The backend is allowed to choose a size smaller than + // what was requested size: Cell::new(size), current_clear_color: Cell::new((0.0, 0.0, 0.0, 0.0)), extension_manager: WebGLExtensions::new(webgl_version), @@ -268,6 +270,8 @@ impl WebGLRenderingContext { pub fn recreate(&self, size: Size2D) { let (sender, receiver) = webgl_channel().unwrap(); self.webgl_sender.send_resize(size, sender).unwrap(); + // FIXME(#21718) The backend is allowed to choose a size smaller than + // what was requested self.size.set(size); if let Err(msg) = receiver.recv().unwrap() { diff --git a/components/script/dom/webidls/XRViewerPose.webidl b/components/script/dom/webidls/XRViewerPose.webidl index cbce4f273e7..8b63fd6cdb5 100644 --- a/components/script/dom/webidls/XRViewerPose.webidl +++ b/components/script/dom/webidls/XRViewerPose.webidl @@ -9,5 +9,6 @@ interface XRViewerPose { // readonly attribute XRRigidTransform transform; // readonly attribute FrozenArray views; // workaround until we have FrozenArray + // see https://github.com/servo/servo/issues/10427#issuecomment-449593626 readonly attribute any views; }; From 4d73eac27ca0451dda7df81d1d1cf9df6832072c Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 3 Jan 2019 15:48:05 -0800 Subject: [PATCH 24/25] NonNull::new() --- components/script/dom/xrview.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index 5fd7dfcae2e..55975e5d8a0 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -72,12 +72,12 @@ impl XRViewMethods for XRView { #[allow(unsafe_code)] /// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix unsafe fn ProjectionMatrix(&self, _cx: *mut JSContext) -> NonNull { - NonNull::new_unchecked(self.proj.get()) + NonNull::new(self.proj.get()).unwrap() } #[allow(unsafe_code)] /// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix unsafe fn ViewMatrix(&self, _cx: *mut JSContext) -> NonNull { - NonNull::new_unchecked(self.view.get()) + NonNull::new(self.view.get()).unwrap() } } From e544462b6c4732987c5c8154d4a4e33539e83d13 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Thu, 3 Jan 2019 15:48:39 -0800 Subject: [PATCH 25/25] Remove unrooted_must_root --- components/script/dom/xr.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index b381ef56aa1..98d018eb0f9 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -106,7 +106,6 @@ impl XRMethods for XR { } impl XR { - #[allow(unrooted_must_root)] pub fn get_displays(&self) -> Result>, ()> { if let Some(webvr_thread) = self.webvr_thread() { let (sender, receiver) =