diff --git a/Cargo.lock b/Cargo.lock index f66040ae51..0f5ee9f197 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "android_glue" version = "0.2.3" @@ -2101,6 +2107,7 @@ dependencies = [ name = "wgpu-hal" version = "0.12.0" dependencies = [ + "android-properties", "arrayvec", "ash", "bit-set", diff --git a/wgpu-hal/Cargo.toml b/wgpu-hal/Cargo.toml index caad696d40..020b39cc9a 100644 --- a/wgpu-hal/Cargo.toml +++ b/wgpu-hal/Cargo.toml @@ -90,6 +90,9 @@ wasm-bindgen = { version = "0.2" } web-sys = { version = "0.3", features = ["Window", "HtmlCanvasElement", "WebGl2RenderingContext"] } js-sys = { version = "0.3" } +[target.'cfg(target_os = "android")'.dependencies] +android-properties = "0.2" + [dependencies.naga] git = "https://github.com/gfx-rs/naga" rev = "571302e" diff --git a/wgpu-hal/src/vulkan/instance.rs b/wgpu-hal/src/vulkan/instance.rs index ad137f090e..c12ef1b5c5 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -214,10 +214,13 @@ impl super::Instance { /// - `raw_instance` must be created respecting `driver_api_version`, `extensions` and `flags` /// - `extensions` must be a superset of `required_extensions()` and must be created from the /// same entry, driver_api_version and flags. + /// - `android_sdk_version` is ignored and can be `0` for all platforms besides Android + #[allow(clippy::too_many_arguments)] pub unsafe fn from_raw( entry: ash::Entry, raw_instance: ash::Instance, driver_api_version: u32, + android_sdk_version: u32, extensions: Vec<&'static CStr>, flags: crate::InstanceFlags, has_nv_optimus: bool, @@ -283,6 +286,7 @@ impl super::Instance { entry, has_nv_optimus, driver_api_version, + android_sdk_version, }), extensions, }) @@ -557,6 +561,28 @@ impl crate::Instance for super::Instance { layers }; + #[cfg(target_os = "android")] + let android_sdk_version = { + // See: https://developer.android.com/reference/android/os/Build.VERSION_CODES + let mut prop = android_properties::getprop("ro.build.version.sdk"); + if let Some(val) = prop.value() { + match val.parse::() { + Ok(sdk_ver) => sdk_ver, + Err(err) => { + log::error!( + "Couldn't parse Android's ro.build.version.sdk system property ({val}): {err}" + ); + 0 + } + } + } else { + log::error!("Couldn't read Android's ro.build.version.sdk system property"); + 0 + } + }; + #[cfg(not(target_os = "android"))] + let android_sdk_version = 0; + let vk_instance = { let str_pointers = layers .iter() @@ -583,6 +609,7 @@ impl crate::Instance for super::Instance { entry, vk_instance, driver_api_version, + android_sdk_version, extensions, desc.flags, has_nv_optimus, @@ -711,11 +738,24 @@ impl crate::Surface for super::Surface { ) -> Result>, crate::SurfaceError> { let sc = self.swapchain.as_mut().unwrap(); - let timeout_ns = match timeout { + let mut timeout_ns = match timeout { Some(duration) => duration.as_nanos() as u64, None => u64::MAX, }; + // AcquireNextImageKHR on Android (prior to Android 11) doesn't support timeouts + // and will also log verbose warnings if tying to use a timeout. + // + // Android 10 implementation for reference: + // https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-mainline-10.0.0_r13/vulkan/libvulkan/swapchain.cpp#1426 + // Android 11 implementation for reference: + // https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-mainline-11.0.0_r45/vulkan/libvulkan/swapchain.cpp#1438 + // + // Android 11 corresponds to an SDK_INT/ro.build.version.sdk of 30 + if cfg!(target_os = "android") && self.instance.android_sdk_version < 30 { + timeout_ns = u64::MAX; + } + // will block if no image is available let (index, suboptimal) = match sc diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index b3e1a0aa7f..f79d9e00ee 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -87,6 +87,7 @@ struct InstanceShared { get_physical_device_properties: Option, entry: ash::Entry, has_nv_optimus: bool, + android_sdk_version: u32, driver_api_version: u32, }