Clean up vrdisplay, set active immersive session correctly

This commit is contained in:
Manish Goregaokar 2019-07-08 14:30:51 -07:00
parent 8780edb165
commit 57c85361be
4 changed files with 18 additions and 152 deletions

View file

@ -15,7 +15,6 @@ use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGL
use crate::dom::bindings::codegen::Bindings::WindowBinding::FrameRequestCallback; use crate::dom::bindings::codegen::Bindings::WindowBinding::FrameRequestCallback;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods; use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateInit; use crate::dom::bindings::codegen::Bindings::XRRenderStateBinding::XRRenderStateInit;
use crate::dom::bindings::codegen::Bindings::XRWebGLLayerBinding::XRWebGLLayerMethods;
use crate::dom::bindings::error::Error; use crate::dom::bindings::error::Error;
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite; use crate::dom::bindings::num::Finite;
@ -35,8 +34,6 @@ use crate::dom::vrpose::VRPose;
use crate::dom::vrstageparameters::VRStageParameters; use crate::dom::vrstageparameters::VRStageParameters;
use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::xrinputsource::XRInputSource; use crate::dom::xrinputsource::XRInputSource;
use crate::dom::xrsession::XRSession;
use crate::dom::xrwebgllayer::XRWebGLLayer;
use crate::script_runtime::CommonScriptMsg; use crate::script_runtime::CommonScriptMsg;
use crate::script_runtime::ScriptThreadEventCategory::WebVREvent; use crate::script_runtime::ScriptThreadEventCategory::WebVREvent;
use crate::task_source::{TaskSource, TaskSourceName}; use crate::task_source::{TaskSource, TaskSourceName};
@ -88,8 +85,6 @@ pub struct VRDisplay {
running_display_raf: Cell<bool>, running_display_raf: Cell<bool>,
paused: Cell<bool>, paused: Cell<bool>,
stopped_on_pause: Cell<bool>, stopped_on_pause: Cell<bool>,
/// Whether or not this is XR mode, and the session
xr_session: MutNullableDom<XRSession>,
/// Have inputs been initialized? (i.e, has getInputSources() been called?) /// Have inputs been initialized? (i.e, has getInputSources() been called?)
/// XR only /// XR only
initialized_inputs: Cell<bool>, initialized_inputs: Cell<bool>,
@ -166,7 +161,6 @@ impl VRDisplay {
// This flag is set when the Display was presenting when it received a VR Pause event. // This flag is set when the Display was presenting when it received a VR Pause event.
// When the VR Resume event is received and the flag is set, VR presentation automatically restarts. // When the VR Resume event is received and the flag is set, VR presentation automatically restarts.
stopped_on_pause: Cell::new(false), stopped_on_pause: Cell::new(false),
xr_session: MutNullableDom::default(),
initialized_inputs: Cell::new(false), initialized_inputs: Cell::new(false),
input_sources: DomRefCell::new(HashMap::new()), input_sources: DomRefCell::new(HashMap::new()),
} }
@ -179,14 +173,6 @@ impl VRDisplay {
VRDisplayBinding::Wrap, VRDisplayBinding::Wrap,
) )
} }
pub fn left_eye_params_offset(&self) -> [f32; 3] {
self.left_eye_params.get().offset_array()
}
pub fn right_eye_params_offset(&self) -> [f32; 3] {
self.right_eye_params.get().offset_array()
}
} }
impl Drop for VRDisplay { impl Drop for VRDisplay {
@ -628,47 +614,8 @@ impl VRDisplay {
} }
} }
pub fn queue_renderstate(&self, state: &XRRenderStateInit, promise: Rc<Promise>) {
// can't clone dictionaries
let new_state = XRRenderStateInit {
depthNear: state.depthNear,
depthFar: state.depthFar,
baseLayer: state.baseLayer.clone(),
};
self.pending_renderstate_updates
.borrow_mut()
.push((new_state, promise));
if let Some(ref wakeup) = *self.raf_wakeup_sender.borrow() {
let _ = wakeup.send(());
}
}
fn process_renderstate_queue(&self) {
let mut updates = self.pending_renderstate_updates.borrow_mut();
debug_assert!(updates.is_empty() || self.xr_session.get().is_some());
for update in updates.drain(..) {
if let Some(near) = update.0.depthNear {
self.depth_near.set(*near);
}
if let Some(far) = update.0.depthFar {
self.depth_far.set(*far);
}
if let Some(ref layer) = update.0.baseLayer {
self.xr_session.get().unwrap().set_layer(&layer);
let layer = layer.downcast::<XRWebGLLayer>().unwrap();
self.layer_ctx.set(Some(&layer.Context()));
}
update.1.resolve_native(&());
}
}
fn init_present(&self) { fn init_present(&self) {
self.presenting.set(true); self.presenting.set(true);
let xr = self.global().as_window().Navigator().Xr();
xr.set_active_immersive_session(&self);
self.process_renderstate_queue();
if self.has_raf_thread.get() { if self.has_raf_thread.get() {
return; return;
} }
@ -739,7 +686,6 @@ impl VRDisplay {
let this = address.clone(); let this = address.clone();
let task = Box::new(task!(flush_renderstate_queue: move || { let task = Box::new(task!(flush_renderstate_queue: move || {
let this = this.root(); let this = this.root();
this.process_renderstate_queue();
sender.send(Ok(this.vr_raf_update())).unwrap(); sender.send(Ok(this.vr_raf_update())).unwrap();
})); }));
js_sender js_sender
@ -785,8 +731,6 @@ impl VRDisplay {
fn stop_present(&self) { fn stop_present(&self) {
self.presenting.set(false); self.presenting.set(false);
let xr = self.global().as_window().Navigator().Xr();
xr.deactivate_session();
*self.frame_data_receiver.borrow_mut() = None; *self.frame_data_receiver.borrow_mut() = None;
self.has_raf_thread.set(false); self.has_raf_thread.set(false);
if let Some(api_sender) = self.api_sender() { if let Some(api_sender) = self.api_sender() {
@ -839,29 +783,24 @@ impl VRDisplay {
let now = self.global().as_window().Performance().Now(); let now = self.global().as_window().Performance().Now();
if let Some(_) = self.xr_session.get() { self.running_display_raf.set(true);
unreachable!("old webxr-on-webvr cruft") let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]);
} else { // Call registered VRDisplay.requestAnimationFrame callbacks.
self.running_display_raf.set(true); for (_, callback) in callbacks.drain(..) {
let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]); if let Some(callback) = callback {
// Call registered VRDisplay.requestAnimationFrame callbacks. let _ = callback.Call__(Finite::wrap(*now), ExceptionHandling::Report);
for (_, callback) in callbacks.drain(..) {
if let Some(callback) = callback {
let _ = callback.Call__(Finite::wrap(*now), ExceptionHandling::Report);
}
}
self.running_display_raf.set(false);
if self.frame_data_status.get() == VRFrameDataStatus::Waiting {
// User didn't call getFrameData while presenting.
// We automatically reads the pending VRFrameData to avoid overflowing the IPC-Channel buffers.
// Show a warning as the WebVR Spec recommends.
warn!("WebVR: You should call GetFrameData while presenting");
self.sync_frame_data();
} }
} }
self.process_renderstate_queue(); self.running_display_raf.set(false);
if self.frame_data_status.get() == VRFrameDataStatus::Waiting {
// User didn't call getFrameData while presenting.
// We automatically reads the pending VRFrameData to avoid overflowing the IPC-Channel buffers.
// Show a warning as the WebVR Spec recommends.
warn!("WebVR: You should call GetFrameData while presenting");
self.sync_frame_data();
}
match self.frame_data_status.get() { match self.frame_data_status.get() {
VRFrameDataStatus::Synced => { VRFrameDataStatus::Synced => {
// Sync succeeded. Notify RAF thread. // Sync succeeded. Notify RAF thread.
@ -876,72 +815,6 @@ 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>,
promise: Option<Rc<Promise>>,
) {
let layer_bounds = WebVRLayer::default();
self.xr_session.set(Some(session));
let session = Trusted::new(session);
self.request_present(layer_bounds, ctx, promise, move |p| {
let session = session.root();
p.resolve_native(&session);
});
}
/// Initialize XRInputSources
fn initialize_inputs(&self) {
if self.initialized_inputs.get() {
return;
}
self.initialized_inputs.set(true);
let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap();
let display = self.display.borrow().display_id;
self.webvr_thread()
.send(WebVRMsg::GetGamepadsForDisplay(display, sender))
.unwrap();
match receiver.recv().unwrap() {
Ok(gamepads) => {
let global = self.global();
let session = self
.xr_session
.get()
.expect("initialize_inputs called on a VR session");
let roots: Vec<_> = gamepads
.into_iter()
.map(|g| {
(
g.1.gamepad_id,
XRInputSource::new(&global, &session, g.0, g.1),
)
})
.collect();
let mut inputs = self.input_sources.borrow_mut();
for (id, root) in &roots {
inputs.insert(*id, Dom::from_ref(&root));
}
},
Err(_) => {},
}
}
pub fn get_input_sources(&self) -> Vec<DomRoot<XRInputSource>> {
self.initialize_inputs();
self.input_sources
.borrow()
.iter()
.map(|(_, x)| DomRoot::from_ref(&**x))
.collect()
}
}
// WebVR Spec: If the number of values in the leftBounds/rightBounds arrays // 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 // is not 0 or 4 for any of the passed layers the promise is rejected
fn parse_bounds(src: &Option<Vec<Finite<f32>>>, dst: &mut [f32; 4]) -> Result<(), &'static str> { fn parse_bounds(src: &Option<Vec<Finite<f32>>>, dst: &mut [f32; 4]) -> Result<(), &'static str> {

View file

@ -62,10 +62,6 @@ impl VREyeParameters {
eye_parameters eye_parameters
} }
pub fn offset_array(&self) -> [f32; 3] {
self.parameters.borrow().offset
}
} }
impl VREyeParametersMethods for VREyeParameters { impl VREyeParametersMethods for VREyeParameters {

View file

@ -40,7 +40,7 @@ pub struct XR {
displays: DomRefCell<Vec<Dom<VRDisplay>>>, displays: DomRefCell<Vec<Dom<VRDisplay>>>,
gamepads: DomRefCell<Vec<Dom<Gamepad>>>, gamepads: DomRefCell<Vec<Dom<Gamepad>>>,
pending_immersive_session: Cell<bool>, pending_immersive_session: Cell<bool>,
active_immersive_session: MutNullableDom<VRDisplay>, active_immersive_session: MutNullableDom<XRSession>,
test: MutNullableDom<XRTest>, test: MutNullableDom<XRTest>,
} }
@ -70,7 +70,7 @@ impl XR {
self.pending_immersive_session.set(true) self.pending_immersive_session.set(true)
} }
pub fn set_active_immersive_session(&self, session: &VRDisplay) { pub fn set_active_immersive_session(&self, session: &XRSession) {
// XXXManishearth when we support non-immersive (inline) sessions we should // XXXManishearth when we support non-immersive (inline) sessions we should
// ensure they never reach these codepaths // ensure they never reach these codepaths
self.pending_immersive_session.set(false); self.pending_immersive_session.set(false);
@ -237,6 +237,7 @@ impl XR {
}; };
let session = XRSession::new(&self.global(), session); let session = XRSession::new(&self.global(), session);
self.set_active_immersive_session(&session);
promise.resolve_native(&session); promise.resolve_native(&session);
} }

View file

@ -88,10 +88,6 @@ impl XRSession {
) )
} }
pub fn set_layer(&self, layer: &XRLayer) {
self.base_layer.set(Some(layer))
}
pub fn with_session<F: FnOnce(&Session)>(&self, with: F) { pub fn with_session<F: FnOnce(&Session)>(&self, with: F) {
let session = self.session.borrow(); let session = self.session.borrow();
with(&session) with(&session)