diff options
| author | 2020-09-28 18:23:24 +0000 | |
|---|---|---|
| committer | 2020-09-28 18:23:24 +0000 | |
| commit | 05a696cf1beb5d63f0b7c5da9c0eb868b36a6b98 (patch) | |
| tree | b14e402e870d979e7932d25659245f2b3dcbe913 | |
| parent | a57fdf911bba9edd775a25fc125071764b354ea2 (diff) | |
| parent | b0111a51310f0a1c96c8f11cb0fcac598dfedc14 (diff) | |
Merge "Vulkan: swapchain images to be early released must be idle" am: b0111a5131
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1437451
Change-Id: I4e1e62c6927081b9f03417938efec65b7f546735
| -rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index d3ed88d2eb..6b51817caa 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -258,7 +258,11 @@ struct Swapchain { bool shared; struct Image { - Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {} + Image() + : image(VK_NULL_HANDLE), + dequeue_fence(-1), + release_fence(-1), + dequeued(false) {} VkImage image; android::sp<ANativeWindowBuffer> buffer; // The fence is only valid when the buffer is dequeued, and should be @@ -266,6 +270,10 @@ struct Swapchain { // closed: either by closing it explicitly when queueing the buffer, // or by passing ownership e.g. to ANativeWindow::cancelBuffer(). int dequeue_fence; + // This fence is a dup of the sync fd returned from the driver via + // vkQueueSignalReleaseImageANDROID upon vkQueuePresentKHR. We must + // ensure it is closed upon re-presenting or releasing the image. + int release_fence; bool dequeued; } images[android::BufferQueueDefs::NUM_BUFFER_SLOTS]; @@ -280,10 +288,19 @@ Swapchain* SwapchainFromHandle(VkSwapchainKHR handle) { return reinterpret_cast<Swapchain*>(handle); } +static bool IsFencePending(int fd) { + if (fd < 0) + return false; + + errno = 0; + return sync_wait(fd, 0 /* timeout */) == -1 && errno == ETIME; +} + void ReleaseSwapchainImage(VkDevice device, ANativeWindow* window, int release_fence, - Swapchain::Image& image) { + Swapchain::Image& image, + bool defer_if_pending) { ATRACE_CALL(); ALOG_ASSERT(release_fence == -1 || image.dequeued, @@ -319,10 +336,18 @@ void ReleaseSwapchainImage(VkDevice device, close(release_fence); } } - + release_fence = -1; image.dequeued = false; } + if (defer_if_pending && IsFencePending(image.release_fence)) + return; + + if (image.release_fence >= 0) { + close(image.release_fence); + image.release_fence = -1; + } + if (image.image) { ATRACE_BEGIN("DestroyImage"); GetData(device).driver.DestroyImage(device, image.image, nullptr); @@ -338,7 +363,8 @@ void OrphanSwapchain(VkDevice device, Swapchain* swapchain) { return; for (uint32_t i = 0; i < swapchain->num_images; i++) { if (!swapchain->images[i].dequeued) - ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i]); + ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i], + true); } swapchain->surface.swapchain_handle = VK_NULL_HANDLE; swapchain->timing.clear(); @@ -998,7 +1024,7 @@ static void DestroySwapchainInternal(VkDevice device, } for (uint32_t i = 0; i < swapchain->num_images; i++) { - ReleaseSwapchainImage(device, window, -1, swapchain->images[i]); + ReleaseSwapchainImage(device, window, -1, swapchain->images[i], false); } if (active) { @@ -1630,6 +1656,9 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { ALOGE("QueueSignalReleaseImageANDROID failed: %d", result); swapchain_result = result; } + if (img.release_fence >= 0) + close(img.release_fence); + img.release_fence = fence < 0 ? -1 : dup(fence); if (swapchain.surface.swapchain_handle == present_info->pSwapchains[sc]) { @@ -1763,7 +1792,7 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { WorstPresentResult(swapchain_result, VK_SUBOPTIMAL_KHR); } } else { - ReleaseSwapchainImage(device, nullptr, fence, img); + ReleaseSwapchainImage(device, nullptr, fence, img, true); swapchain_result = VK_ERROR_OUT_OF_DATE_KHR; } |