summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/VulkanManager.cpp
diff options
context:
space:
mode:
authorStan Iliev <stani@google.com>2019-03-21 11:34:15 -0400
committerStan Iliev <stani@google.com>2019-03-21 12:25:08 -0400
commit197843d031fc1480dbebb2ee1403742834d59fd2 (patch)
treed703048299713b8f0cac932e07a9864e61a37216 /libs/hwui/renderthread/VulkanManager.cpp
parent3e99fa7a272efe3a1c70fd96cb6444f75790811e (diff)
Block GPU on dequeue fence only if it has not signalled already
When Vulkan pipeline dequeues next frame at the beginning of DrawFrame, the dequeue fence has been signalled in most cases. This CL avoids additional work and saves about 0.3ms per frame. There is no need to create VkSemaphore and commit an empty command buffer to the queue if the fence has already signalled. Bug: 128998567 Test: Ran systrace on SelfieCity and observed better performance Change-Id: I3532b785fae90308d922a29f1698f5dbcbd79079
Diffstat (limited to 'libs/hwui/renderthread/VulkanManager.cpp')
-rw-r--r--libs/hwui/renderthread/VulkanManager.cpp73
1 files changed, 41 insertions, 32 deletions
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 7f979d6c3e53..b8ebf3bb0ca9 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -439,38 +439,47 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) {
LOG_ALWAYS_FATAL_IF(!bufferInfo->dequeued);
if (bufferInfo->dequeue_fence != -1) {
- int fence_clone = dup(bufferInfo->dequeue_fence);
- if (fence_clone == -1) {
- ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno), errno);
- sync_wait(bufferInfo->dequeue_fence, -1 /* forever */);
- } else {
- VkSemaphoreCreateInfo semaphoreInfo;
- semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
- semaphoreInfo.pNext = nullptr;
- semaphoreInfo.flags = 0;
- VkSemaphore semaphore;
- VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore);
- LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to create import semaphore, err: %d",
- err);
-
- VkImportSemaphoreFdInfoKHR importInfo;
- importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
- importInfo.pNext = nullptr;
- importInfo.semaphore = semaphore;
- importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT;
- importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
- importInfo.fd = fence_clone;
-
- err = mImportSemaphoreFdKHR(mDevice, &importInfo);
- LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to import semaphore, err: %d", err);
-
- GrBackendSemaphore backendSemaphore;
- backendSemaphore.initVulkan(semaphore);
- bufferInfo->skSurface->wait(1, &backendSemaphore);
- // The following flush blocks the GPU immediately instead of waiting for other
- // drawing ops. It seems dequeue_fence is not respected otherwise.
- //TODO: remove the flush after finding why backendSemaphore is not working.
- bufferInfo->skSurface->flush();
+ struct sync_file_info* finfo = sync_file_info(bufferInfo->dequeue_fence);
+ bool isSignalPending = false;
+ if (finfo != NULL) {
+ isSignalPending = finfo->status != 1;
+ sync_file_info_free(finfo);
+ }
+ if (isSignalPending) {
+ int fence_clone = dup(bufferInfo->dequeue_fence);
+ if (fence_clone == -1) {
+ ALOGE("dup(fence) failed, stalling until signalled: %s (%d)", strerror(errno),
+ errno);
+ sync_wait(bufferInfo->dequeue_fence, -1 /* forever */);
+ } else {
+ VkSemaphoreCreateInfo semaphoreInfo;
+ semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+ semaphoreInfo.pNext = nullptr;
+ semaphoreInfo.flags = 0;
+ VkSemaphore semaphore;
+ VkResult err = mCreateSemaphore(mDevice, &semaphoreInfo, nullptr, &semaphore);
+ LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to create import semaphore, err: %d",
+ err);
+
+ VkImportSemaphoreFdInfoKHR importInfo;
+ importInfo.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR;
+ importInfo.pNext = nullptr;
+ importInfo.semaphore = semaphore;
+ importInfo.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT;
+ importInfo.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
+ importInfo.fd = fence_clone;
+
+ err = mImportSemaphoreFdKHR(mDevice, &importInfo);
+ LOG_ALWAYS_FATAL_IF(VK_SUCCESS != err, "Failed to import semaphore, err: %d", err);
+
+ GrBackendSemaphore backendSemaphore;
+ backendSemaphore.initVulkan(semaphore);
+ bufferInfo->skSurface->wait(1, &backendSemaphore);
+ // The following flush blocks the GPU immediately instead of waiting for other
+ // drawing ops. It seems dequeue_fence is not respected otherwise.
+ //TODO: remove the flush after finding why backendSemaphore is not working.
+ bufferInfo->skSurface->flush();
+ }
}
}