summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yiwei Zhang <zzyiwei@google.com> 2023-04-18 23:11:35 +0000
committer Yiwei Zhang <zzyiwei@google.com> 2023-04-19 15:25:26 +0000
commit3b88f31851e1e32236f4887c29f65c6532e0e907 (patch)
tree9fb644eba25d966eee8911f753466421238da296
parent7ec5b1d9f60728dd767cf6d6fd44a43360c7a7f9 (diff)
swapchain: avoid redundant disconnect/connect for new surface
Platform API contract ensures VkSurfaceKHR is created with a new or disconnected ANativeWindow. Then the first swapchain created against the new surface can skip the disconnect/connect of the native window, which saves 2 binder IPC calls. In theory, the same can be skipped until the first successful present call. We dirty the bit at the end of swapchain creation to avoid extra external synchronization. Bug: 275176234 Bug: 265763295 Test: no deadlock against ANGLE eglCreateWindowSurface Change-Id: Ic2d09e4547e0ec7e910863c77a4657d52e9366fd
-rw-r--r--vulkan/libvulkan/swapchain.cpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 922a44fa05..5965953b38 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -227,6 +227,10 @@ struct Surface {
android::sp<ANativeWindow> window;
VkSwapchainKHR swapchain_handle;
uint64_t consumer_usage;
+
+ // Indicate whether this surface has been used by a swapchain, no matter the
+ // swapchain is still current or has been destroyed.
+ bool used_by_swapchain;
};
VkSurfaceKHR HandleFromSurface(Surface* surface) {
@@ -601,6 +605,7 @@ VkResult CreateAndroidSurfaceKHR(
surface->window = pCreateInfo->window;
surface->swapchain_handle = VK_NULL_HANDLE;
+ surface->used_by_swapchain = false;
int err = native_window_get_consumer_usage(surface->window.get(),
&surface->consumer_usage);
if (err != android::OK) {
@@ -1394,14 +1399,20 @@ VkResult CreateSwapchainKHR(VkDevice device,
// orphans the previous buffers, getting us back to the state where we can
// dequeue all buffers.
//
+ // This is not necessary if the surface was never used previously.
+ //
// TODO(http://b/134186185) recycle swapchain images more efficiently
ANativeWindow* window = surface.window.get();
- err = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
- ALOGW_IF(err != android::OK, "native_window_api_disconnect failed: %s (%d)",
- strerror(-err), err);
- err = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
- ALOGW_IF(err != android::OK, "native_window_api_connect failed: %s (%d)",
- strerror(-err), err);
+ if (surface.used_by_swapchain) {
+ err = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+ ALOGW_IF(err != android::OK,
+ "native_window_api_disconnect failed: %s (%d)", strerror(-err),
+ err);
+ err = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
+ ALOGW_IF(err != android::OK,
+ "native_window_api_connect failed: %s (%d)", strerror(-err),
+ err);
+ }
err =
window->perform(window, NATIVE_WINDOW_SET_DEQUEUE_TIMEOUT, nsecs_t{-1});
@@ -1787,6 +1798,7 @@ VkResult CreateSwapchainKHR(VkDevice device,
android::GraphicsEnv::getInstance().setTargetStats(
android::GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN);
+ surface.used_by_swapchain = true;
surface.swapchain_handle = HandleFromSwapchain(swapchain);
*swapchain_handle = surface.swapchain_handle;
return VK_SUCCESS;