mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +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();
|
let displays = self.Xr().get_displays();
|
||||||
match displays {
|
match displays {
|
||||||
Ok(displays) => promise.resolve_native(&displays),
|
Ok(displays) => promise.resolve_native(&displays),
|
||||||
Err(e) => promise.reject_error(Error::Security),
|
Err(_) => promise.reject_error(Error::Security),
|
||||||
}
|
}
|
||||||
promise
|
promise
|
||||||
}
|
}
|
||||||
|
|
|
@ -683,7 +683,8 @@ impl VRDisplay {
|
||||||
self.global().pipeline_id(),
|
self.global().pipeline_id(),
|
||||||
self.display.borrow().display_id,
|
self.display.borrow().display_id,
|
||||||
sender,
|
sender,
|
||||||
)).unwrap();
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
if let Ok(()) = receiver.recv().unwrap() {
|
if let Ok(()) = receiver.recv().unwrap() {
|
||||||
*self.layer.borrow_mut() = layer_bounds;
|
*self.layer.borrow_mut() = layer_bounds;
|
||||||
|
|
|
@ -71,8 +71,9 @@ impl VRFrameData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FIXME(#22526) this should be in a better place
|
||||||
#[allow(unsafe_code)]
|
#[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>());
|
rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>());
|
||||||
unsafe {
|
unsafe {
|
||||||
let _ = Float32Array::create(cx, CreateWith::Slice(src), array.handle_mut());
|
let _ = Float32Array::create(cx, CreateWith::Slice(src), array.handle_mut());
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
// https://immersive-web.github.io/webxr/#xrframe-interface
|
// https://immersive-web.github.io/webxr/#xrframe-interface
|
||||||
|
|
||||||
[SecureContext, Exposed=Window] interface XRFrame {
|
[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);
|
// XRInputPose? getInputPose(XRInputSource inputSource, optional XRReferenceSpace referenceSpace);
|
||||||
};
|
};
|
|
@ -11,7 +11,7 @@ enum XREye {
|
||||||
|
|
||||||
[SecureContext, Exposed=Window] interface XRView {
|
[SecureContext, Exposed=Window] interface XRView {
|
||||||
readonly attribute XREye eye;
|
readonly attribute XREye eye;
|
||||||
// readonly attribute Float32Array projectionMatrix;
|
readonly attribute Float32Array projectionMatrix;
|
||||||
// readonly attribute Float32Array viewMatrix;
|
readonly attribute Float32Array viewMatrix;
|
||||||
// readonly attribute XRRigidTransform transform;
|
// readonly attribute XRRigidTransform transform;
|
||||||
};
|
};
|
|
@ -7,4 +7,6 @@
|
||||||
[SecureContext, Exposed=Window] interface XRViewerPose {
|
[SecureContext, Exposed=Window] interface XRViewerPose {
|
||||||
// readonly attribute XRRigidTransform transform;
|
// readonly attribute XRRigidTransform transform;
|
||||||
// readonly attribute FrozenArray<XRView> views;
|
// readonly attribute FrozenArray<XRView> views;
|
||||||
|
// workaround until we have FrozenArray
|
||||||
|
sequence<XRView> views();
|
||||||
};
|
};
|
|
@ -119,7 +119,7 @@ impl XR {
|
||||||
self.sync_display(&display);
|
self.sync_display(&display);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => return Err(()),
|
Err(_) => return Err(()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// WebVR spec: The Promise MUST be rejected if WebVR is not enabled/supported.
|
// WebVR spec: The Promise MUST be rejected if WebVR is not enabled/supported.
|
||||||
|
@ -127,7 +127,8 @@ impl XR {
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert from Dom to DomRoot
|
// convert from Dom to DomRoot
|
||||||
Ok(self.displays
|
Ok(self
|
||||||
|
.displays
|
||||||
.borrow()
|
.borrow()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|d| DomRoot::from_ref(&**d))
|
.map(|d| DomRoot::from_ref(&**d))
|
||||||
|
|
|
@ -3,28 +3,63 @@
|
||||||
* 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::XRFrameBinding;
|
use crate::dom::bindings::codegen::Bindings::XRFrameBinding;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
use crate::dom::bindings::codegen::Bindings::XRFrameBinding::XRFrameMethods;
|
||||||
use crate::dom::bindings::root::DomRoot;
|
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::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 dom_struct::dom_struct;
|
||||||
|
use webvr_traits::WebVRFrameData;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRFrame {
|
pub struct XRFrame {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
|
session: Dom<XRSession>,
|
||||||
|
#[ignore_malloc_size_of = "defined in rust-webvr"]
|
||||||
|
data: WebVRFrameData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRFrame {
|
impl XRFrame {
|
||||||
fn new_inherited() -> XRFrame {
|
fn new_inherited(session: &XRSession, data: WebVRFrameData) -> XRFrame {
|
||||||
XRFrame {
|
XRFrame {
|
||||||
reflector_: Reflector::new(),
|
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(
|
reflect_dom_object(
|
||||||
Box::new(XRFrame::new_inherited()),
|
Box::new(XRFrame::new_inherited(session, data)),
|
||||||
global,
|
global,
|
||||||
XRFrameBinding::Wrap,
|
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::reflector::{reflect_dom_object, Reflector};
|
||||||
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::vrframedata::create_typed_array;
|
||||||
use crate::dom::xrsession::XRSession;
|
use crate::dom::xrsession::XRSession;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use js::jsapi::{Heap, JSContext, JSObject};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
use webvr_traits::WebVRFrameData;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRView {
|
pub struct XRView {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
session: Dom<XRSession>,
|
session: Dom<XRSession>,
|
||||||
eye: XREye,
|
eye: XREye,
|
||||||
|
proj: Heap<*mut JSObject>,
|
||||||
|
view: Heap<*mut JSObject>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRView {
|
impl XRView {
|
||||||
|
@ -22,16 +28,34 @@ impl XRView {
|
||||||
XRView {
|
XRView {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
session: Dom::from_ref(session),
|
session: Dom::from_ref(session),
|
||||||
eye
|
eye,
|
||||||
|
proj: Heap::default(),
|
||||||
|
view: Heap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope, session: &XRSession, eye: XREye) -> DomRoot<XRView> {
|
pub fn new(
|
||||||
reflect_dom_object(
|
global: &GlobalScope,
|
||||||
|
session: &XRSession,
|
||||||
|
eye: XREye,
|
||||||
|
data: &WebVRFrameData,
|
||||||
|
) -> DomRoot<XRView> {
|
||||||
|
let ret = reflect_dom_object(
|
||||||
Box::new(XRView::new_inherited(session, eye)),
|
Box::new(XRView::new_inherited(session, eye)),
|
||||||
global,
|
global,
|
||||||
XRViewBinding::Wrap,
|
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 {
|
pub fn session(&self) -> &XRSession {
|
||||||
|
@ -44,4 +68,16 @@ impl XRViewMethods for XRView {
|
||||||
fn Eye(&self) -> XREye {
|
fn Eye(&self) -> XREye {
|
||||||
self.eye
|
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/. */
|
* 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;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XRViewerPoseBinding::XRViewerPoseMethods;
|
||||||
use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
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::globalscope::GlobalScope;
|
||||||
|
use crate::dom::xrview::XRView;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct XRViewerPose {
|
pub struct XRViewerPose {
|
||||||
reflector_: Reflector,
|
reflector_: Reflector,
|
||||||
|
left: Dom<XRView>,
|
||||||
|
right: Dom<XRView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRViewerPose {
|
impl XRViewerPose {
|
||||||
fn new_inherited() -> XRViewerPose {
|
fn new_inherited(left: &XRView, right: &XRView) -> XRViewerPose {
|
||||||
XRViewerPose {
|
XRViewerPose {
|
||||||
reflector_: Reflector::new(),
|
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(
|
reflect_dom_object(
|
||||||
Box::new(XRViewerPose::new_inherited()),
|
Box::new(XRViewerPose::new_inherited(left, right)),
|
||||||
global,
|
global,
|
||||||
XRViewerPoseBinding::Wrap,
|
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 {
|
fn new_inherited(x: u32, y: u32, width: u32, height: u32) -> XRViewport {
|
||||||
XRViewport {
|
XRViewport {
|
||||||
reflector_: Reflector::new(),
|
reflector_: Reflector::new(),
|
||||||
x, y, width, height
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope,
|
pub fn new(
|
||||||
x: u32, y: u32, width: u32, height: u32) -> DomRoot<XRViewport> {
|
global: &GlobalScope,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> DomRoot<XRViewport> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(XRViewport::new_inherited(x, y, width, height)),
|
Box::new(XRViewport::new_inherited(x, y, width, height)),
|
||||||
global,
|
global,
|
||||||
|
@ -56,4 +64,4 @@ impl XRViewportMethods for XRViewport {
|
||||||
fn Height(&self) -> i32 {
|
fn Height(&self) -> i32 {
|
||||||
self.height as i32
|
self.height as i32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods};
|
use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods};
|
||||||
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding;
|
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::XRWebGLLayerInit;
|
||||||
|
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
|
||||||
use crate::dom::bindings::error::Fallible;
|
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::bindings::root::{Dom, DomRoot};
|
||||||
use crate::dom::globalscope::GlobalScope;
|
use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
|
@ -32,8 +32,11 @@ pub struct XRWebGLLayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XRWebGLLayer {
|
impl XRWebGLLayer {
|
||||||
pub fn new_inherited(session: &XRSession, context: &WebGLRenderingContext,
|
pub fn new_inherited(
|
||||||
init: &XRWebGLLayerInit) -> XRWebGLLayer {
|
session: &XRSession,
|
||||||
|
context: &WebGLRenderingContext,
|
||||||
|
init: &XRWebGLLayerInit,
|
||||||
|
) -> XRWebGLLayer {
|
||||||
XRWebGLLayer {
|
XRWebGLLayer {
|
||||||
xrlayer: XRLayer::new_inherited(),
|
xrlayer: XRLayer::new_inherited(),
|
||||||
antialias: Cell::new(init.antialias),
|
antialias: Cell::new(init.antialias),
|
||||||
|
@ -45,8 +48,12 @@ impl XRWebGLLayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(global: &GlobalScope, session: &XRSession, context: &WebGLRenderingContext,
|
pub fn new(
|
||||||
init: &XRWebGLLayerInit) -> DomRoot<XRWebGLLayer> {
|
global: &GlobalScope,
|
||||||
|
session: &XRSession,
|
||||||
|
context: &WebGLRenderingContext,
|
||||||
|
init: &XRWebGLLayerInit,
|
||||||
|
) -> DomRoot<XRWebGLLayer> {
|
||||||
reflect_dom_object(
|
reflect_dom_object(
|
||||||
Box::new(XRWebGLLayer::new_inherited(session, context, init)),
|
Box::new(XRWebGLLayer::new_inherited(session, context, init)),
|
||||||
global,
|
global,
|
||||||
|
@ -54,9 +61,12 @@ impl XRWebGLLayer {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Constructor(global: &Window, session: &XRSession,
|
pub fn Constructor(
|
||||||
context: &WebGLRenderingContext,
|
global: &Window,
|
||||||
init: &XRWebGLLayerInit) -> Fallible<DomRoot<Self>> {
|
session: &XRSession,
|
||||||
|
context: &WebGLRenderingContext,
|
||||||
|
init: &XRWebGLLayerInit,
|
||||||
|
) -> Fallible<DomRoot<Self>> {
|
||||||
Ok(XRWebGLLayer::new(&global.global(), session, context, init))
|
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
|
// 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
|
// which need not be generally true for all devices, and will not work in
|
||||||
// inline VR mode
|
// 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