diff --git a/Cargo.toml b/Cargo.toml index 2f6c6f5..bb93ce7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,10 @@ openxr = { git = "https://github.com/Ralith/openxrs", rev = "0177d2d", features "static", ] } +[target.'cfg(target_os = "android")'.dependencies] +ndk-context = "0.1" +jni = "0.20" + [dev-dependencies] bevy = "0.12" bevy_rapier3d = { git = "https://github.com/devil-ira/bevy_rapier", branch = "bevy-0.12" } diff --git a/src/lib.rs b/src/lib.rs index d1bd31a..4705e54 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod resources; pub mod xr_init; pub mod xr_input; +use std::sync::atomic::AtomicBool; use std::sync::{Arc, Mutex}; use crate::xr_init::RenderRestartPlugin; @@ -70,6 +71,13 @@ pub struct FutureXrResources( impl Plugin for OpenXrPlugin { fn build(&self, app: &mut App) { + app.insert_resource(XrSessionRunning::new(AtomicBool::new(false))); + // #[cfg(target_os = "android")] + // { + // let ctx = ndk_context::android_context(); + // let vm = unsafe { jni::JavaVM::from_raw(ctx.vm().cast()) }.unwrap(); + // let env = vm.attach_current_thread_permanently(); + // } #[cfg(not(target_arch = "wasm32"))] match graphics::try_full_init( &mut app.world, @@ -91,8 +99,7 @@ impl Plugin for OpenXrPlugin { instance, ), }); - app.add_plugins(ExtractResourcePlugin::::default()); - app.insert_resource(XrEnableStatus::Enabled); + app.insert_resource(XrEnableStatus::Disabled); } Err(err) => { warn!("OpenXR Failed to initialize: {}", err); @@ -107,11 +114,17 @@ impl Plugin for OpenXrPlugin { app.add_plugins(RenderPlugin::default()); app.insert_resource(XrEnableStatus::Disabled); } + app.add_plugins(ExtractResourcePlugin::::default()); + app.add_systems( + PreUpdate, + (xr_poll_events, xr_begin_frame.run_if(xr_only())).chain(), + ); } fn finish(&self, app: &mut App) { // TODO: Split this up into the indevidual resources - if app.world.get_resource::() == Some(&XrEnableStatus::Enabled) { + // app.world.get_resource::() == Some(&XrEnableStatus::Enabled) + if true { warn!("finished xr init"); let xr_instance = app .world @@ -152,7 +165,6 @@ impl Plugin for OpenXrPlugin { size: **xr_resolution, format: **xr_format, }; - app.add_systems(PreUpdate, xr_begin_frame.run_if(xr_only())); let mut manual_texture_views = app.world.resource_mut::(); manual_texture_views.insert(LEFT_XR_TEXTURE_HANDLE, left); manual_texture_views.insert(RIGHT_XR_TEXTURE_HANDLE, right); @@ -215,18 +227,13 @@ impl PluginGroup for DefaultXrPlugins { } } -pub fn xr_begin_frame( - instance: Res, - session: Res, +pub fn xr_poll_events( + instance: Option>, + session: Option>, session_running: Res, - mut frame_state: ResMut, - mut frame_waiter: ResMut, - swapchain: Res, - mut views: ResMut, - input: Res, mut app_exit: EventWriter, ) { - { + if let (Some(instance), Some(session)) = (instance, session) { let _span = info_span!("xr_poll_events"); while let Some(event) = instance.poll_event(&mut Default::default()).unwrap() { use xr::Event::*; @@ -237,6 +244,7 @@ pub fn xr_begin_frame( info!("entered XR state {:?}", e.state()); match e.state() { xr::SessionState::READY => { + info!("Calling Session begin :3"); session.begin(VIEW_TYPE).unwrap(); session_running.store(true, std::sync::atomic::Ordering::Relaxed); } @@ -260,6 +268,16 @@ pub fn xr_begin_frame( } } } +} + +pub fn xr_begin_frame( + session: Res, + mut frame_state: ResMut, + mut frame_waiter: ResMut, + swapchain: Res, + mut views: ResMut, + input: Res, +) { { let _span = info_span!("xr_wait_frame").entered(); *frame_state = match frame_waiter.wait() { @@ -322,6 +340,8 @@ pub fn end_frame( swapchain: Option>, resolution: Option>, environment_blend_mode: Option>, + // _main_thread: NonSend<()>, + #[cfg(target_os = "android")] mut attached: Local, // passthrough_layer: Option>, ) { let xr_frame_state = xr_frame_state.unwrap(); @@ -330,6 +350,15 @@ pub fn end_frame( let swapchain = swapchain.unwrap(); let resolution = resolution.unwrap(); let environment_blend_mode = environment_blend_mode.unwrap(); + + #[cfg(target_os = "android")] + // if !*attached { + { + let ctx = ndk_context::android_context(); + let vm = unsafe { jni::JavaVM::from_raw(ctx.vm().cast()) }.unwrap(); + let env = vm.attach_current_thread_as_daemon(); + *attached = true; + } { let _span = info_span!("xr_release_image").entered(); swapchain.release_image().unwrap(); diff --git a/src/resources.rs b/src/resources.rs index b73cb1c..584cb16 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -45,6 +45,7 @@ impl Plugin for XrResourcePlugin { app.add_plugins(ExtractResourcePlugin::::default()); app.add_plugins(ExtractResourcePlugin::::default()); app.add_plugins(ExtractResourcePlugin::::default()); + app.add_plugins(ExtractResourcePlugin::::default()); } } @@ -218,7 +219,8 @@ impl SwapchainInner { // } // None => - self.stream.lock().unwrap().end( + info!("swapchain stream lock"); + let r = self.stream.lock().unwrap().end( predicted_display_time, environment_blend_mode, &[&xr::CompositionLayerProjection::new().space(stage).views(&[ @@ -241,7 +243,9 @@ impl SwapchainInner { .image_rect(rect), ), ])], - ) + ); + info!("swapchain stream done"); + r // } } } diff --git a/src/xr_init.rs b/src/xr_init.rs index 13ee973..fb4917a 100644 --- a/src/xr_init.rs +++ b/src/xr_init.rs @@ -114,7 +114,14 @@ impl Plugin for RenderRestartPlugin { .add_event::() .add_event::() .add_event::() - .add_systems(PostStartup, setup_xr.run_if(xr_only())) + .add_systems( + PreUpdate, + setup_xr + .run_if(|running: Res| { + running.load(std::sync::atomic::Ordering::Relaxed) + }) + .run_if(run_once()), + ) .add_systems( PostUpdate, update_xr_stuff.run_if(on_event::()), @@ -132,8 +139,14 @@ impl Plugin for RenderRestartPlugin { .chain(), ) .add_systems(XrCleanup, cleanup_oxr_session); - app.add_systems(PostUpdate, start_xr_session.run_if(on_event::())); - app.add_systems(PostUpdate, stop_xr_session.run_if(on_event::())); + app.add_systems( + PostUpdate, + start_xr_session.run_if(on_event::()), + ); + app.add_systems( + PostUpdate, + stop_xr_session.run_if(on_event::()), + ); } } @@ -162,6 +175,8 @@ fn add_schedules(app: &mut App) { } pub fn setup_xr(world: &mut World) { + info!("running setup schedule :3"); + world.insert_resource(XrEnableStatus::Enabled); world.run_schedule(XrPreSetup); world.run_schedule(XrSetup); world.run_schedule(XrPrePostSetup);