aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorAlan Jeffrey <ajeffrey@mozilla.com>2020-04-08 17:35:20 -0500
committerAlan Jeffrey <ajeffrey@mozilla.com>2020-04-13 13:57:58 -0500
commitfda8da0e9dcb575205fd29e566ece1d72fe1ab11 (patch)
treea51a14cb21db8989ab019ec748ed4658f2ca6a08 /components/script
parent7ae11588dc36e644750008d1224a6d93c9e49d08 (diff)
downloadservo-fda8da0e9dcb575205fd29e566ece1d72fe1ab11.tar.gz
servo-fda8da0e9dcb575205fd29e566ece1d72fe1ab11.zip
Added first-cut implementation of XR layers
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/mod.rs9
-rw-r--r--components/script/dom/webidls/XRLayer.webidl63
-rw-r--r--components/script/dom/webidls/XRMediaBinding.webidl18
-rw-r--r--components/script/dom/webidls/XRRenderState.webidl3
-rw-r--r--components/script/dom/webidls/XRSubImage.webidl9
-rw-r--r--components/script/dom/webidls/XRWebGLBinding.webidl44
-rw-r--r--components/script/dom/webidls/XRWebGLSubImage.webidl11
-rw-r--r--components/script/dom/xrlayer.rs53
-rw-r--r--components/script/dom/xrmediabinding.rs35
-rw-r--r--components/script/dom/xrrenderstate.rs63
-rw-r--r--components/script/dom/xrsession.rs59
-rw-r--r--components/script/dom/xrsubimage.rs23
-rw-r--r--components/script/dom/xrwebglbinding.rs109
-rw-r--r--components/script/dom/xrwebglsubimage.rs35
14 files changed, 519 insertions, 15 deletions
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index dcc9af258cd..9ae4274a194 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -535,9 +535,8 @@ pub mod videotracklist;
pub mod virtualmethods;
pub mod vttcue;
pub mod vttregion;
-pub mod webgl_extensions;
-pub use self::webgl_extensions::ext::*;
pub mod webgl2renderingcontext;
+pub mod webgl_extensions;
pub mod webgl_validations;
pub mod webglactiveinfo;
pub mod webglbuffer;
@@ -577,6 +576,8 @@ pub mod xrinputsource;
pub mod xrinputsourcearray;
pub mod xrinputsourceevent;
pub mod xrinputsourceschangeevent;
+pub mod xrlayer;
+pub mod xrmediabinding;
pub mod xrpose;
pub mod xrreferencespace;
pub mod xrrenderstate;
@@ -584,9 +585,13 @@ pub mod xrrigidtransform;
pub mod xrsession;
pub mod xrsessionevent;
pub mod xrspace;
+pub mod xrsubimage;
pub mod xrsystem;
pub mod xrtest;
pub mod xrview;
pub mod xrviewerpose;
pub mod xrviewport;
+pub mod xrwebglbinding;
pub mod xrwebgllayer;
+pub mod xrwebglsubimage;
+pub use self::webgl_extensions::ext::*;
diff --git a/components/script/dom/webidls/XRLayer.webidl b/components/script/dom/webidls/XRLayer.webidl
new file mode 100644
index 00000000000..eb967abf091
--- /dev/null
+++ b/components/script/dom/webidls/XRLayer.webidl
@@ -0,0 +1,63 @@
+/* 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/layers/#xrlayertype
+[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+interface XRLayer {
+ readonly attribute unsigned long pixelWidth;
+ readonly attribute unsigned long pixelHeight;
+
+// attribute boolean blendTextureSourceAlpha;
+// attribute boolean chromaticAberrationCorrection;
+
+ void destroy();
+};
+//
+// TODO: Implement the layer types
+//
+// [SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
+// interface XRProjectionLayer : XRLayer {
+// readonly attribute boolean ignoreDepthValues;
+// };
+//
+// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+// interface XRQuadLayer : XRLayer {
+// readonly attribute XRLayerLayout layout;
+// attribute XRRigidTransform transform;
+//
+// attribute float width;
+// attribute float height;
+// };
+//
+// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+// interface XRCylinderLayer : XRLayer {
+// readonly attribute XRLayerLayout layout;
+// attribute XRReferenceSpace referenceSpace;
+//
+// attribute XRRigidTransform transform;
+// attribute float radius;
+// attribute float centralAngle;
+// attribute float aspectRatio;
+// };
+//
+// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+// interface XREquirectLayer : XRLayer {
+// readonly attribute XRLayerLayout layout;
+// attribute XRReferenceSpace referenceSpace;
+//
+// attribute XRRigidTransform transform;
+// attribute float radius;
+// attribute float scaleX;
+// attribute float scaleY;
+// attribute float biasX;
+// attribute float biasY;
+// };
+//
+// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+// interface XRCubeLayer : XRLayer {
+// readonly attribute XRLayerLayout layout;
+// attribute XRReferenceSpace referenceSpace;
+//
+// attribute DOMPoint orientation;
+// };
diff --git a/components/script/dom/webidls/XRMediaBinding.webidl b/components/script/dom/webidls/XRMediaBinding.webidl
new file mode 100644
index 00000000000..9ea40de56a4
--- /dev/null
+++ b/components/script/dom/webidls/XRMediaBinding.webidl
@@ -0,0 +1,18 @@
+/* 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/layers/#xrmediabindingtype
+[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+interface XRMediaBinding {
+ constructor(XRSession session);
+
+// XRQuadLayer createQuadVideoLayer(HTMLVideoElement video, optional XRMediaLayerInit init = {});
+// XRCylinderLayer createCylinderVideoLayer(HTMLVideoElement video, optional XRMediaLayerInit init = {});
+// XREquirectLayer createEquirectVideoLayer(HTMLVideoElement video, optional XRMediaLayerInit init = {});
+};
+
+dictionary XRMediaLayerInit {
+ XRLayerLayout layout = "mono";
+ boolean invertStereo = false;
+};
diff --git a/components/script/dom/webidls/XRRenderState.webidl b/components/script/dom/webidls/XRRenderState.webidl
index e361ced6597..708df1f20eb 100644
--- a/components/script/dom/webidls/XRRenderState.webidl
+++ b/components/script/dom/webidls/XRRenderState.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/. */
+typedef (XRWebGLLayer or XRLayer) XRGenericLayer;
+
// https://immersive-web.github.io/webxr/#xrrenderstate-interface
dictionary XRRenderStateInit {
@@ -9,6 +11,7 @@ dictionary XRRenderStateInit {
double depthFar;
double inlineVerticalFieldOfView;
XRWebGLLayer baseLayer;
+ sequence<XRGenericLayer> layers;
};
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRRenderState {
diff --git a/components/script/dom/webidls/XRSubImage.webidl b/components/script/dom/webidls/XRSubImage.webidl
new file mode 100644
index 00000000000..9dbbd089928
--- /dev/null
+++ b/components/script/dom/webidls/XRSubImage.webidl
@@ -0,0 +1,9 @@
+/* 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/layers/#xrsubimagetype
+[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+interface XRSubImage {
+ readonly attribute XRViewport viewport;
+};
diff --git a/components/script/dom/webidls/XRWebGLBinding.webidl b/components/script/dom/webidls/XRWebGLBinding.webidl
new file mode 100644
index 00000000000..08617561b36
--- /dev/null
+++ b/components/script/dom/webidls/XRWebGLBinding.webidl
@@ -0,0 +1,44 @@
+/* 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/layers/#XRWebGLBindingtype
+[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+interface XRWebGLBinding {
+ constructor(XRSession session, XRWebGLRenderingContext context);
+
+// readonly attribute double nativeProjectionScaleFactor;
+
+// XRProjectionLayer createProjectionLayer(GLenum textureTarget, optional XRProjectionLayerInit init = {});
+// XRQuadLayer createQuadLayer(GLenum textureTarget, XRLayerInit init);
+// XRCylinderLayer createCylinderLayer(GLenum textureTarget, XRLayerInit init);
+// XREquirectLayer createEquirectLayer(GLenum textureTarget, XRLayerInit init);
+// XRCubeLayer createCubeLayer(XRLayerInit init);
+
+ XRWebGLSubImage? getSubImage(XRLayer layer, XRFrame frame); // for mono layers
+ XRWebGLSubImage? getViewSubImage(XRLayer layer, XRView view); // for stereo layers
+};
+
+dictionary XRProjectionLayerInit {
+ boolean depth = true;
+ boolean stencil = false;
+ boolean alpha = true;
+ double scaleFactor = 1.0;
+};
+
+dictionary XRLayerInit {
+ required unsigned long pixelWidth;
+ required unsigned long pixelHeight;
+ XRLayerLayout layout = "mono";
+ boolean depth = false; // This is a change from typical WebGL initialization, but feels appropriate.
+ boolean stencil = false;
+ boolean alpha = true;
+};
+
+enum XRLayerLayout {
+ "mono",
+ "stereo",
+ "stereo-left-right",
+ "stereo-top-bottom"
+};
+
diff --git a/components/script/dom/webidls/XRWebGLSubImage.webidl b/components/script/dom/webidls/XRWebGLSubImage.webidl
new file mode 100644
index 00000000000..f25552d533e
--- /dev/null
+++ b/components/script/dom/webidls/XRWebGLSubImage.webidl
@@ -0,0 +1,11 @@
+/* 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/layers/#xrwebglsubimagetype
+[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
+interface XRWebGLSubImage : XRSubImage {
+ readonly attribute WebGLTexture colorTexture;
+ readonly attribute WebGLTexture? depthStencilTexture;
+ readonly attribute unsigned long? imageIndex;
+};
diff --git a/components/script/dom/xrlayer.rs b/components/script/dom/xrlayer.rs
new file mode 100644
index 00000000000..e70cdb5085a
--- /dev/null
+++ b/components/script/dom/xrlayer.rs
@@ -0,0 +1,53 @@
+/* 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::XRLayerBinding::XRLayerMethods;
+use crate::dom::bindings::reflector::Reflector;
+use crate::dom::bindings::root::Dom;
+use crate::dom::webglrenderingcontext::WebGLRenderingContext;
+use crate::dom::xrsession::XRSession;
+use dom_struct::dom_struct;
+use euclid::Size2D;
+use webxr_api::Viewport;
+
+#[dom_struct]
+pub struct XRLayer {
+ reflector: Reflector,
+ session: Dom<XRSession>,
+ context: Dom<WebGLRenderingContext>,
+ size: Size2D<u32, Viewport>,
+}
+
+impl XRLayerMethods for XRLayer {
+ /// https://immersive-web.github.io/layers/#dom-xrlayer-pixelwidth
+ fn PixelWidth(&self) -> u32 {
+ self.size.width
+ }
+
+ /// https://immersive-web.github.io/layers/#dom-xrlayer-pixelheight
+ fn PixelHeight(&self) -> u32 {
+ self.size.height
+ }
+
+ /// https://immersive-web.github.io/layers/#dom-xrlayer-destroy
+ fn Destroy(&self) {
+ // TODO: Implement this
+ }
+}
+
+impl XRLayer {
+ #[allow(dead_code)]
+ pub fn new_inherited(
+ session: &XRSession,
+ context: &WebGLRenderingContext,
+ size: Size2D<u32, Viewport>,
+ ) -> XRLayer {
+ XRLayer {
+ reflector: Reflector::new(),
+ session: Dom::from_ref(session),
+ context: Dom::from_ref(context),
+ size: size,
+ }
+ }
+}
diff --git a/components/script/dom/xrmediabinding.rs b/components/script/dom/xrmediabinding.rs
new file mode 100644
index 00000000000..b0b6a0ac69c
--- /dev/null
+++ b/components/script/dom/xrmediabinding.rs
@@ -0,0 +1,35 @@
+/* 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::reflector::reflect_dom_object;
+use crate::dom::bindings::reflector::Reflector;
+use crate::dom::bindings::root::Dom;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::window::Window;
+use crate::dom::xrsession::XRSession;
+use dom_struct::dom_struct;
+
+#[dom_struct]
+pub struct XRMediaBinding {
+ reflector: Reflector,
+ session: Dom<XRSession>,
+}
+
+impl XRMediaBinding {
+ pub fn new_inherited(session: &XRSession) -> XRMediaBinding {
+ XRMediaBinding {
+ reflector: Reflector::new(),
+ session: Dom::from_ref(session),
+ }
+ }
+
+ pub fn new(global: &Window, session: &XRSession) -> DomRoot<XRMediaBinding> {
+ reflect_dom_object(Box::new(XRMediaBinding::new_inherited(session)), global)
+ }
+
+ #[allow(non_snake_case)]
+ pub fn Constructor(global: &Window, session: &XRSession) -> DomRoot<XRMediaBinding> {
+ XRMediaBinding::new(global, session)
+ }
+}
diff --git a/components/script/dom/xrrenderstate.rs b/components/script/dom/xrrenderstate.rs
index 199e029ee7d..d174af531d0 100644
--- a/components/script/dom/xrrenderstate.rs
+++ b/components/script/dom/xrrenderstate.rs
@@ -2,15 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateMethods;
+use crate::dom::bindings::codegen::UnionTypes::XRWebGLLayerOrXRLayer as RootedXRWebGLLayerOrXRLayer;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
-use crate::dom::bindings::root::{DomRoot, MutNullableDom};
+use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::globalscope::GlobalScope;
+use crate::dom::xrlayer::XRLayer;
use crate::dom::xrwebgllayer::XRWebGLLayer;
-
use dom_struct::dom_struct;
use std::cell::Cell;
+use webxr_api::SwapChainId;
#[dom_struct]
pub struct XRRenderState {
@@ -19,6 +22,42 @@ pub struct XRRenderState {
depth_far: Cell<f64>,
inline_vertical_fov: Cell<Option<f64>>,
layer: MutNullableDom<XRWebGLLayer>,
+ layers: DomRefCell<Vec<XRWebGLLayerOrXRLayer>>,
+}
+
+#[unrooted_must_root_lint::must_root]
+#[derive(Clone, JSTraceable, MallocSizeOf)]
+pub enum XRWebGLLayerOrXRLayer {
+ XRWebGLLayer(Dom<XRWebGLLayer>),
+ XRLayer(Dom<XRLayer>),
+}
+
+impl XRWebGLLayerOrXRLayer {
+ #[allow(unrooted_must_root)]
+ fn from_ref(layer: &RootedXRWebGLLayerOrXRLayer) -> XRWebGLLayerOrXRLayer {
+ match layer {
+ RootedXRWebGLLayerOrXRLayer::XRWebGLLayer(ref layer) => {
+ XRWebGLLayerOrXRLayer::XRWebGLLayer(Dom::from_ref(layer))
+ },
+ RootedXRWebGLLayerOrXRLayer::XRLayer(ref layer) => {
+ XRWebGLLayerOrXRLayer::XRLayer(Dom::from_ref(layer))
+ },
+ }
+ }
+
+ pub fn swap_chain_id(&self) -> Option<SwapChainId> {
+ match self {
+ XRWebGLLayerOrXRLayer::XRWebGLLayer(layer) => Some(layer.swap_chain_id()),
+ XRWebGLLayerOrXRLayer::XRLayer(_) => None,
+ }
+ }
+
+ pub fn swap_buffers(&self) {
+ match self {
+ XRWebGLLayerOrXRLayer::XRWebGLLayer(layer) => layer.swap_buffers(),
+ XRWebGLLayerOrXRLayer::XRLayer(_) => (),
+ }
+ }
}
impl XRRenderState {
@@ -27,13 +66,16 @@ impl XRRenderState {
depth_far: f64,
inline_vertical_fov: Option<f64>,
layer: Option<&XRWebGLLayer>,
+ layers: &[XRWebGLLayerOrXRLayer],
) -> XRRenderState {
+ debug_assert!(layer.is_none() || layers.is_empty());
XRRenderState {
reflector_: Reflector::new(),
depth_near: Cell::new(depth_near),
depth_far: Cell::new(depth_far),
inline_vertical_fov: Cell::new(inline_vertical_fov),
layer: MutNullableDom::new(layer),
+ layers: DomRefCell::new(layers.iter().cloned().collect()),
}
}
@@ -43,6 +85,7 @@ impl XRRenderState {
depth_far: f64,
inline_vertical_fov: Option<f64>,
layer: Option<&XRWebGLLayer>,
+ layers: &[XRWebGLLayerOrXRLayer],
) -> DomRoot<XRRenderState> {
reflect_dom_object(
Box::new(XRRenderState::new_inherited(
@@ -50,18 +93,21 @@ impl XRRenderState {
depth_far,
inline_vertical_fov,
layer,
+ layers,
)),
global,
)
}
pub fn clone_object(&self) -> DomRoot<Self> {
+ let layers = self.layers.borrow();
XRRenderState::new(
&self.global(),
self.depth_near.get(),
self.depth_far.get(),
self.inline_vertical_fov.get(),
self.layer.get().as_ref().map(|x| &**x),
+ &layers,
)
}
@@ -78,6 +124,19 @@ impl XRRenderState {
pub fn set_layer(&self, layer: Option<&XRWebGLLayer>) {
self.layer.set(layer)
}
+ pub fn set_layers(&self, layers: &[RootedXRWebGLLayerOrXRLayer]) {
+ *self.layers.borrow_mut() = layers.iter().map(XRWebGLLayerOrXRLayer::from_ref).collect();
+ }
+ pub fn with_layers<F, R>(&self, f: F) -> R
+ where
+ F: FnOnce(&[XRWebGLLayerOrXRLayer]) -> R,
+ {
+ let layers = self.layers.borrow();
+ f(&*layers)
+ }
+ pub fn has_layer(&self) -> bool {
+ self.layer.get().is_some() || !self.layers.borrow().is_empty()
+ }
}
impl XRRenderStateMethods for XRRenderState {
diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs
index 3396ca669c1..53e6c492b68 100644
--- a/components/script/dom/xrsession.rs
+++ b/components/script/dom/xrsession.rs
@@ -31,7 +31,6 @@ use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrrenderstate::XRRenderState;
use crate::dom::xrsessionevent::XRSessionEvent;
use crate::dom::xrspace::XRSpace;
-use crate::dom::xrwebgllayer::XRWebGLLayer;
use crate::realms::InRealm;
use crate::task_source::TaskSource;
use dom_struct::dom_struct;
@@ -52,7 +51,6 @@ use webxr_api::{
#[dom_struct]
pub struct XRSession {
eventtarget: EventTarget,
- base_layer: MutNullableDom<XRWebGLLayer>,
blend_mode: XREnvironmentBlendMode,
mode: XRSessionMode,
visibility_state: Cell<XRVisibilityState>,
@@ -88,7 +86,6 @@ impl XRSession {
) -> XRSession {
XRSession {
eventtarget: EventTarget::new_inherited(),
- base_layer: Default::default(),
blend_mode: session.environment_blend_mode().into(),
mode,
visibility_state: Cell::new(XRVisibilityState::Visible),
@@ -119,7 +116,7 @@ impl XRSession {
} else {
None
};
- let render_state = XRRenderState::new(global, 0.1, 1000.0, ivfov, None);
+ let render_state = XRRenderState::new(global, 0.1, 1000.0, ivfov, None, &[]);
let input_sources = XRInputSourceArray::new(global);
let ret = reflect_dom_object(
Box::new(XRSession::new_inherited(
@@ -355,7 +352,14 @@ impl XRSession {
// Step 6-7: XXXManishearth handle inlineVerticalFieldOfView
if self.is_immersive() {
- let swap_chain_id = pending.GetBaseLayer().map(|layer| layer.swap_chain_id());
+ let swap_chain_id = pending
+ .GetBaseLayer()
+ .map(|layer| layer.swap_chain_id())
+ .or_else(|| {
+ self.active_render_state.get().with_layers(|layers| {
+ layers.get(0).and_then(|layer| layer.swap_chain_id())
+ })
+ });
self.session.borrow_mut().set_swap_chain(swap_chain_id);
} else {
self.update_inline_projection_matrix()
@@ -367,10 +371,9 @@ impl XRSession {
}
// Step 2
- let base_layer = match self.active_render_state.get().GetBaseLayer() {
- Some(layer) => layer,
- None => return,
- };
+ if !self.active_render_state.get().has_layer() {
+ return;
+ }
// Step 3: XXXManishearth handle inline session
@@ -395,7 +398,15 @@ impl XRSession {
frame.set_active(false);
if self.is_immersive() {
- base_layer.swap_buffers();
+ if let Some(base_layer) = self.active_render_state.get().GetBaseLayer() {
+ base_layer.swap_buffers();
+ } else {
+ self.active_render_state.get().with_layers(|layers| {
+ for layer in layers {
+ layer.swap_buffers();
+ }
+ });
+ }
self.session.borrow_mut().render_animation_frame();
} else {
self.session.borrow_mut().start_render_loop();
@@ -513,6 +524,23 @@ impl XRSessionMethods for XRSession {
return Err(Error::InvalidState);
}
+ // TODO: add spec link for this step once XR layers has settled down
+ // https://immersive-web.github.io/layers/
+ if init.baseLayer.is_some() && init.layers.is_some() {
+ return Err(Error::InvalidState);
+ }
+
+ // TODO: add spec link for this step once XR layers has settled down
+ // https://immersive-web.github.io/layers/
+ if init
+ .layers
+ .as_ref()
+ .map(|layers| layers.is_empty())
+ .unwrap_or(false)
+ {
+ return Err(Error::InvalidState);
+ }
+
let pending = self
.pending_render_state
.or_init(|| self.active_render_state.get().clone_object());
@@ -546,7 +574,8 @@ impl XRSessionMethods for XRSession {
pending.set_inline_vertical_fov(fov);
}
if let Some(ref layer) = init.baseLayer {
- pending.set_layer(Some(&layer))
+ pending.set_layer(Some(&layer));
+ pending.set_layers(&[]);
}
if init.depthFar.is_some() || init.depthNear.is_some() {
@@ -554,6 +583,14 @@ impl XRSessionMethods for XRSession {
.borrow_mut()
.update_clip_planes(*pending.DepthNear() as f32, *pending.DepthFar() as f32);
}
+
+ // TODO: add spec link for this step once XR layers has settled down
+ // https://immersive-web.github.io/layers/
+ if let Some(ref layers) = init.layers {
+ pending.set_layer(None);
+ pending.set_layers(layers);
+ }
+
Ok(())
}
diff --git a/components/script/dom/xrsubimage.rs b/components/script/dom/xrsubimage.rs
new file mode 100644
index 00000000000..2be59d48d3b
--- /dev/null
+++ b/components/script/dom/xrsubimage.rs
@@ -0,0 +1,23 @@
+/* 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::XRSubImageBinding::XRSubImageBinding::XRSubImageMethods;
+use crate::dom::bindings::reflector::Reflector;
+use crate::dom::bindings::root::Dom;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::xrviewport::XRViewport;
+use dom_struct::dom_struct;
+
+#[dom_struct]
+pub struct XRSubImage {
+ reflector: Reflector,
+ viewport: Dom<XRViewport>,
+}
+
+impl XRSubImageMethods for XRSubImage {
+ /// https://immersive-web.github.io/layers/#dom-xrsubimage-viewport
+ fn Viewport(&self) -> DomRoot<XRViewport> {
+ DomRoot::from_ref(&self.viewport)
+ }
+}
diff --git a/components/script/dom/xrwebglbinding.rs b/components/script/dom/xrwebglbinding.rs
new file mode 100644
index 00000000000..27435aa3ddc
--- /dev/null
+++ b/components/script/dom/xrwebglbinding.rs
@@ -0,0 +1,109 @@
+/* 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::XRWebGLBindingBinding::XRWebGLBindingBinding::XRWebGLBindingMethods;
+use crate::dom::bindings::codegen::UnionTypes::WebGLRenderingContextOrWebGL2RenderingContext as RootedWebGLRenderingContextOrWebGL2RenderingContext;
+use crate::dom::bindings::reflector::reflect_dom_object;
+use crate::dom::bindings::reflector::Reflector;
+use crate::dom::bindings::root::Dom;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::webgl2renderingcontext::WebGL2RenderingContext;
+use crate::dom::webglrenderingcontext::WebGLRenderingContext;
+use crate::dom::window::Window;
+use crate::dom::xrframe::XRFrame;
+use crate::dom::xrlayer::XRLayer;
+use crate::dom::xrsession::XRSession;
+use crate::dom::xrview::XRView;
+use crate::dom::xrwebglsubimage::XRWebGLSubImage;
+use dom_struct::dom_struct;
+
+#[dom_struct]
+pub struct XRWebGLBinding {
+ reflector: Reflector,
+ session: Dom<XRSession>,
+ context: WebGLRenderingContextOrWebGL2RenderingContext,
+}
+
+// TODO: Should this live somewhere else?
+#[unrooted_must_root_lint::must_root]
+#[derive(Clone, JSTraceable, MallocSizeOf)]
+pub enum WebGLRenderingContextOrWebGL2RenderingContext {
+ WebGLRenderingContext(Dom<WebGLRenderingContext>),
+ WebGL2RenderingContext(Dom<WebGL2RenderingContext>),
+}
+
+impl WebGLRenderingContextOrWebGL2RenderingContext {
+ #[allow(unrooted_must_root)]
+ fn from_ref(
+ context: &RootedWebGLRenderingContextOrWebGL2RenderingContext,
+ ) -> WebGLRenderingContextOrWebGL2RenderingContext {
+ match context {
+ RootedWebGLRenderingContextOrWebGL2RenderingContext::WebGLRenderingContext(
+ ref context,
+ ) => WebGLRenderingContextOrWebGL2RenderingContext::WebGLRenderingContext(
+ Dom::from_ref(context),
+ ),
+ RootedWebGLRenderingContextOrWebGL2RenderingContext::WebGL2RenderingContext(
+ ref context,
+ ) => WebGLRenderingContextOrWebGL2RenderingContext::WebGL2RenderingContext(
+ Dom::from_ref(context),
+ ),
+ }
+ }
+}
+
+impl XRWebGLBindingMethods for XRWebGLBinding {
+ /// https://immersive-web.github.io/layers/#dom-xrwebglbinding-getsubimage
+ fn GetSubImage(&self, _layer: &XRLayer, _frame: &XRFrame) -> Option<DomRoot<XRWebGLSubImage>> {
+ // TODO: Implement this
+ None
+ }
+
+ /// https://immersive-web.github.io/layers/#dom-xrwebglbinding-getviewsubimage
+ fn GetViewSubImage(
+ &self,
+ _layer: &XRLayer,
+ _view: &XRView,
+ ) -> Option<DomRoot<XRWebGLSubImage>> {
+ // TODO: Implement this
+ None
+ }
+}
+
+impl XRWebGLBinding {
+ pub fn new_inherited(
+ session: &XRSession,
+ context: &WebGLRenderingContextOrWebGL2RenderingContext,
+ ) -> XRWebGLBinding {
+ XRWebGLBinding {
+ reflector: Reflector::new(),
+ session: Dom::from_ref(session),
+ context: context.clone(),
+ }
+ }
+
+ pub fn new(
+ global: &Window,
+ session: &XRSession,
+ context: &WebGLRenderingContextOrWebGL2RenderingContext,
+ ) -> DomRoot<XRWebGLBinding> {
+ reflect_dom_object(
+ Box::new(XRWebGLBinding::new_inherited(session, context)),
+ global,
+ )
+ }
+
+ #[allow(non_snake_case)]
+ pub fn Constructor(
+ global: &Window,
+ session: &XRSession,
+ context: RootedWebGLRenderingContextOrWebGL2RenderingContext,
+ ) -> DomRoot<XRWebGLBinding> {
+ XRWebGLBinding::new(
+ global,
+ session,
+ &WebGLRenderingContextOrWebGL2RenderingContext::from_ref(&context),
+ )
+ }
+}
diff --git a/components/script/dom/xrwebglsubimage.rs b/components/script/dom/xrwebglsubimage.rs
new file mode 100644
index 00000000000..0331d36c4c2
--- /dev/null
+++ b/components/script/dom/xrwebglsubimage.rs
@@ -0,0 +1,35 @@
+/* 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::XRWebGLSubImageBinding::XRWebGLSubImageBinding::XRWebGLSubImageMethods;
+use crate::dom::bindings::root::Dom;
+use crate::dom::bindings::root::DomRoot;
+use crate::dom::webgltexture::WebGLTexture;
+use crate::dom::xrsubimage::XRSubImage;
+use dom_struct::dom_struct;
+
+#[dom_struct]
+pub struct XRWebGLSubImage {
+ xr_sub_image: XRSubImage,
+ color_texture: Dom<WebGLTexture>,
+ depth_stencil_texture: Option<Dom<WebGLTexture>>,
+ image_index: Option<u32>,
+}
+
+impl XRWebGLSubImageMethods for XRWebGLSubImage {
+ /// https://immersive-web.github.io/layers/#dom-xrwebglsubimage-colortexture
+ fn ColorTexture(&self) -> DomRoot<WebGLTexture> {
+ DomRoot::from_ref(&self.color_texture)
+ }
+
+ /// https://immersive-web.github.io/layers/#dom-xrwebglsubimage-depthstenciltexture
+ fn GetDepthStencilTexture(&self) -> Option<DomRoot<WebGLTexture>> {
+ self.depth_stencil_texture.as_deref().map(DomRoot::from_ref)
+ }
+
+ /// https://immersive-web.github.io/layers/#dom-xrwebglsubimage-imageindex
+ fn GetImageIndex(&self) -> Option<u32> {
+ self.image_index
+ }
+}