Update WebXR Layer IDL, and matching changes to the Rust code.

This commit is contained in:
Alan Jeffrey 2020-07-31 18:44:57 -05:00
parent 092dcaf2e6
commit bf7f4eae31
13 changed files with 235 additions and 325 deletions

View file

@ -5,7 +5,6 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants; use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLRenderingContext;
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
@ -141,13 +140,9 @@ impl WebGLFramebuffer {
// https://github.com/servo/servo/issues/24498 // https://github.com/servo/servo/issues/24498
pub fn maybe_new_webxr( pub fn maybe_new_webxr(
session: &XRSession, session: &XRSession,
context: &XRWebGLRenderingContext, context: &WebGLRenderingContext,
size: Size2D<i32, Viewport>, size: Size2D<i32, Viewport>,
) -> Option<DomRoot<Self>> { ) -> Option<DomRoot<Self>> {
let context = match context {
XRWebGLRenderingContext::WebGLRenderingContext(ref ctx) => DomRoot::from_ref(&**ctx),
XRWebGLRenderingContext::WebGL2RenderingContext(ref ctx) => ctx.base_context(),
};
let framebuffer = Self::maybe_new(&*context)?; let framebuffer = Self::maybe_new(&*context)?;
framebuffer.size.set(Some((size.width, size.height))); framebuffer.size.set(Some((size.width, size.height)));
framebuffer.status.set(constants::FRAMEBUFFER_COMPLETE); framebuffer.status.set(constants::FRAMEBUFFER_COMPLETE);

View file

@ -2,59 +2,74 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
// https://immersive-web.github.io/layers/#xrlayertype // https://immersive-web.github.io/webxr/#xrlayer
[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"] [SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
interface XRLayer { interface XRLayer : EventTarget {};
// attribute boolean blendTextureSourceAlpha;
// attribute boolean chromaticAberrationCorrection;
void destroy();
};
//
// TODO: Implement the layer types // TODO: Implement the layer types
// //
// [SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] // [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
// interface XRProjectionLayer : XRLayer { // interface XRCompositionLayer : XRLayer {
// readonly attribute XRLayerLayout layout;
//
// attribute boolean blendTextureSourceAlpha;
// attribute boolean? chromaticAberrationCorrection;
// attribute float? fixedFoveation;
//
// readonly attribute boolean needsRedraw;
//
// void destroy();
// };
//
// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
// interface XRProjectionLayer : XRCompositionLayer {
// readonly attribute boolean ignoreDepthValues; // readonly attribute boolean ignoreDepthValues;
// }; // };
// //
// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"] // [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
// interface XRQuadLayer : XRLayer { // interface XRQuadLayer : XRCompositionLayer {
// readonly attribute XRLayerLayout layout; // attribute XRSpace space;
// attribute XRRigidTransform transform; // attribute XRRigidTransform transform;
// //
// attribute float width; // attribute float width;
// attribute float height; // attribute float height;
//
// // Events
// attribute EventHandler onredraw;
// }; // };
// //
// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"] // [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
// interface XRCylinderLayer : XRLayer { // interface XRCylinderLayer : XRCompositionLayer {
// readonly attribute XRLayerLayout layout; // attribute XRSpace space;
// attribute XRReferenceSpace referenceSpace;
//
// attribute XRRigidTransform transform; // attribute XRRigidTransform transform;
//
// attribute float radius; // attribute float radius;
// attribute float centralAngle; // attribute float centralAngle;
// attribute float aspectRatio; // attribute float aspectRatio;
//
// // Events
// attribute EventHandler onredraw;
// }; // };
// //
// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"] // [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
// interface XREquirectLayer : XRLayer { // interface XREquirectLayer : XRCompositionLayer {
// readonly attribute XRLayerLayout layout; // attribute XRSpace space;
// attribute XRReferenceSpace referenceSpace;
//
// attribute XRRigidTransform transform; // attribute XRRigidTransform transform;
//
// attribute float radius; // attribute float radius;
// attribute float scaleX; // attribute float centralHorizontalAngle;
// attribute float scaleY; // attribute float upperVerticalAngle;
// attribute float biasX; // attribute float lowerVerticalAngle;
// attribute float biasY; //
// // Events
// attribute EventHandler onredraw;
// }; // };
// //
// [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"] // [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
// interface XRCubeLayer : XRLayer { // interface XRCubeLayer : XRCompositionLayer {
// readonly attribute XRLayerLayout layout; // attribute XRSpace space;
// attribute XRReferenceSpace referenceSpace; // attribute DOMPointReadOnly orientation;
// //
// attribute DOMPoint orientation; // // Events
// attribute EventHandler onredraw;
// }; // };

View file

@ -0,0 +1,15 @@
/* 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/#xrlayerevent-interface
// [SecureContext, Exposed=Window]
// interface XRLayerEvent : Event {
// constructor(DOMString type, XRLayerEventInit eventInitDict);
// [SameObject] readonly attribute XRLayer layer;
// };
dictionary XRLayerEventInit : EventInit {
required XRLayer layer;
};

View file

@ -13,6 +13,7 @@ interface XRMediaBinding {
}; };
dictionary XRMediaLayerInit { dictionary XRMediaLayerInit {
required XRSpace space;
XRLayerLayout layout = "mono"; XRLayerLayout layout = "mono";
boolean invertStereo = false; boolean invertStereo = false;
}; };

View file

@ -2,16 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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 // https://immersive-web.github.io/webxr/#xrrenderstate-interface
dictionary XRRenderStateInit { dictionary XRRenderStateInit {
double depthNear; double depthNear;
double depthFar; double depthFar;
double inlineVerticalFieldOfView; double inlineVerticalFieldOfView;
XRWebGLLayer baseLayer; XRWebGLLayer? baseLayer;
sequence<XRGenericLayer> layers; sequence<XRLayer>? layers;
}; };
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRRenderState { [SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] interface XRRenderState {
@ -19,4 +17,8 @@ dictionary XRRenderStateInit {
readonly attribute double depthFar; readonly attribute double depthFar;
readonly attribute double? inlineVerticalFieldOfView; readonly attribute double? inlineVerticalFieldOfView;
readonly attribute XRWebGLLayer? baseLayer; readonly attribute XRWebGLLayer? baseLayer;
// https://immersive-web.github.io/layers/#xrrenderstatechanges
// workaround until we have FrozenArray
readonly attribute /* FrozenArray<XRLayer> */ any layers;
}; };

View file

@ -5,5 +5,5 @@
// https://immersive-web.github.io/layers/#xrsubimagetype // https://immersive-web.github.io/layers/#xrsubimagetype
[SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"] [SecureContext, Exposed=Window, Pref="dom.webxr.layers.enabled"]
interface XRSubImage { interface XRSubImage {
readonly attribute XRViewport viewport; [SameObject] readonly attribute XRViewport viewport;
}; };

View file

@ -9,14 +9,18 @@ interface XRWebGLBinding {
// readonly attribute double nativeProjectionScaleFactor; // readonly attribute double nativeProjectionScaleFactor;
// XRProjectionLayer createProjectionLayer(GLenum textureTarget, optional XRProjectionLayerInit init = {}); // XRProjectionLayer createProjectionLayer(XRTextureType textureType,
// XRQuadLayer createQuadLayer(GLenum textureTarget, XRLayerInit init); // optional XRProjectionLayerInit init);
// XRCylinderLayer createCylinderLayer(GLenum textureTarget, XRLayerInit init); // XRQuadLayer createQuadLayer(XRTextureType textureType,
// XREquirectLayer createEquirectLayer(GLenum textureTarget, XRLayerInit init); // optional XRQuadLayerInit init);
// XRCubeLayer createCubeLayer(XRLayerInit init); // XRCylinderLayer createCylinderLayer(XRTextureType textureType,
// optional XRCylinderLayerInit init);
// XREquirectLayer createEquirectLayer(XRTextureType textureType,
// optional XREquirectLayerInit init);
// XRCubeLayer createCubeLayer(optional XRCubeLayerInit init);
XRWebGLSubImage? getSubImage(XRLayer layer, XRFrame frame); // for mono layers // XRWebGLSubImage getSubImage(XRCompositionLayer layer, XRFrame frame, optional XREye eye = "none");
XRWebGLSubImage? getViewSubImage(XRLayer layer, XRView view); // for stereo layers // XRWebGLSubImage getViewSubImage(XRProjectionLayer layer, XRView view);
}; };
dictionary XRProjectionLayerInit { dictionary XRProjectionLayerInit {
@ -26,19 +30,54 @@ dictionary XRProjectionLayerInit {
double scaleFactor = 1.0; double scaleFactor = 1.0;
}; };
dictionary XRQuadLayerInit : XRLayerInit {
XRRigidTransform? transform;
float width = 1.0;
float height = 1.0;
boolean isStatic = false;
};
dictionary XRCylinderLayerInit : XRLayerInit {
XRRigidTransform? transform;
float radius = 2.0;
float centralAngle = 0.78539;
float aspectRatio = 2.0;
boolean isStatic = false;
};
dictionary XREquirectLayerInit : XRLayerInit {
XRRigidTransform? transform;
float radius = 0;
float centralHorizontalAngle = 6.28318;
float upperVerticalAngle = 1.570795;
float lowerVerticalAngle = -1.570795;
boolean isStatic = false;
};
dictionary XRCubeLayerInit : XRLayerInit {
DOMPointReadOnly? orientation;
boolean isStatic = false;
};
dictionary XRLayerInit { dictionary XRLayerInit {
required unsigned long pixelWidth; required XRSpace space;
required unsigned long pixelHeight; required unsigned long viewPixelWidth;
required unsigned long viewPixelHeight;
XRLayerLayout layout = "mono"; XRLayerLayout layout = "mono";
boolean depth = false; // This is a change from typical WebGL initialization, but feels appropriate. boolean depth = false;
boolean stencil = false; boolean stencil = false;
boolean alpha = true; boolean alpha = true;
}; };
enum XRTextureType {
"texture",
"texture-array"
};
enum XRLayerLayout { enum XRLayerLayout {
"default",
"mono", "mono",
"stereo", "stereo",
"stereo-left-right", "stereo-left-right",
"stereo-top-bottom" "stereo-top-bottom"
}; };

View file

@ -17,19 +17,19 @@ dictionary XRWebGLLayerInit {
}; };
[SecureContext, Exposed=Window, Pref="dom.webxr.enabled"] [SecureContext, Exposed=Window, Pref="dom.webxr.enabled"]
interface XRWebGLLayer { interface XRWebGLLayer: XRLayer {
[Throws] constructor(XRSession session, [Throws] constructor(XRSession session,
XRWebGLRenderingContext context, XRWebGLRenderingContext context,
optional XRWebGLLayerInit layerInit = {}); optional XRWebGLLayerInit layerInit = {});
// // Attributes // Attributes
readonly attribute boolean antialias; readonly attribute boolean antialias;
readonly attribute boolean ignoreDepthValues; readonly attribute boolean ignoreDepthValues;
readonly attribute WebGLFramebuffer? framebuffer; [SameObject] readonly attribute WebGLFramebuffer? framebuffer;
readonly attribute unsigned long framebufferWidth; readonly attribute unsigned long framebufferWidth;
readonly attribute unsigned long framebufferHeight; readonly attribute unsigned long framebufferHeight;
// // Methods // Methods
XRViewport? getViewport(XRView view); XRViewport? getViewport(XRView view);
// // Static Methods // // Static Methods

View file

@ -2,30 +2,26 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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::inheritance::Castable;
use crate::dom::bindings::reflector::Reflector;
use crate::dom::bindings::root::Dom; use crate::dom::bindings::root::Dom;
use crate::dom::eventtarget::EventTarget;
use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::xrframe::XRFrame; use crate::dom::xrframe::XRFrame;
use crate::dom::xrsession::XRSession; use crate::dom::xrsession::XRSession;
use crate::dom::xrwebgllayer::XRWebGLLayer;
use canvas_traits::webgl::WebGLContextId; use canvas_traits::webgl::WebGLContextId;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use webxr_api::LayerId; use webxr_api::LayerId;
#[dom_struct] #[dom_struct]
pub struct XRLayer { pub struct XRLayer {
reflector: Reflector, event_target: EventTarget,
session: Dom<XRSession>, session: Dom<XRSession>,
context: Dom<WebGLRenderingContext>, context: Dom<WebGLRenderingContext>,
#[ignore_malloc_size_of = "Layers don't heap-allocate"] /// If none, the session is inline (the composition disabled flag is true)
layer_id: LayerId, /// and this is a XRWebGLLayer.
} #[ignore_malloc_size_of = "Layer ids don't heap-allocate"]
layer_id: Option<LayerId>,
impl XRLayerMethods for XRLayer {
/// https://immersive-web.github.io/layers/#dom-xrlayer-destroy
fn Destroy(&self) {
// TODO: Implement this
}
} }
impl XRLayer { impl XRLayer {
@ -33,17 +29,17 @@ impl XRLayer {
pub fn new_inherited( pub fn new_inherited(
session: &XRSession, session: &XRSession,
context: &WebGLRenderingContext, context: &WebGLRenderingContext,
layer_id: LayerId, layer_id: Option<LayerId>,
) -> XRLayer { ) -> XRLayer {
XRLayer { XRLayer {
reflector: Reflector::new(), event_target: EventTarget::new_inherited(),
session: Dom::from_ref(session), session: Dom::from_ref(session),
context: Dom::from_ref(context), context: Dom::from_ref(context),
layer_id, layer_id,
} }
} }
pub(crate) fn layer_id(&self) -> LayerId { pub(crate) fn layer_id(&self) -> Option<LayerId> {
self.layer_id self.layer_id
} }
@ -51,13 +47,29 @@ impl XRLayer {
self.context.context_id() self.context.context_id()
} }
pub fn begin_frame(&self, _frame: &XRFrame) -> Option<()> { pub(crate) fn context(&self) -> &WebGLRenderingContext {
// TODO: Implement this &self.context
None
} }
pub fn end_frame(&self, _frame: &XRFrame) -> Option<()> { pub(crate) fn session(&self) -> &XRSession {
// TODO: Implement this &self.session
None }
pub fn begin_frame(&self, frame: &XRFrame) -> Option<()> {
// TODO: Implement this for other layer types
if let Some(this) = self.downcast::<XRWebGLLayer>() {
this.begin_frame(frame)
} else {
unimplemented!()
}
}
pub fn end_frame(&self, frame: &XRFrame) -> Option<()> {
// TODO: Implement this for other layer types
if let Some(this) = self.downcast::<XRWebGLLayer>() {
this.end_frame(frame)
} else {
unimplemented!()
}
} }
} }

View file

@ -4,17 +4,18 @@
use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateMethods; 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::num::Finite;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::root::Dom;
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::bindings::utils::to_frozen_array;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::xrlayer::XRLayer; use crate::dom::xrlayer::XRLayer;
use crate::dom::xrwebgllayer::XRWebGLLayer; use crate::dom::xrwebgllayer::XRWebGLLayer;
use canvas_traits::webgl::WebGLContextId; use crate::script_runtime::JSContext;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::jsval::JSVal;
use std::cell::Cell; use std::cell::Cell;
use webxr_api::LayerId;
use webxr_api::SubImages; use webxr_api::SubImages;
#[dom_struct] #[dom_struct]
@ -24,51 +25,7 @@ pub struct XRRenderState {
depth_far: Cell<f64>, depth_far: Cell<f64>,
inline_vertical_fov: Cell<Option<f64>>, inline_vertical_fov: Cell<Option<f64>>,
base_layer: MutNullableDom<XRWebGLLayer>, base_layer: MutNullableDom<XRWebGLLayer>,
layers: DomRefCell<Vec<XRWebGLLayerOrXRLayer>>, layers: DomRefCell<Vec<Dom<XRLayer>>>,
}
#[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(crate) fn layer_id(&self) -> Option<LayerId> {
match self {
XRWebGLLayerOrXRLayer::XRWebGLLayer(ref layer) => layer.layer_id(),
XRWebGLLayerOrXRLayer::XRLayer(ref layer) => Some(layer.layer_id()),
}
}
}
impl RootedXRWebGLLayerOrXRLayer {
pub(crate) fn layer_id(&self) -> Option<LayerId> {
match self {
RootedXRWebGLLayerOrXRLayer::XRWebGLLayer(ref layer) => layer.layer_id(),
RootedXRWebGLLayerOrXRLayer::XRLayer(ref layer) => Some(layer.layer_id()),
}
}
pub(crate) fn context_id(&self) -> WebGLContextId {
match self {
RootedXRWebGLLayerOrXRLayer::XRWebGLLayer(ref layer) => layer.context_id(),
RootedXRWebGLLayerOrXRLayer::XRLayer(ref layer) => layer.context_id(),
}
}
} }
impl XRRenderState { impl XRRenderState {
@ -77,7 +34,7 @@ impl XRRenderState {
depth_far: f64, depth_far: f64,
inline_vertical_fov: Option<f64>, inline_vertical_fov: Option<f64>,
layer: Option<&XRWebGLLayer>, layer: Option<&XRWebGLLayer>,
layers: &[XRWebGLLayerOrXRLayer], layers: Vec<&XRLayer>,
) -> XRRenderState { ) -> XRRenderState {
debug_assert!(layer.is_none() || layers.is_empty()); debug_assert!(layer.is_none() || layers.is_empty());
XRRenderState { XRRenderState {
@ -86,7 +43,12 @@ impl XRRenderState {
depth_far: Cell::new(depth_far), depth_far: Cell::new(depth_far),
inline_vertical_fov: Cell::new(inline_vertical_fov), inline_vertical_fov: Cell::new(inline_vertical_fov),
base_layer: MutNullableDom::new(layer), base_layer: MutNullableDom::new(layer),
layers: DomRefCell::new(layers.iter().cloned().collect()), layers: DomRefCell::new(
layers
.into_iter()
.map(|layer| Dom::from_ref(layer))
.collect(),
),
} }
} }
@ -96,7 +58,7 @@ impl XRRenderState {
depth_far: f64, depth_far: f64,
inline_vertical_fov: Option<f64>, inline_vertical_fov: Option<f64>,
layer: Option<&XRWebGLLayer>, layer: Option<&XRWebGLLayer>,
layers: &[XRWebGLLayerOrXRLayer], layers: Vec<&XRLayer>,
) -> DomRoot<XRRenderState> { ) -> DomRoot<XRRenderState> {
reflect_dom_object( reflect_dom_object(
Box::new(XRRenderState::new_inherited( Box::new(XRRenderState::new_inherited(
@ -111,14 +73,13 @@ impl XRRenderState {
} }
pub fn clone_object(&self) -> DomRoot<Self> { pub fn clone_object(&self) -> DomRoot<Self> {
let layers = self.layers.borrow();
XRRenderState::new( XRRenderState::new(
&self.global(), &self.global(),
self.depth_near.get(), self.depth_near.get(),
self.depth_far.get(), self.depth_far.get(),
self.inline_vertical_fov.get(), self.inline_vertical_fov.get(),
self.base_layer.get().as_ref().map(|x| &**x), self.base_layer.get().as_ref().map(|x| &**x),
&layers, self.layers.borrow().iter().map(|x| &**x).collect(),
) )
} }
@ -135,12 +96,15 @@ impl XRRenderState {
pub fn set_base_layer(&self, layer: Option<&XRWebGLLayer>) { pub fn set_base_layer(&self, layer: Option<&XRWebGLLayer>) {
self.base_layer.set(layer) self.base_layer.set(layer)
} }
pub fn set_layers(&self, layers: &[RootedXRWebGLLayerOrXRLayer]) { pub fn set_layers(&self, layers: Vec<&XRLayer>) {
*self.layers.borrow_mut() = layers.iter().map(XRWebGLLayerOrXRLayer::from_ref).collect(); *self.layers.borrow_mut() = layers
.into_iter()
.map(|layer| Dom::from_ref(layer))
.collect();
} }
pub fn with_layers<F, R>(&self, f: F) -> R pub fn with_layers<F, R>(&self, f: F) -> R
where where
F: FnOnce(&[XRWebGLLayerOrXRLayer]) -> R, F: FnOnce(&[Dom<XRLayer>]) -> R,
{ {
let layers = self.layers.borrow(); let layers = self.layers.borrow();
f(&*layers) f(&*layers)
@ -187,4 +151,12 @@ impl XRRenderStateMethods for XRRenderState {
fn GetBaseLayer(&self) -> Option<DomRoot<XRWebGLLayer>> { fn GetBaseLayer(&self) -> Option<DomRoot<XRWebGLLayer>> {
self.base_layer.get() self.base_layer.get()
} }
/// https://immersive-web.github.io/layers/#dom-xrrenderstate-layers
fn Layers(&self, cx: JSContext) -> JSVal {
// TODO: cache this array?
let layers = self.layers.borrow();
let layers: Vec<&XRLayer> = layers.iter().map(|x| &**x).collect();
to_frozen_array(&layers[..], cx)
}
} }

View file

@ -16,7 +16,6 @@ use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRFrameRequestCal
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods;
use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRVisibilityState; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRVisibilityState;
use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionMode; use crate::dom::bindings::codegen::Bindings::XRSystemBinding::XRSessionMode;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLRenderingContext;
use crate::dom::bindings::error::{Error, ErrorResult}; use crate::dom::bindings::error::{Error, ErrorResult};
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::refcounted::Trusted;
@ -33,7 +32,6 @@ use crate::dom::xrinputsourcearray::XRInputSourceArray;
use crate::dom::xrinputsourceevent::XRInputSourceEvent; use crate::dom::xrinputsourceevent::XRInputSourceEvent;
use crate::dom::xrreferencespace::XRReferenceSpace; use crate::dom::xrreferencespace::XRReferenceSpace;
use crate::dom::xrrenderstate::XRRenderState; use crate::dom::xrrenderstate::XRRenderState;
use crate::dom::xrrenderstate::XRWebGLLayerOrXRLayer;
use crate::dom::xrsessionevent::XRSessionEvent; use crate::dom::xrsessionevent::XRSessionEvent;
use crate::dom::xrspace::XRSpace; use crate::dom::xrspace::XRSpace;
use crate::realms::InRealm; use crate::realms::InRealm;
@ -133,7 +131,7 @@ impl XRSession {
} else { } else {
None 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, Vec::new());
let input_sources = XRInputSourceArray::new(global); let input_sources = XRInputSourceArray::new(global);
let ret = reflect_dom_object( let ret = reflect_dom_object(
Box::new(XRSession::new_inherited( Box::new(XRSession::new_inherited(
@ -495,12 +493,7 @@ impl XRSession {
pub fn dirty_layers(&self) { pub fn dirty_layers(&self) {
if let Some(layer) = self.RenderState().GetBaseLayer() { if let Some(layer) = self.RenderState().GetBaseLayer() {
match layer.context() { layer.context().mark_as_dirty();
XRWebGLRenderingContext::WebGLRenderingContext(c) => c.mark_as_dirty(),
XRWebGLRenderingContext::WebGL2RenderingContext(c) => {
c.base_context().mark_as_dirty()
},
}
} }
} }
@ -511,14 +504,7 @@ impl XRSession {
} }
self.active_render_state.get().with_layers(|layers| { self.active_render_state.get().with_layers(|layers| {
for layer in layers { for layer in layers {
match layer {
XRWebGLLayerOrXRLayer::XRWebGLLayer(layer) => {
layer.begin_frame(frame); layer.begin_frame(frame);
},
XRWebGLLayerOrXRLayer::XRLayer(layer) => {
layer.begin_frame(frame);
},
}
} }
}); });
} }
@ -530,14 +516,7 @@ impl XRSession {
} }
self.active_render_state.get().with_layers(|layers| { self.active_render_state.get().with_layers(|layers| {
for layer in layers { for layer in layers {
match layer {
XRWebGLLayerOrXRLayer::XRWebGLLayer(layer) => {
layer.end_frame(frame); layer.end_frame(frame);
},
XRWebGLLayerOrXRLayer::XRLayer(layer) => {
layer.end_frame(frame);
},
}
} }
}); });
} }
@ -612,7 +591,7 @@ impl XRSessionMethods for XRSession {
return Err(Error::InvalidState); return Err(Error::InvalidState);
} }
// Step 3: // Step 3:
if let Some(ref layer) = init.baseLayer { if let Some(Some(ref layer)) = init.baseLayer {
if Dom::from_ref(layer.session()) != Dom::from_ref(self) { if Dom::from_ref(layer.session()) != Dom::from_ref(self) {
return Err(Error::InvalidState); return Err(Error::InvalidState);
} }
@ -623,22 +602,8 @@ impl XRSessionMethods for XRSession {
return Err(Error::InvalidState); return Err(Error::InvalidState);
} }
// TODO: add spec link for this step once XR layers has settled down // TODO: Add the checks in
// https://immersive-web.github.io/layers/ // https://immersive-web.github.io/layers/#updaterenderstatechanges
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 let pending = self
.pending_render_state .pending_render_state
@ -673,9 +638,10 @@ impl XRSessionMethods for XRSession {
pending.set_inline_vertical_fov(fov); pending.set_inline_vertical_fov(fov);
} }
if let Some(ref layer) = init.baseLayer { if let Some(ref layer) = init.baseLayer {
pending.set_base_layer(Some(&layer)); pending.set_base_layer(layer.as_deref());
pending.set_layers(&[]); pending.set_layers(Vec::new());
let layers = std::iter::once(layer) let layers = layer
.iter()
.filter_map(|layer| { .filter_map(|layer| {
let context_id = WebXRContextId::from(layer.context_id()); let context_id = WebXRContextId::from(layer.context_id());
let layer_id = layer.layer_id()?; let layer_id = layer.layer_id()?;
@ -691,11 +657,11 @@ impl XRSessionMethods for XRSession {
.update_clip_planes(*pending.DepthNear() as f32, *pending.DepthFar() as f32); .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/#updaterenderstatechanges
// https://immersive-web.github.io/layers/
if let Some(ref layers) = init.layers { if let Some(ref layers) = init.layers {
let layers = layers.as_deref().unwrap_or_default();
pending.set_base_layer(None); pending.set_base_layer(None);
pending.set_layers(layers); pending.set_layers(layers.iter().map(|x| &**x).collect());
let layers = layers let layers = layers
.iter() .iter()
.filter_map(|layer| { .filter_map(|layer| {

View file

@ -2,105 +2,36 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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;
use crate::dom::bindings::codegen::UnionTypes::WebGLRenderingContextOrWebGL2RenderingContext as RootedWebGLRenderingContextOrWebGL2RenderingContext;
use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::reflector::reflect_dom_object;
use crate::dom::bindings::reflector::Reflector; use crate::dom::bindings::reflector::Reflector;
use crate::dom::bindings::root::Dom; use crate::dom::bindings::root::Dom;
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
use crate::dom::webgl2renderingcontext::WebGL2RenderingContext;
use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::window::Window; use crate::dom::window::Window;
use crate::dom::xrframe::XRFrame;
use crate::dom::xrlayer::XRLayer;
use crate::dom::xrsession::XRSession; use crate::dom::xrsession::XRSession;
use crate::dom::xrview::XRView;
use crate::dom::xrwebglsubimage::XRWebGLSubImage;
use canvas_traits::webgl::WebGLContextId;
use dom_struct::dom_struct; use dom_struct::dom_struct;
#[dom_struct] #[dom_struct]
pub struct XRWebGLBinding { pub struct XRWebGLBinding {
reflector: Reflector, reflector: Reflector,
session: Dom<XRSession>, session: Dom<XRSession>,
context: WebGLRenderingContextOrWebGL2RenderingContext, context: Dom<WebGLRenderingContext>,
}
// 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 RootedWebGLRenderingContextOrWebGL2RenderingContext {
pub(crate) fn context_id(&self) -> WebGLContextId {
match self {
RootedWebGLRenderingContextOrWebGL2RenderingContext::WebGLRenderingContext(
ref context,
) => context.context_id(),
RootedWebGLRenderingContextOrWebGL2RenderingContext::WebGL2RenderingContext(
ref context,
) => context.base_context().context_id(),
}
}
}
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 { impl XRWebGLBinding {
pub fn new_inherited( pub fn new_inherited(session: &XRSession, context: &WebGLRenderingContext) -> XRWebGLBinding {
session: &XRSession,
context: &WebGLRenderingContextOrWebGL2RenderingContext,
) -> XRWebGLBinding {
XRWebGLBinding { XRWebGLBinding {
reflector: Reflector::new(), reflector: Reflector::new(),
session: Dom::from_ref(session), session: Dom::from_ref(session),
context: context.clone(), context: Dom::from_ref(context),
} }
} }
pub fn new( pub fn new(
global: &Window, global: &Window,
session: &XRSession, session: &XRSession,
context: &WebGLRenderingContextOrWebGL2RenderingContext, context: &WebGLRenderingContext,
) -> DomRoot<XRWebGLBinding> { ) -> DomRoot<XRWebGLBinding> {
reflect_dom_object( reflect_dom_object(
Box::new(XRWebGLBinding::new_inherited(session, context)), Box::new(XRWebGLBinding::new_inherited(session, context)),
@ -112,12 +43,14 @@ impl XRWebGLBinding {
pub fn Constructor( pub fn Constructor(
global: &Window, global: &Window,
session: &XRSession, session: &XRSession,
context: RootedWebGLRenderingContextOrWebGL2RenderingContext, context: WebGLRenderingContextOrWebGL2RenderingContext,
) -> DomRoot<XRWebGLBinding> { ) -> DomRoot<XRWebGLBinding> {
XRWebGLBinding::new( let context = match context {
global, WebGLRenderingContextOrWebGL2RenderingContext::WebGLRenderingContext(ctx) => ctx,
session, WebGLRenderingContextOrWebGL2RenderingContext::WebGL2RenderingContext(ctx) => {
&WebGLRenderingContextOrWebGL2RenderingContext::from_ref(&context), ctx.base_context()
) },
};
XRWebGLBinding::new(global, session, &context)
} }
} }

View file

@ -2,30 +2,29 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants; use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as constants;
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods;
use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextBinding::WebGL2RenderingContextMethods;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerInit; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerInit;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLRenderingContext; use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLRenderingContext;
use crate::dom::bindings::error::Error; use crate::dom::bindings::error::Error;
use crate::dom::bindings::error::Fallible; use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject};
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::dom::webglframebuffer::WebGLFramebuffer; use crate::dom::webglframebuffer::WebGLFramebuffer;
use crate::dom::webglobject::WebGLObject; use crate::dom::webglobject::WebGLObject;
use crate::dom::webgltexture::WebGLTexture;
use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::webgl2renderingcontext::WebGL2RenderingContext; use crate::dom::webgltexture::WebGLTexture;
use crate::dom::window::Window; use crate::dom::window::Window;
use crate::dom::xrframe::XRFrame; use crate::dom::xrframe::XRFrame;
use crate::dom::xrlayer::XRLayer;
use crate::dom::xrsession::XRSession; use crate::dom::xrsession::XRSession;
use crate::dom::xrview::XRView; use crate::dom::xrview::XRView;
use crate::dom::xrviewport::XRViewport; use crate::dom::xrviewport::XRViewport;
use canvas_traits::webgl::WebGLContextId;
use canvas_traits::webgl::WebGLCommand; use canvas_traits::webgl::WebGLCommand;
use canvas_traits::webgl::WebGLContextId;
use canvas_traits::webgl::WebGLTextureId; use canvas_traits::webgl::WebGLTextureId;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use euclid::{Rect, Size2D}; use euclid::{Rect, Size2D};
@ -35,22 +34,6 @@ use webxr_api::LayerId;
use webxr_api::LayerInit; use webxr_api::LayerInit;
use webxr_api::Viewport; use webxr_api::Viewport;
#[derive(JSTraceable, MallocSizeOf)]
#[unrooted_must_root_lint::must_root]
pub enum RenderingContext {
WebGL1(Dom<WebGLRenderingContext>),
WebGL2(Dom<WebGL2RenderingContext>),
}
impl RenderingContext {
fn context_id(&self) -> WebGLContextId {
match self {
RenderingContext::WebGL1(ref ctx) => ctx.context_id(),
RenderingContext::WebGL2(ref ctx) => ctx.base_context().context_id(),
}
}
}
impl<'a> From<&'a XRWebGLLayerInit> for LayerInit { impl<'a> From<&'a XRWebGLLayerInit> for LayerInit {
fn from(init: &'a XRWebGLLayerInit) -> LayerInit { fn from(init: &'a XRWebGLLayerInit) -> LayerInit {
LayerInit::WebGLLayer { LayerInit::WebGLLayer {
@ -66,46 +49,31 @@ impl<'a> From<&'a XRWebGLLayerInit> for LayerInit {
#[dom_struct] #[dom_struct]
pub struct XRWebGLLayer { pub struct XRWebGLLayer {
reflector_: Reflector, xr_layer: XRLayer,
antialias: bool, antialias: bool,
depth: bool, depth: bool,
stencil: bool, stencil: bool,
alpha: bool, alpha: bool,
ignore_depth_values: bool, ignore_depth_values: bool,
context: RenderingContext,
session: Dom<XRSession>,
/// If none, this is an inline session (the composition disabled flag is true) /// If none, this is an inline session (the composition disabled flag is true)
framebuffer: Option<Dom<WebGLFramebuffer>>, framebuffer: Option<Dom<WebGLFramebuffer>>,
/// If none, this is an inline session (the composition disabled flag is true)
#[ignore_malloc_size_of = "Layer ids don't heap-allocate"]
layer_id: Option<LayerId>,
} }
impl XRWebGLLayer { impl XRWebGLLayer {
pub fn new_inherited( pub fn new_inherited(
session: &XRSession, session: &XRSession,
context: XRWebGLRenderingContext, context: &WebGLRenderingContext,
init: &XRWebGLLayerInit, init: &XRWebGLLayerInit,
framebuffer: Option<&WebGLFramebuffer>, framebuffer: Option<&WebGLFramebuffer>,
layer_id: Option<LayerId>, layer_id: Option<LayerId>,
) -> XRWebGLLayer { ) -> XRWebGLLayer {
XRWebGLLayer { XRWebGLLayer {
reflector_: Reflector::new(), xr_layer: XRLayer::new_inherited(session, context, layer_id),
antialias: init.antialias, antialias: init.antialias,
depth: init.depth, depth: init.depth,
stencil: init.stencil, stencil: init.stencil,
alpha: init.alpha, alpha: init.alpha,
ignore_depth_values: init.ignoreDepthValues, ignore_depth_values: init.ignoreDepthValues,
layer_id,
context: match context {
XRWebGLRenderingContext::WebGLRenderingContext(ctx) => {
RenderingContext::WebGL1(Dom::from_ref(&*ctx))
},
XRWebGLRenderingContext::WebGL2RenderingContext(ctx) => {
RenderingContext::WebGL2(Dom::from_ref(&*ctx))
},
},
session: Dom::from_ref(session),
framebuffer: framebuffer.map(Dom::from_ref), framebuffer: framebuffer.map(Dom::from_ref),
} }
} }
@ -113,7 +81,7 @@ impl XRWebGLLayer {
pub fn new( pub fn new(
global: &GlobalScope, global: &GlobalScope,
session: &XRSession, session: &XRSession,
context: XRWebGLRenderingContext, context: &WebGLRenderingContext,
init: &XRWebGLLayerInit, init: &XRWebGLLayerInit,
framebuffer: Option<&WebGLFramebuffer>, framebuffer: Option<&WebGLFramebuffer>,
layer_id: Option<LayerId>, layer_id: Option<LayerId>,
@ -138,6 +106,11 @@ impl XRWebGLLayer {
context: XRWebGLRenderingContext, context: XRWebGLRenderingContext,
init: &XRWebGLLayerInit, init: &XRWebGLLayerInit,
) -> Fallible<DomRoot<Self>> { ) -> Fallible<DomRoot<Self>> {
let context = match context {
XRWebGLRenderingContext::WebGLRenderingContext(ctx) => ctx,
XRWebGLRenderingContext::WebGL2RenderingContext(ctx) => ctx.base_context(),
};
// Step 2 // Step 2
if session.is_ended() { if session.is_ended() {
return Err(Error::InvalidState); return Err(Error::InvalidState);
@ -169,16 +142,13 @@ impl XRWebGLLayer {
}; };
// Ensure that we finish setting up this layer before continuing. // Ensure that we finish setting up this layer before continuing.
match context { context.Finish();
XRWebGLRenderingContext::WebGLRenderingContext(ref ctx) => ctx.Finish(),
XRWebGLRenderingContext::WebGL2RenderingContext(ref ctx) => ctx.Finish(),
}
// Step 10. "Return layer." // Step 10. "Return layer."
Ok(XRWebGLLayer::new( Ok(XRWebGLLayer::new(
&global.global(), &global.global(),
session, session,
context, &context,
init, init,
framebuffer.as_deref(), framebuffer.as_deref(),
layer_id, layer_id,
@ -186,15 +156,15 @@ impl XRWebGLLayer {
} }
pub fn layer_id(&self) -> Option<LayerId> { pub fn layer_id(&self) -> Option<LayerId> {
self.layer_id self.xr_layer.layer_id()
} }
pub fn context_id(&self) -> WebGLContextId { pub fn context_id(&self) -> WebGLContextId {
self.context.context_id() self.xr_layer.context_id()
} }
pub fn session(&self) -> &XRSession { pub fn session(&self) -> &XRSession {
&self.session &self.xr_layer.session()
} }
pub fn size(&self) -> Size2D<u32, Viewport> { pub fn size(&self) -> Size2D<u32, Viewport> {
@ -205,10 +175,7 @@ impl XRWebGLLayer {
size.1.try_into().unwrap_or(0), size.1.try_into().unwrap_or(0),
) )
} else { } else {
let size = match self.context { let size = self.context().Canvas().get_size();
RenderingContext::WebGL1(ref ctx) => ctx.Canvas().get_size(),
RenderingContext::WebGL2(ref ctx) => ctx.base_context().Canvas().get_size(),
};
Size2D::from_untyped(size) Size2D::from_untyped(size)
} }
} }
@ -225,7 +192,7 @@ impl XRWebGLLayer {
debug!("XRWebGLLayer begin frame"); debug!("XRWebGLLayer begin frame");
let framebuffer = self.framebuffer.as_ref()?; let framebuffer = self.framebuffer.as_ref()?;
let context = framebuffer.upcast::<WebGLObject>().context(); let context = framebuffer.upcast::<WebGLObject>().context();
let sub_images = frame.get_sub_images(self.layer_id?)?; let sub_images = frame.get_sub_images(self.layer_id()?)?;
// TODO: Cache this texture // TODO: Cache this texture
let color_texture_id = let color_texture_id =
WebGLTextureId::maybe_new(sub_images.sub_image.as_ref()?.color_texture)?; WebGLTextureId::maybe_new(sub_images.sub_image.as_ref()?.color_texture)?;
@ -306,15 +273,8 @@ impl XRWebGLLayer {
Some(()) Some(())
} }
pub(crate) fn context(&self) -> XRWebGLRenderingContext { pub(crate) fn context(&self) -> &WebGLRenderingContext {
match self.context { self.xr_layer.context()
RenderingContext::WebGL1(ref ctx) => {
XRWebGLRenderingContext::WebGLRenderingContext(DomRoot::from_ref(&**ctx))
},
RenderingContext::WebGL2(ref ctx) => {
XRWebGLRenderingContext::WebGL2RenderingContext(DomRoot::from_ref(&**ctx))
},
}
} }
} }
@ -346,13 +306,13 @@ impl XRWebGLLayerMethods for XRWebGLLayer {
/// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport /// https://immersive-web.github.io/webxr/#dom-xrwebgllayer-getviewport
fn GetViewport(&self, view: &XRView) -> Option<DomRoot<XRViewport>> { fn GetViewport(&self, view: &XRView) -> Option<DomRoot<XRViewport>> {
if self.session != view.session() { if self.session() != view.session() {
return None; return None;
} }
let index = view.viewport_index(); let index = view.viewport_index();
let viewport = self.session.with_session(|s| { let viewport = self.session().with_session(|s| {
// Inline sssions // Inline sssions
if s.viewports().is_empty() { if s.viewports().is_empty() {
Rect::from_size(self.size().to_i32()) Rect::from_size(self.size().to_i32())