diff --git a/components/script/dom/vrdisplay.rs b/components/script/dom/vrdisplay.rs index e203a2779b7..6c4bea1568c 100644 --- a/components/script/dom/vrdisplay.rs +++ b/components/script/dom/vrdisplay.rs @@ -347,8 +347,9 @@ impl VRDisplayMethods for VRDisplay { }, }; - self.request_present(layer_bounds, Some(&layer_ctx), - promise.clone(), |p| p.resolve_native(&())); + self.request_present(layer_bounds, Some(&layer_ctx), Some(promise.clone()), |p| { + p.resolve_native(&()) + }); promise } @@ -437,15 +438,20 @@ impl VRDisplay { } } - pub fn request_present(&self, layer_bounds: WebVRLayer, - ctx: Option<&WebGLRenderingContext>, - promise: Rc, resolve: F) - where F: FnOnce(Rc) + Send + 'static { + pub fn request_present( + &self, + layer_bounds: WebVRLayer, + ctx: Option<&WebGLRenderingContext>, + promise: Option>, + resolve: F, + ) where + F: FnOnce(Rc) + Send + 'static, + { // WebVR spec: Repeat calls while already presenting will update the VRLayers being displayed. if self.presenting.get() { *self.layer.borrow_mut() = layer_bounds; self.layer_ctx.set(ctx); - resolve(promise); + promise.map(resolve); return; } @@ -458,7 +464,7 @@ impl VRDisplay { sender, )) .unwrap(); - let promise = TrustedPromise::new(promise); + let promise = promise.map(TrustedPromise::new); let this = Trusted::new(self); let ctx = ctx.map(|c| Trusted::new(c)); let global = self.global(); @@ -471,23 +477,22 @@ impl VRDisplay { let _ = task_source.queue_with_canceller( task!(vr_presenting: move || { let this = this.root(); - let promise = promise.root(); + let promise = promise.map(|p| p.root()); let ctx = ctx.map(|c| c.root()); match recv { Ok(()) => { *this.layer.borrow_mut() = layer_bounds; this.layer_ctx.set(ctx.as_ref().map(|c| &**c)); this.init_present(); - resolve(promise); + promise.map(resolve); }, Err(e) => { - promise.reject_native(&e); + promise.map(|p| p.reject_native(&e)); }, } }), &canceller, ); - }); } @@ -715,30 +720,19 @@ impl VRDisplay { // XR stuff // XXXManishearth eventually we should share as much logic as possible impl VRDisplay { - pub fn xr_present(&self, session: &XRSession, ctx: Option<&WebGLRenderingContext>) { + pub fn xr_present( + &self, + session: &XRSession, + ctx: Option<&WebGLRenderingContext>, + promise: Option>, + ) { let layer_bounds = WebVRLayer::default(); self.xr_session.set(Some(session)); - if self.presenting.get() { - *self.layer.borrow_mut() = layer_bounds; - self.layer_ctx.set(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(ctx); - self.init_present(); - } + let session = Trusted::new(session); + self.request_present(layer_bounds, ctx, promise, move |p| { + let session = session.root(); + p.resolve_native(&session); + }); } pub fn xr_raf(&self, callback: Rc) -> u32 { diff --git a/components/script/dom/xr.rs b/components/script/dom/xr.rs index a608d7e31a4..3e18ee0d279 100644 --- a/components/script/dom/xr.rs +++ b/components/script/dom/xr.rs @@ -95,9 +95,7 @@ impl XRMethods for XR { } let session = XRSession::new(&self.global(), &displays[0]); - // XXXManishearth we should actually xr_present() here instead of - // in XRSession::new, and resolve a promise based on it - promise.resolve_native(&session); + session.xr_present(promise.clone()); promise } } diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 73814a386b2..93837255f37 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -14,6 +14,7 @@ use crate::dom::bindings::reflector::reflect_dom_object; use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::dom::promise::Promise; use crate::dom::vrdisplay::VRDisplay; use crate::dom::xrlayer::XRLayer; use crate::dom::xrwebgllayer::XRWebGLLayer; @@ -37,13 +38,15 @@ impl XRSession { } pub fn new(global: &GlobalScope, display: &VRDisplay) -> DomRoot { - let ret = reflect_dom_object( + reflect_dom_object( Box::new(XRSession::new_inherited(display)), global, XRSessionBinding::Wrap, - ); - ret.display.xr_present(&ret, None); - ret + ) + } + + pub fn xr_present(&self, p: Rc) { + self.display.xr_present(self, None, Some(p)); } } @@ -78,7 +81,7 @@ impl XRSessionMethods for XRSession { self.base_layer.set(layer); if let Some(layer) = layer { let layer = layer.downcast::().unwrap(); - self.display.xr_present(&self, Some(&layer.Context())); + self.display.xr_present(&self, Some(&layer.Context()), None); } else { // steps unknown // https://github.com/immersive-web/webxr/issues/453