mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Use async VR presentation code for XRSession
This commit is contained in:
parent
9ddbf68cb3
commit
e2522d36ff
3 changed files with 37 additions and 42 deletions
|
@ -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<F>(&self, layer_bounds: WebVRLayer,
|
||||
ctx: Option<&WebGLRenderingContext>,
|
||||
promise: Rc<Promise>, resolve: F)
|
||||
where F: FnOnce(Rc<Promise>) + Send + 'static {
|
||||
pub fn request_present<F>(
|
||||
&self,
|
||||
layer_bounds: WebVRLayer,
|
||||
ctx: Option<&WebGLRenderingContext>,
|
||||
promise: Option<Rc<Promise>>,
|
||||
resolve: F,
|
||||
) where
|
||||
F: FnOnce(Rc<Promise>) + 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<Rc<Promise>>,
|
||||
) {
|
||||
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<XRFrameRequestCallback>) -> u32 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<XRSession> {
|
||||
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<Promise>) {
|
||||
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::<XRWebGLLayer>().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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue