Fill in XR frame/pose/view implementations

This commit is contained in:
Manish Goregaokar 2018-12-21 15:20:51 -08:00
parent 7e043a33f1
commit 28dff81dbf
12 changed files with 152 additions and 38 deletions

View file

@ -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
}

View file

@ -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;

View file

@ -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::<JSObject>());
unsafe {
let _ = Float32Array::create(cx, CreateWith::Slice(src), array.handle_mut());

View file

@ -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);
};

View file

@ -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;
};

View file

@ -7,4 +7,6 @@
[SecureContext, Exposed=Window] interface XRViewerPose {
// readonly attribute XRRigidTransform transform;
// readonly attribute FrozenArray<XRView> views;
// workaround until we have FrozenArray
sequence<XRView> views();
};

View file

@ -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))

View file

@ -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<XRSession>,
#[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<XRFrame> {
pub fn new(
global: &GlobalScope,
session: &XRSession,
data: WebVRFrameData,
) -> DomRoot<XRFrame> {
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<XRSession> {
DomRoot::from_ref(&self.session)
}
fn GetViewerPose(&self, reference: Option<&XRReferenceSpace>) -> Option<DomRoot<XRViewerPose>> {
// 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))
}
}

View file

@ -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<XRSession>,
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<XRView> {
reflect_dom_object(
pub fn new(
global: &GlobalScope,
session: &XRSession,
eye: XREye,
data: &WebVRFrameData,
) -> DomRoot<XRView> {
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
}
}
#[allow(unsafe_code)]
/// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix
unsafe fn ProjectionMatrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> {
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<JSObject> {
NonNull::new_unchecked(self.view.get())
}
}

View file

@ -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<XRView>,
right: Dom<XRView>,
}
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<XRViewerPose> {
pub fn new(global: &GlobalScope, left: &XRView, right: &XRView) -> DomRoot<XRViewerPose> {
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<DomRoot<XRView>> {
vec![
DomRoot::from_ref(&self.left),
DomRoot::from_ref(&self.right),
]
}
}

View file

@ -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<XRViewport> {
pub fn new(
global: &GlobalScope,
x: u32,
y: u32,
width: u32,
height: u32,
) -> DomRoot<XRViewport> {
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
}
}
}

View file

@ -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<XRWebGLLayer> {
pub fn new(
global: &GlobalScope,
session: &XRSession,
context: &WebGLRenderingContext,
init: &XRWebGLLayerInit,
) -> DomRoot<XRWebGLLayer> {
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<DomRoot<Self>> {
pub fn Constructor(
global: &Window,
session: &XRSession,
context: &WebGLRenderingContext,
init: &XRWebGLLayerInit,
) -> Fallible<DomRoot<Self>> {
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,
))
}
}