summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2020-09-28 18:23:24 +0000
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2020-09-28 18:23:24 +0000
commit05a696cf1beb5d63f0b7c5da9c0eb868b36a6b98 (patch)
treeb14e402e870d979e7932d25659245f2b3dcbe913
parenta57fdf911bba9edd775a25fc125071764b354ea2 (diff)
parentb0111a51310f0a1c96c8f11cb0fcac598dfedc14 (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.cpp41
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;
}