diff --git a/README.md b/README.md index c6208edab..46d4a97dd 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,18 @@ path = "$HOME/.android/debug.keystore" keystore_password = "android" ``` +> [!NOTE] +> As `cargo apk` does not allow passing command line arguments or environment variables to the app when ran, these can be embedded into the +> program at compile time (currently for Android only) +> `with_winit` currently supports the environment variables: +> - `VELLO_STATIC_LOG`, which is equivalent to `RUST_LOG` +> - `VELLO_STATIC_ARGS`, which is equivalent to passing in command line arguments + +For example (with unix shell environment variable syntax): +```sh +VELLO_STATIC_LOG="vello=trace" VELLO_STATIC_ARGS="--test-scenes" cargo apk run -p with_winit --lib +``` + ## Community Discussion of Vello development happens in the [Xi Zulip](https://xi.zulipchat.com/), specifically the [#gpu stream](https://xi.zulipchat.com/#narrow/stream/197075-gpu). All public content can be read without logging in. diff --git a/examples/with_winit/Cargo.toml b/examples/with_winit/Cargo.toml index 7f64be1a3..e17aae88d 100644 --- a/examples/with_winit/Cargo.toml +++ b/examples/with_winit/Cargo.toml @@ -38,7 +38,6 @@ notify-debouncer-mini = "0.3" [target.'cfg(target_os = "android")'.dependencies] winit = { version = "0.29.12", features = ["android-native-activity"] } android_logger = "0.13.3" -jni = "0.21" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" diff --git a/examples/with_winit/src/lib.rs b/examples/with_winit/src/lib.rs index 5875234cd..718552260 100644 --- a/examples/with_winit/src/lib.rs +++ b/examples/with_winit/src/lib.rs @@ -732,17 +732,15 @@ fn android_main(app: AndroidApp) { config.with_max_level(log::LevelFilter::Warn) }; android_logger::init_once(config); - let cache_dir = get_cache_directory(&app) - .inspect(|path| log::info!("Got cache directory {path:?}")) - .inspect_err(|e| log::warn!("Failed to get cache directory: {e}")) - .ok(); - let _ = cache_dir; + let event_loop = EventLoopBuilder::with_user_event() .with_android_app(app) .build() .expect("Required to continue"); let args = if let Some(args) = option_env!("VELLO_STATIC_ARGS") { - // We split by whitespace here to allow + // We split by whitespace here to allow passing multiple arguments + // In theory, we could do more advanced parsing/splitting (e.g. using quotes), + // but that would require a lot more effort Args::parse_from(args.split_ascii_whitespace()) } else { Args::parse() @@ -756,29 +754,3 @@ fn android_main(app: AndroidApp) { run(event_loop, args, scenes, render_cx); } - -#[cfg(target_os = "android")] -fn get_cache_directory(app: &AndroidApp) -> anyhow::Result { - use std::path::PathBuf; - - use anyhow::Context; - - let app_jobject = unsafe { jni::objects::JObject::from_raw(app.activity_as_ptr().cast()) }; - // If we got a null VM, we can't pass up - let jvm = unsafe { jni::JavaVM::from_raw(app.vm_as_ptr().cast()).context("Making VM")? }; - let mut env = jvm.attach_current_thread().context("Attaching to thread")?; - let res = env - .call_method(app_jobject, "getCacheDir", "()Ljava/io/File;", &[]) - .context("Calling GetCacheDir")?; - let file = res.l().context("Converting to JObject")?; - let directory_path = env - .call_method(file, "getAbsolutePath", "()Ljava/lang/String;", &[]) - .context("Calling `getAbsolutePath`")?; - let string = directory_path.l().context("Converting to a string")?.into(); - let string = env - .get_string(&string) - .context("Converting into a Rust string")?; - let string: String = string.into(); - // TODO: Also get the quota. This appears to be more involved, requiring a worker thread and being asynchronous - Ok(PathBuf::from(string).join("vello")) -} diff --git a/src/shaders.rs b/src/shaders.rs index 1d7843379..887eeb039 100644 --- a/src/shaders.rs +++ b/src/shaders.rs @@ -80,8 +80,6 @@ pub fn full_shaders( engine: &mut WgpuEngine, options: &RendererOptions, ) -> Result { - use std::time::Instant; - use crate::wgpu_engine::CpuShaderType; use BindType::*; let imports = SHARED_SHADERS @@ -98,7 +96,6 @@ pub fn full_shaders( let mut force_gpu = false; let force_gpu_from: Option<&str> = None; - let mut previous_done = Instant::now(); // Uncomment this to force use of GPU shaders from the specified shader and later even // if `engine.use_cpu` is specified. @@ -111,13 +108,7 @@ pub fn full_shaders( } let processed = preprocess::preprocess(shader!(stringify!($name)), &$defines, &imports).into(); - // Preprocessing is very quick, so we don't need to take this time into account - // log::debug!( - // "Pre-processing {} took {:?}", - // $label, - // previous_done.elapsed() - // ); - let shader = engine.add_shader( + engine.add_shader( device, $label, processed, @@ -127,15 +118,7 @@ pub fn full_shaders( } else { $cpu }, - )?; - let now = Instant::now(); - log::trace!( - "Processing and compiling {} took {:?}", - $label, - now - previous_done - ); - previous_done = now; - shader + )? }}; ($name:ident, $bindings:expr, $defines:expr, $cpu:expr) => {{ add_shader!($name, stringify!($name), $bindings, &$defines, $cpu) diff --git a/src/wgpu_engine.rs b/src/wgpu_engine.rs index f59c4f92b..0c8ff0043 100644 --- a/src/wgpu_engine.rs +++ b/src/wgpu_engine.rs @@ -5,7 +5,6 @@ use std::{ borrow::Cow, cell::RefCell, collections::{hash_map::Entry, HashMap, HashSet}, - time::Instant, }; use wgpu::{ @@ -264,10 +263,7 @@ impl WgpuEngine { CpuShaderType::Missing => {} } } - let shader_module = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: Some(label), - source: wgpu::ShaderSource::Wgsl(wgsl), - }); + let entries = layout .iter() .enumerate()