diff options
author | Steven Laver <lavers@google.com> | 2019-05-08 06:18:42 -0700 |
---|---|---|
committer | Steven Laver <lavers@google.com> | 2019-05-08 06:18:42 -0700 |
commit | 4a30c150e58ec67edb92a7bec5ea48cebd6b90d4 (patch) | |
tree | 6d902794d7e59acd54f54ef235feb75becfb01e3 /libs/hwui/renderthread/VulkanManager.cpp | |
parent | a6c7c402af360214e509d15980957e74fc673f42 (diff) | |
parent | e4f4eabc31685c001c2b46d8fa87b443f4af5b21 (diff) |
Merge QP1A.190501.001
Change-Id: I0f9f887d6a33702a6988709d8296731cfdb8f73d
Diffstat (limited to 'libs/hwui/renderthread/VulkanManager.cpp')
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.cpp | 128 |
1 files changed, 40 insertions, 88 deletions
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 5edf3301b2e8..62fd48940870 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -58,10 +58,6 @@ static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& fe #define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F) void VulkanManager::destroy() { - // We don't need to explicitly free the command buffer since it automatically gets freed when we - // delete the VkCommandPool below. - mDummyCB = VK_NULL_HANDLE; - if (VK_NULL_HANDLE != mCommandPool) { mDestroyCommandPool(mDevice, mCommandPool, nullptr); mCommandPool = VK_NULL_HANDLE; @@ -376,12 +372,6 @@ void VulkanManager::initialize() { } LOG_ALWAYS_FATAL_IF(mCommandPool == VK_NULL_HANDLE); - if (!setupDummyCommandBuffer()) { - this->destroy(); - // Pass through will crash on next line. - } - LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE); - mGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue); if (Properties::enablePartialUpdates && Properties::useBufferAge) { @@ -488,6 +478,22 @@ Frame VulkanManager::dequeueNextBuffer(VulkanSurface* surface) { return Frame(surface->logicalWidth(), surface->logicalHeight(), bufferAge); } +struct DestroySemaphoreInfo { + PFN_vkDestroySemaphore mDestroyFunction; + VkDevice mDevice; + VkSemaphore mSemaphore; + + DestroySemaphoreInfo(PFN_vkDestroySemaphore destroyFunction, VkDevice device, + VkSemaphore semaphore) + : mDestroyFunction(destroyFunction), mDevice(device), mSemaphore(semaphore) {} +}; + +static void destroy_semaphore(void* context) { + DestroySemaphoreInfo* info = reinterpret_cast<DestroySemaphoreInfo*>(context); + info->mDestroyFunction(info->mDevice, info->mSemaphore, nullptr); + delete info; +} + void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) { if (CC_UNLIKELY(Properties::waitForGpuCompletion)) { ATRACE_NAME("Finishing GPU work"); @@ -517,9 +523,12 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) backendSemaphore.initVulkan(semaphore); int fenceFd = -1; + DestroySemaphoreInfo* destroyInfo = new DestroySemaphoreInfo(mDestroySemaphore, mDevice, + semaphore); GrSemaphoresSubmitted submitted = bufferInfo->skSurface->flush(SkSurface::BackendSurfaceAccess::kPresent, - SkSurface::kNone_FlushFlags, 1, &backendSemaphore); + kNone_GrFlushFlags, 1, &backendSemaphore, + destroy_semaphore, destroyInfo); if (submitted == GrSemaphoresSubmitted::kYes) { VkSemaphoreGetFdInfoKHR getFdInfo; getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; @@ -535,12 +544,6 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) } surface->presentCurrentBuffer(dirtyRect, fenceFd); - - // Exporting a semaphore with copy transference via vkGetSemaphoreFdKHR, has the same effect of - // destroying the semaphore and creating a new one with the same handle, and the payloads - // ownership is move to the Fd we created. Thus the semaphore is in a state that we can delete - // it and we don't need to wait on the command buffer we submitted to finish. - mDestroySemaphore(mDevice, semaphore, nullptr); } void VulkanManager::destroySurface(VulkanSurface* surface) { @@ -566,38 +569,7 @@ VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode col *this, extraBuffers); } -bool VulkanManager::setupDummyCommandBuffer() { - if (mDummyCB != VK_NULL_HANDLE) { - return true; - } - - VkCommandBufferAllocateInfo commandBuffersInfo; - memset(&commandBuffersInfo, 0, sizeof(VkCommandBufferAllocateInfo)); - commandBuffersInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - commandBuffersInfo.pNext = nullptr; - commandBuffersInfo.commandPool = mCommandPool; - commandBuffersInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - commandBuffersInfo.commandBufferCount = 1; - - VkResult err = mAllocateCommandBuffers(mDevice, &commandBuffersInfo, &mDummyCB); - if (err != VK_SUCCESS) { - // It is probably unnecessary to set this back to VK_NULL_HANDLE, but we set it anyways to - // make sure the driver didn't set a value and then return a failure. - mDummyCB = VK_NULL_HANDLE; - return false; - } - - VkCommandBufferBeginInfo beginInfo; - memset(&beginInfo, 0, sizeof(VkCommandBufferBeginInfo)); - beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - - mBeginCommandBuffer(mDummyCB, &beginInfo); - mEndCommandBuffer(mDummyCB); - return true; -} - -status_t VulkanManager::fenceWait(sp<Fence>& fence) { +status_t VulkanManager::fenceWait(sp<Fence>& fence, GrContext* grContext) { if (!hasVkContext()) { ALOGE("VulkanManager::fenceWait: VkDevice not initialized"); return INVALID_OPERATION; @@ -630,36 +602,22 @@ status_t VulkanManager::fenceWait(sp<Fence>& fence) { err = mImportSemaphoreFdKHR(mDevice, &importInfo); if (VK_SUCCESS != err) { + mDestroySemaphore(mDevice, semaphore, nullptr); ALOGE("Failed to import semaphore, err: %d", err); return UNKNOWN_ERROR; } - LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE); + GrBackendSemaphore beSemaphore; + beSemaphore.initVulkan(semaphore); - VkPipelineStageFlags waitDstStageFlags = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + // Skia takes ownership of the semaphore and will delete it once the wait has finished. + grContext->wait(1, &beSemaphore); + grContext->flush(); - VkSubmitInfo submitInfo; - memset(&submitInfo, 0, sizeof(VkSubmitInfo)); - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 1; - // Wait to make sure aquire semaphore set above has signaled. - submitInfo.pWaitSemaphores = &semaphore; - submitInfo.pWaitDstStageMask = &waitDstStageFlags; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &mDummyCB; - submitInfo.signalSemaphoreCount = 0; - - mQueueSubmit(mGraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); - - // On Android when we import a semaphore, it is imported using temporary permanence. That - // means as soon as we queue the semaphore for a wait it reverts to its previous permanent - // state before importing. This means it will now be in an idle state with no pending - // signal or wait operations, so it is safe to immediately delete it. - mDestroySemaphore(mDevice, semaphore, nullptr); return OK; } -status_t VulkanManager::createReleaseFence(sp<Fence>& nativeFence) { +status_t VulkanManager::createReleaseFence(sp<Fence>& nativeFence, GrContext* grContext) { if (!hasVkContext()) { ALOGE("VulkanManager::createReleaseFence: VkDevice not initialized"); return INVALID_OPERATION; @@ -681,20 +639,20 @@ status_t VulkanManager::createReleaseFence(sp<Fence>& nativeFence) { return INVALID_OPERATION; } - LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE); + GrBackendSemaphore backendSemaphore; + backendSemaphore.initVulkan(semaphore); - VkSubmitInfo submitInfo; - memset(&submitInfo, 0, sizeof(VkSubmitInfo)); - submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submitInfo.waitSemaphoreCount = 0; - submitInfo.pWaitSemaphores = nullptr; - submitInfo.pWaitDstStageMask = nullptr; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &mDummyCB; - submitInfo.signalSemaphoreCount = 1; - submitInfo.pSignalSemaphores = &semaphore; + DestroySemaphoreInfo* destroyInfo = new DestroySemaphoreInfo(mDestroySemaphore, mDevice, + semaphore); + GrSemaphoresSubmitted submitted = + grContext->flush(kNone_GrFlushFlags, 1, &backendSemaphore, + destroy_semaphore, destroyInfo); - mQueueSubmit(mGraphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); + if (submitted == GrSemaphoresSubmitted::kNo) { + ALOGE("VulkanManager::createReleaseFence: Failed to submit semaphore"); + mDestroySemaphore(mDevice, semaphore, nullptr); + return INVALID_OPERATION; + } VkSemaphoreGetFdInfoKHR getFdInfo; getFdInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR; @@ -711,12 +669,6 @@ status_t VulkanManager::createReleaseFence(sp<Fence>& nativeFence) { } nativeFence = new Fence(fenceFd); - // Exporting a semaphore with copy transference via vkGetSemahporeFdKHR, has the same effect of - // destroying the semaphore and creating a new one with the same handle, and the payloads - // ownership is move to the Fd we created. Thus the semahpore is in a state that we can delete - // it and we don't need to wait on the command buffer we submitted to finish. - mDestroySemaphore(mDevice, semaphore, nullptr); - return OK; } |