diff --git a/webxr-api/device.rs b/webxr-api/device.rs index 9ed2ca10..bb636746 100644 --- a/webxr-api/device.rs +++ b/webxr-api/device.rs @@ -48,13 +48,9 @@ pub trait Device: 'static { Size2D::new(viewport.max_x(), viewport.max_y()) } - /// This method checks if the session has exited since last - /// wait_for_animation_frame call. - fn is_running(&self) -> bool; - /// This method should block waiting for the next frame, /// and return the information for it. - fn wait_for_animation_frame(&mut self) -> Frame; + fn wait_for_animation_frame(&mut self) -> Option; /// This method should render a GL texture to the device. /// While this method is being called, the device has unique access diff --git a/webxr-api/session.rs b/webxr-api/session.rs index 34e98dac..2432c1f7 100644 --- a/webxr-api/session.rs +++ b/webxr-api/session.rs @@ -205,12 +205,14 @@ impl SessionThread { } SessionMsg::RequestAnimationFrame(dest) => { let timestamp = self.timestamp; - if self.device.is_running() { - let frame = self.device.wait_for_animation_frame(); - let _ = dest.send((timestamp, frame)); - } else { - return false; - } + match self.device.wait_for_animation_frame() { + Some(frame) => { + let _ = dest.send((timestamp, frame)); + } + None => { + return false; + } + }; } SessionMsg::UpdateClipPlanes(near, far) => self.device.update_clip_planes(near, far), SessionMsg::RenderAnimationFrame => { diff --git a/webxr/glwindow/mod.rs b/webxr/glwindow/mod.rs index ce9402e6..744ccbd9 100644 --- a/webxr/glwindow/mod.rs +++ b/webxr/glwindow/mod.rs @@ -89,7 +89,6 @@ pub struct GlWindowDevice { read_fbo: GLuint, events: EventBuffer, clip_planes: ClipPlanes, - is_running: bool, } impl Device for GlWindowDevice { @@ -104,7 +103,7 @@ impl Device for GlWindowDevice { Views::Stereo(left, right) } - fn wait_for_animation_frame(&mut self) -> Frame { + fn wait_for_animation_frame(&mut self) -> Option { self.window.swap_buffers(); let translation = Vector3D::new(0.0, 0.0, -5.0); let transform = RigidTransform3D::from_translation(translation); @@ -113,11 +112,11 @@ impl Device for GlWindowDevice { } else { vec![] }; - Frame { + Some(Frame { transform, inputs: vec![], events, - } + }) } fn render_animation_frame( @@ -178,12 +177,7 @@ impl Device for GlWindowDevice { self.events.upgrade(dest) } - fn is_running(&self) -> bool { - self.is_running - } - fn quit(&mut self) { - self.is_running = false; self.events.callback(Event::SessionEnd); } @@ -210,7 +204,6 @@ impl GlWindowDevice { read_fbo, events: Default::default(), clip_planes: Default::default(), - is_running: true, }) } diff --git a/webxr/googlevr/device.rs b/webxr/googlevr/device.rs index d46d6058..746a0e65 100644 --- a/webxr/googlevr/device.rs +++ b/webxr/googlevr/device.rs @@ -63,7 +63,6 @@ pub(crate) struct GoogleVRDevice { depth: bool, clip_planes: ClipPlanes, input: Option, - is_running: bool, #[cfg(target_os = "android")] java_class: ndk::jclass, @@ -99,7 +98,6 @@ impl GoogleVRDevice { depth: false, clip_planes: Default::default(), input: None, - is_running: true, ctx: ctx.get(), controller_ctx: controller_ctx.get(), @@ -141,7 +139,6 @@ impl GoogleVRDevice { depth: false, clip_planes: Default::default(), input: None, - is_running: true, ctx: ctx.get(), controller_ctx: controller_ctx.get(), @@ -532,7 +529,7 @@ impl Device for GoogleVRDevice { } } - fn wait_for_animation_frame(&mut self) -> Frame { + fn wait_for_animation_frame(&mut self) -> Option { unsafe { self.acquire_frame(); } @@ -542,11 +539,11 @@ impl Device for GoogleVRDevice { vec![] }; // Predict head matrix - Frame { + Some(Frame { transform: self.fetch_head_matrix(), inputs: self.input_state(), events, - } + }) } fn render_animation_frame( @@ -582,14 +579,9 @@ impl Device for GoogleVRDevice { self.events.upgrade(dest); } - fn is_running(&self) -> bool { - self.is_running - } - fn quit(&mut self) { self.stop_present(); self.events.callback(Event::SessionEnd); - self.is_running = false; } fn set_quitter(&mut self, _: Quitter) { diff --git a/webxr/headless/mod.rs b/webxr/headless/mod.rs index 0235f3a7..74312d09 100644 --- a/webxr/headless/mod.rs +++ b/webxr/headless/mod.rs @@ -58,7 +58,6 @@ struct InputInfo { struct HeadlessDevice { gl: Rc, data: Arc>, - is_running: bool, } struct HeadlessDeviceData { @@ -120,13 +119,7 @@ impl Discovery for HeadlessDiscovery { } let gl = self.gl.clone(); let data = self.data.clone(); - xr.run_on_main_thread(move || { - Ok(HeadlessDevice { - gl, - data, - is_running: true, - }) - }) + xr.run_on_main_thread(move || Ok(HeadlessDevice { gl, data })) } fn supports_session(&self, mode: SessionMode) -> bool { @@ -143,7 +136,7 @@ impl Device for HeadlessDevice { self.data.lock().unwrap().views.clone() } - fn wait_for_animation_frame(&mut self) -> Frame { + fn wait_for_animation_frame(&mut self) -> Option { let mut data = self.data.lock().unwrap(); let transform = data.viewer_origin; let inputs = data @@ -162,11 +155,11 @@ impl Device for HeadlessDevice { } else { vec![] }; - Frame { + Some(Frame { transform, inputs, events, - } + }) } fn render_animation_frame(&mut self, _: GLuint, _: Size2D, sync: Option) { @@ -184,12 +177,7 @@ impl Device for HeadlessDevice { self.data.lock().unwrap().events.upgrade(dest) } - fn is_running(&self) -> bool { - self.is_running - } - fn quit(&mut self) { - self.is_running = false; self.data.lock().unwrap().events.callback(Event::SessionEnd); } diff --git a/webxr/magicleap/mod.rs b/webxr/magicleap/mod.rs index 81c48583..761e4816 100644 --- a/webxr/magicleap/mod.rs +++ b/webxr/magicleap/mod.rs @@ -98,7 +98,6 @@ pub struct MagicLeapDevice { frame_handle: MLHandle, cameras: MLGraphicsVirtualCameraInfoArray, view_update_needed: bool, - is_running: bool, } impl MagicLeapDiscovery { @@ -165,7 +164,6 @@ impl MagicLeapDevice { frame_handle, cameras, view_update_needed: false, - is_running: true, }; // Rather annoyingly, in order for the views to be available, we have to @@ -444,12 +442,7 @@ impl Device for MagicLeapDevice { // TODO: handle events } - fn is_running(&self) -> bool { - self.is_running - } - fn quit(&mut self) { - self.is_running = false; // TODO: handle quit } diff --git a/webxr/openxr/mod.rs b/webxr/openxr/mod.rs index f2f9865a..594bb364 100644 --- a/webxr/openxr/mod.rs +++ b/webxr/openxr/mod.rs @@ -122,7 +122,6 @@ struct OpenXrDevice { resource: ComPtr, device_context: ComPtr, device: ComPtr, - is_running: bool, } impl OpenXrDevice { @@ -261,11 +260,10 @@ impl OpenXrDevice { resource, device_context, device, - is_running: true, }) } - fn handle_openxr_events(&mut self) { + fn handle_openxr_events(&mut self) -> bool { use openxr::Event::*; loop { let mut buffer = openxr::EventDataBuffer::new(); @@ -275,12 +273,18 @@ impl OpenXrDevice { openxr::SessionState::STOPPING => { self.events.callback(Event::SessionEnd); self.session.end().unwrap(); - self.is_running = false; + return false; + } + openxr::SessionState::EXITING | openxr::SessionState::LOSS_PENDING => { + break; } _ => { // FIXME: Handle other states } }, + Some(InstanceLossPending(_)) => { + break; + } Some(_) => { // FIXME: Handle other events } @@ -290,6 +294,7 @@ impl OpenXrDevice { } } } + true } } @@ -336,12 +341,11 @@ impl Device for OpenXrDevice { Views::Stereo(left_view, right_view) } - fn is_running(&self) -> bool { - self.is_running - } - - fn wait_for_animation_frame(&mut self) -> Frame { - self.handle_openxr_events(); + fn wait_for_animation_frame(&mut self) -> Option { + if !self.handle_openxr_events() { + // Session is not running anymore. + return None; + } self.frame_state = self.frame_waiter.wait().expect("error waiting for frame"); // XXXManishearth should we check frame_state.should_render? let (_view_flags, views) = self @@ -361,11 +365,11 @@ impl Device for OpenXrDevice { } else { vec![] }; - Frame { + Some(Frame { transform, inputs: vec![], events, - } + }) } fn render_animation_frame(