diff options
author | 2023-04-18 23:11:35 +0000 | |
---|---|---|
committer | 2023-04-19 15:25:26 +0000 | |
commit | 3b88f31851e1e32236f4887c29f65c6532e0e907 (patch) | |
tree | 9fb644eba25d966eee8911f753466421238da296 | |
parent | 7ec5b1d9f60728dd767cf6d6fd44a43360c7a7f9 (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.cpp | 24 |
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; |