//! On-device benchmark entry point. //! //! A deliberately plain Android app: no OpenXR, no swapchain, no camera. //! The only question it answers is how fast the Adreno runs a DINOv3 //! forward pass under meganeura, and mixing in the XR compositor would //! only add noise to that. //! //! ```text //! cargo apk run --manifest-path android/Cargo.toml --release --no-logcat //! adb logcat -v time | grep -E "dinovision|RustStdoutStderr" //! ``` //! //! The run is one-shot: results go to logcat and the process stays alive so //! the launcher does not report a crash. #![cfg(target_os = "android")] use android_activity::{AndroidApp, MainEvent, PollEvent}; #[unsafe(no_mangle)] fn android_main(app: AndroidApp) { android_logger::init_once( android_logger::Config::default() .with_max_level(log::LevelFilter::Info) .with_tag("dinovision"), ); // Vulkan initialization can fail on a device we have not accounted for; // a panic here would be reported as an opaque crash, so log the reason. std::panic::set_hook(Box::new(|info| { log::error!("panic: {info}"); })); log::info!("=== dinovision benchmark ==="); match std::panic::catch_unwind(run) { Ok(()) => log::info!("=== benchmark complete ==="), Err(_) => log::error!("=== benchmark aborted ==="), } // Stay responsive to the lifecycle instead of returning, which Android // treats as the activity dying. loop { app.poll_events(Some(std::time::Duration::from_millis(500)), |event| { if let PollEvent::Main(MainEvent::Destroy) = event { std::process::exit(0); } }); } } fn run() { let gpu = match dinovision::init_context(None) { Ok(gpu) => gpu, Err(e) => { log::error!("GPU context init failed: {e:?}"); return; } }; let iters = std::env::var("DINOVISION_ITERS") .ok() .and_then(|s| s.parse::().ok()) .unwrap_or(20); log::info!( "timing protocol: {} warmups, {iters} retained samples", std::env::var("DINOVISION_WARMUPS").unwrap_or_else(|_| "5".into()) ); let results = dinovision::bench::run_all(gpu, iters); log::info!("---- summary ----"); for t in &results { log::info!("{t}"); log::info!("DINOVISION_BENCH_JSON {}", t.json_line()); } }