diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index 152601c4f71..bd7b68f0154 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -664,6 +664,35 @@ impl VRDisplay { } } +// XR stuff +// XXXManishearth eventually we should share as much logic as possible +impl VRDisplay { + pub fn xr_present(&self, ctx: &WebGLRenderingContext) { + let layer_bounds = WebVRLayer::default(); + self.xr.set(true); + if self.presenting.get() { + *self.layer.borrow_mut() = layer_bounds; + self.layer_ctx.set(Some(&ctx)); + return; + } + + // Request Present + let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); + self.webvr_thread() + .send(WebVRMsg::RequestPresent( + self.global().pipeline_id(), + self.display.borrow().display_id, + sender, + )).unwrap(); + + if let Ok(()) = receiver.recv().unwrap() { + *self.layer.borrow_mut() = layer_bounds; + self.layer_ctx.set(Some(&ctx)); + self.init_present(); + } + } +} + // WebVR Spec: If the number of values in the leftBounds/rightBounds arrays // is not 0 or 4 for any of the passed layers the promise is rejected fn parse_bounds(src: &Option>>, dst: &mut [f32; 4]) -> Result<(), &'static str> { diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index d5571ac60c7..37154c34c6b 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -89,12 +89,15 @@ impl XRMethods for XR { }, }; + // XXXManishearth filter for displays which can_present if displays.is_empty() { promise.reject_error(Error::Security); } let session = XRSession::new(&self.global(), &displays[0]); promise.resolve_native(&session); + // whether or not we should initiate presentation is unclear + // https://github.com/immersive-web/webxr/issues/453 promise } diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 40ccb90fbd3..c652b80a3f9 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -5,6 +5,8 @@ use crate::dom::bindings::codegen::Bindings::XRBinding::XRSessionMode; use crate::dom::bindings::codegen::Bindings::XRSessionBinding; use crate::dom::bindings::codegen::Bindings::XRSessionBinding::XRSessionMethods; +use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods; +use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; @@ -12,6 +14,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::vrdisplay::VRDisplay; use crate::dom::xrlayer::XRLayer; +use crate::dom::xrwebgllayer::XRWebGLLayer; use dom_struct::dom_struct; use std::cell::Cell; @@ -66,7 +69,14 @@ impl XRSessionMethods for XRSession { } fn SetBaseLayer(&self, layer: Option<&XRLayer>) { - self.base_layer.set(layer) + self.base_layer.set(layer); + if let Some(layer) = layer { + let layer = layer.downcast::().unwrap(); + self.display.xr_present(&layer.Context()); + } else { + // steps unknown + // https://github.com/immersive-web/webxr/issues/453 + } } fn GetBaseLayer(&self) -> Option> {