Skip to content

Commit

Permalink
Clean up vrdisplay, set active immersive session correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Jul 11, 2019
1 parent 8780edb commit 57c8536
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 151 deletions.
155 changes: 14 additions & 141 deletions components/script/dom/vrdisplay.rs
Expand Up @@ -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::WindowMethods;
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::inheritance::Castable;
use crate::dom::bindings::num::Finite;
Expand All @@ -35,8 +34,6 @@ use crate::dom::vrpose::VRPose;
use crate::dom::vrstageparameters::VRStageParameters;
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use crate::dom::xrinputsource::XRInputSource;
use crate::dom::xrsession::XRSession;
use crate::dom::xrwebgllayer::XRWebGLLayer;
use crate::script_runtime::CommonScriptMsg;
use crate::script_runtime::ScriptThreadEventCategory::WebVREvent;
use crate::task_source::{TaskSource, TaskSourceName};
Expand Down Expand Up @@ -88,8 +85,6 @@ pub struct VRDisplay {
running_display_raf: Cell<bool>,
paused: 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?)
/// XR only
initialized_inputs: Cell<bool>,
Expand Down Expand Up @@ -166,7 +161,6 @@ impl VRDisplay {
// 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.
stopped_on_pause: Cell::new(false),
xr_session: MutNullableDom::default(),
initialized_inputs: Cell::new(false),
input_sources: DomRefCell::new(HashMap::new()),
}
Expand All @@ -179,14 +173,6 @@ impl VRDisplay {
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 {
Expand Down Expand Up @@ -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) {
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() {
return;
}
Expand Down Expand Up @@ -739,7 +686,6 @@ impl VRDisplay {
let this = address.clone();
let task = Box::new(task!(flush_renderstate_queue: move || {
let this = this.root();
this.process_renderstate_queue();
sender.send(Ok(this.vr_raf_update())).unwrap();
}));
js_sender
Expand Down Expand Up @@ -785,8 +731,6 @@ impl VRDisplay {

fn stop_present(&self) {
self.presenting.set(false);
let xr = self.global().as_window().Navigator().Xr();
xr.deactivate_session();
*self.frame_data_receiver.borrow_mut() = None;
self.has_raf_thread.set(false);
if let Some(api_sender) = self.api_sender() {
Expand Down Expand Up @@ -839,29 +783,24 @@ impl VRDisplay {

let now = self.global().as_window().Performance().Now();

if let Some(_) = self.xr_session.get() {
unreachable!("old webxr-on-webvr cruft")
} else {
self.running_display_raf.set(true);
let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]);
// Call registered VRDisplay.requestAnimationFrame callbacks.
for (_, callback) in callbacks.drain(..) {
if let Some(callback) = callback {
let _ = callback.Call__(Finite::wrap(*now), ExceptionHandling::Report);
}
self.running_display_raf.set(true);
let mut callbacks = mem::replace(&mut *self.raf_callback_list.borrow_mut(), vec![]);
// Call registered VRDisplay.requestAnimationFrame callbacks.
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.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();
match self.frame_data_status.get() {
VRFrameDataStatus::Synced => {
// Sync succeeded. Notify RAF thread.
Expand All @@ -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
// 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> {
Expand Down
4 changes: 0 additions & 4 deletions components/script/dom/vreyeparameters.rs
Expand Up @@ -62,10 +62,6 @@ impl VREyeParameters {

eye_parameters
}

pub fn offset_array(&self) -> [f32; 3] {
self.parameters.borrow().offset
}
}

impl VREyeParametersMethods for VREyeParameters {
Expand Down
5 changes: 3 additions & 2 deletions components/script/dom/xr.rs
Expand Up @@ -40,7 +40,7 @@ pub struct XR {
displays: DomRefCell<Vec<Dom<VRDisplay>>>,
gamepads: DomRefCell<Vec<Dom<Gamepad>>>,
pending_immersive_session: Cell<bool>,
active_immersive_session: MutNullableDom<VRDisplay>,
active_immersive_session: MutNullableDom<XRSession>,
test: MutNullableDom<XRTest>,
}

Expand Down Expand Up @@ -70,7 +70,7 @@ impl XR {
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
// ensure they never reach these codepaths
self.pending_immersive_session.set(false);
Expand Down Expand Up @@ -237,6 +237,7 @@ impl XR {
};

let session = XRSession::new(&self.global(), session);
self.set_active_immersive_session(&session);
promise.resolve_native(&session);
}

Expand Down
4 changes: 0 additions & 4 deletions components/script/dom/xrsession.rs
Expand Up @@ -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) {
let session = self.session.borrow();
with(&session)
Expand Down

0 comments on commit 57c8536

Please sign in to comment.