diff --git a/Cargo.lock b/Cargo.lock index f66040ae51b..0f5ee9f1977 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 caad696d40c..020b39cc9ae 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 18b632d4cb8..180e29194e8 100644 --- a/wgpu-hal/src/vulkan/instance.rs +++ b/wgpu-hal/src/vulkan/instance.rs @@ -218,6 +218,7 @@ impl super::Instance { entry: ash::Entry, raw_instance: ash::Instance, driver_api_version: u32, + platform_version: u32, extensions: Vec<&'static CStr>, flags: crate::InstanceFlags, has_nv_optimus: bool, @@ -283,6 +284,7 @@ impl super::Instance { entry, has_nv_optimus, driver_api_version, + platform_version, }), extensions, }) @@ -557,6 +559,18 @@ impl crate::Instance for super::Instance { layers }; + #[cfg(target_os = "android")] + let platform_version = { + let mut prop = android_properties::getprop("ro.build.version.sdk"); + if let Some(val) = prop.value() { + u32::from_str_radix(&val, 10).expect("Failed to parse ro.build.version.sdk property") + } else { + panic!("Couldn't read ro.build.version.sdk system property"); + } + }; + #[cfg(not(target_os = "android"))] + let platform_version = 0; + let vk_instance = { let str_pointers = layers .iter() @@ -583,6 +597,7 @@ impl crate::Instance for super::Instance { entry, vk_instance, driver_api_version, + platform_version, extensions, desc.flags, has_nv_optimus, @@ -711,11 +726,26 @@ 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 logs 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") { + if self.instance.platform_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 b3e1a0aa7f7..a007eaa9c23 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, + platform_version: u32, driver_api_version: u32, }