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(