diff options
author | 2023-08-25 17:18:02 +0000 | |
---|---|---|
committer | 2023-08-25 17:32:50 +0000 | |
commit | 671a9f66236f8fdee2b15a3bc84cc1139ddda741 (patch) | |
tree | b89c193a6a33670238bfd61c3b1948403b87749f | |
parent | 025af291d696a93613e72b192dc8e910607ed538 (diff) |
Tighten up race condition risk in VulkanManager.
Checking for mDevice != null risks using inconsistent state if the
HardwareBufferUpload thread and the render thread race in setting up
vulkan. Instead, use an atomic bool and std::call_once to manage
initiaizing VulkanManager instances.
Bug: 280178674
Test: builds, boots
Change-Id: Ic0a1c3ae1939ece536eb57de369232b213236d11
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.cpp | 28 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.h | 5 |
2 files changed, 16 insertions, 17 deletions
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index a6e8c08ffbe8..e2b541aa5ecb 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -384,25 +384,23 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe } void VulkanManager::initialize() { - std::lock_guard _lock{mInitializeLock}; + std::call_once(mInitFlag, [&] { + GET_PROC(EnumerateInstanceVersion); + uint32_t instanceVersion; + LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); + LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); - if (mDevice != VK_NULL_HANDLE) { - return; - } - - GET_PROC(EnumerateInstanceVersion); - uint32_t instanceVersion; - LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); - LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); + this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); - this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); + mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); + mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue); - mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); - mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue); + if (Properties::enablePartialUpdates && Properties::useBufferAge) { + mSwapBehavior = SwapBehavior::BufferAge; + } - if (Properties::enablePartialUpdates && Properties::useBufferAge) { - mSwapBehavior = SwapBehavior::BufferAge; - } + mInitialized = true; + }); } static void onGrContextReleased(void* context) { diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index 2be1ffdbc423..dbef7fbd51b2 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -70,7 +70,7 @@ public: void initialize(); // Quick check to see if the VulkanManager has been initialized. - bool hasVkContext() { return mDevice != VK_NULL_HANDLE; } + bool hasVkContext() { return mInitialized; } // Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface VulkanSurface* createSurface(ANativeWindow* window, @@ -204,7 +204,8 @@ private: VkSemaphore mSwapSemaphore = VK_NULL_HANDLE; void* mDestroySemaphoreContext = nullptr; - std::mutex mInitializeLock; + std::once_flag mInitFlag; + std::atomic_bool mInitialized = false; }; } /* namespace renderthread */ |