diff --git a/src/compositor.rs b/src/compositor.rs index 6eaebd68..3654a0cf 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1271,8 +1271,10 @@ impl FrameController { trace!("submitted {eye:?}"); if self.eyes_submitted.iter().all(|eye| eye.is_some()) { - let mut swapchain_data = self.swapchain_data.as_mut(); - if let Some(data) = &mut swapchain_data { + // If the session was restarted while no frame was begun, nothing has been acquired from the new swapchain yet, so there is nothing to release + if self.image_acquired + && let Some(data) = self.swapchain_data.as_mut() + { trace!("releasing image"); data.swapchain.release_image().unwrap(); } @@ -1942,6 +1944,28 @@ mod tests { f.check_frame_state(fakexr::FrameState::Waited); } + #[test] + fn explicit_timing_submit_without_begun_frame() { + let f = Fixture::new(); + f.comp.SetExplicitTimingMode( + vr::EVRCompositorTimingMode::Explicit_ApplicationPerformsPostPresentHandoff, + ); + + // The first Submit restarts the session while no frame has been begun, so the new swapchain has no acquired image when both eyes have been submitted + assert_eq!(f.wait_get_poses(), None); + assert_eq!(f.submit(vr::EVREye::Left), None); + assert_eq!(f.submit(vr::EVREye::Right), None); + + // The next frame should proceed as usual + assert_eq!(f.wait_get_poses(), None); + assert_eq!(f.comp.SubmitExplicitTimingData(), None); + f.check_frame_state(fakexr::FrameState::Begun); + assert_eq!(f.submit(vr::EVREye::Left), None); + assert_eq!(f.submit(vr::EVREye::Right), None); + f.comp.PostPresentHandoff(); + f.check_frame_state(fakexr::FrameState::Ended); + } + #[test] fn explicit_timing_unfocused() { let f = Fixture::new();