summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2023-08-25 17:18:02 +0000
committer Alec Mouri <alecmouri@google.com> 2023-08-25 17:32:50 +0000
commit671a9f66236f8fdee2b15a3bc84cc1139ddda741 (patch)
treeb89c193a6a33670238bfd61c3b1948403b87749f
parent025af291d696a93613e72b192dc8e910607ed538 (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.cpp28
-rw-r--r--libs/hwui/renderthread/VulkanManager.h5
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 */