Skip to content

Commit

Permalink
surface.acquire_texture: ignore timeout for Android < 11
Browse files Browse the repository at this point in the history
Prior to Android 11 then Android's vkAcquireNextImageKHR implementation was
non-conformant and didn't support timeouts and additionally would log a
verbose warning if a timeout was requested.

For reference this version of AcquireNextImageKHR doesn't support timeouts:
https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-mainline-10.0.0_r13/vulkan/libvulkan/swapchain.cpp#1426
and this version does:
https://android.googlesource.com/platform/frameworks/native/+/refs/tags/android-mainline-11.0.0_r45/vulkan/libvulkan/swapchain.cpp#1438
(i.e. timeout support was added in Android 11)

This patch adds a dependency on the `android-properties` crate that provides
a simple wrapper for the `__system_property_set` syscall so that the
platform version can be read via the `ro.build.version.sdk` property
and then for versions < 30 (corresponds to Android 11) any timeout
given to `acquire_texture` will be ignored (and `u64::MAX` will be
passed to Vulkan)
  • Loading branch information
rib committed Jun 4, 2022
1 parent 3657915 commit ea233d2
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
42 changes: 41 additions & 1 deletion wgpu-hal/src/vulkan/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -283,6 +286,7 @@ impl super::Instance {
entry,
has_nv_optimus,
driver_api_version,
android_sdk_version,
}),
extensions,
})
Expand Down Expand Up @@ -557,6 +561,28 @@ impl crate::Instance<super::Api> 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::<u32>() {
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()
Expand All @@ -583,6 +609,7 @@ impl crate::Instance<super::Api> for super::Instance {
entry,
vk_instance,
driver_api_version,
android_sdk_version,
extensions,
desc.flags,
has_nv_optimus,
Expand Down Expand Up @@ -711,11 +738,24 @@ impl crate::Surface<super::Api> for super::Surface {
) -> Result<Option<crate::AcquiredSurfaceTexture<super::Api>>, 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
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/src/vulkan/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ struct InstanceShared {
get_physical_device_properties: Option<khr::GetPhysicalDeviceProperties2>,
entry: ash::Entry,
has_nv_optimus: bool,
android_sdk_version: u32,
driver_api_version: u32,
}

Expand Down

0 comments on commit ea233d2

Please sign in to comment.