mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
Fill in XR frame/pose/view implementations
This commit is contained in:
parent
7e043a33f1
commit
28dff81dbf
12 changed files with 152 additions and 38 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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();
|
||||
};
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue