diff options
-rw-r--r-- | libs/hwui/Properties.cpp | 15 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.cpp | 43 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.h | 23 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.h | 46 |
5 files changed, 74 insertions, 55 deletions
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp index ba44d056dda3..65f4e8c8ecec 100644 --- a/libs/hwui/Properties.cpp +++ b/libs/hwui/Properties.cpp @@ -15,7 +15,9 @@ */ #include "Properties.h" + #include "Debug.h" +#include "log/log_main.h" #ifdef __ANDROID__ #include "HWUIProperties.sysprop.h" #endif @@ -190,15 +192,12 @@ RenderPipelineType Properties::getRenderPipelineType() { return sRenderPipelineType; } -void Properties::overrideRenderPipelineType(RenderPipelineType type) { +void Properties::overrideRenderPipelineType(RenderPipelineType type, bool inUnitTest) { // If we're doing actual rendering then we can't change the renderer after it's been set. - // Unit tests can freely change this as often as it wants, though, as there's no actual - // GL rendering happening - if (sRenderPipelineType != RenderPipelineType::NotInitialized) { - LOG_ALWAYS_FATAL_IF(sRenderPipelineType != type, - "Trying to change pipeline but it's already set"); - return; - } + // Unit tests can freely change this as often as it wants. + LOG_ALWAYS_FATAL_IF(sRenderPipelineType != RenderPipelineType::NotInitialized && + sRenderPipelineType != type && !inUnitTest, + "Trying to change pipeline but it's already set."); sRenderPipelineType = type; } diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 85a0f4aa7809..1639143ef87c 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -238,7 +238,7 @@ public: static bool enableRTAnimations; // Used for testing only to change the render pipeline. - static void overrideRenderPipelineType(RenderPipelineType); + static void overrideRenderPipelineType(RenderPipelineType, bool inUnitTest = false); static bool runningInEmulator; diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 1333b92037c3..3e7ce368f55d 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -27,6 +27,8 @@ #include <vk/GrVkExtensions.h> #include <vk/GrVkTypes.h> +#include <cstring> + #include "Properties.h" #include "RenderThread.h" #include "renderstate/RenderState.h" @@ -53,6 +55,19 @@ static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& fe } } +GrVkGetProc VulkanManager::sSkiaGetProp = [](const char* proc_name, VkInstance instance, + VkDevice device) { + if (device != VK_NULL_HANDLE) { + if (strcmp("vkQueueSubmit", proc_name) == 0) { + return (PFN_vkVoidFunction)VulkanManager::interceptedVkQueueSubmit; + } else if (strcmp("vkQueueWaitIdle", proc_name) == 0) { + return (PFN_vkVoidFunction)VulkanManager::interceptedVkQueueWaitIdle; + } + return vkGetDeviceProcAddr(device, proc_name); + } + return vkGetInstanceProcAddr(instance, proc_name); +}; + #define GET_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(VK_NULL_HANDLE, "vk" #F) #define GET_INST_PROC(F) m##F = (PFN_vk##F)vkGetInstanceProcAddr(mInstance, "vk" #F) #define GET_DEV_PROC(F) m##F = (PFN_vk##F)vkGetDeviceProcAddr(mDevice, "vk" #F) @@ -83,7 +98,6 @@ VulkanManager::~VulkanManager() { } mGraphicsQueue = VK_NULL_HANDLE; - mAHBUploadQueue = VK_NULL_HANDLE; mDevice = VK_NULL_HANDLE; mPhysicalDevice = VK_NULL_HANDLE; mInstance = VK_NULL_HANDLE; @@ -185,7 +199,6 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe for (uint32_t i = 0; i < queueCount; i++) { if (queueProps[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { mGraphicsQueueIndex = i; - LOG_ALWAYS_FATAL_IF(queueProps[i].queueCount < 2); break; } } @@ -210,14 +223,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe LOG_ALWAYS_FATAL_IF(!hasKHRSwapchainExtension); } - auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { - if (device != VK_NULL_HANDLE) { - return vkGetDeviceProcAddr(device, proc_name); - } - return vkGetInstanceProcAddr(instance, proc_name); - }; - - grExtensions.init(getProc, mInstance, mPhysicalDevice, mInstanceExtensions.size(), + grExtensions.init(sSkiaGetProp, mInstance, mPhysicalDevice, mInstanceExtensions.size(), mInstanceExtensions.data(), mDeviceExtensions.size(), mDeviceExtensions.data()); @@ -289,7 +295,7 @@ void VulkanManager::setupDevice(GrVkExtensions& grExtensions, VkPhysicalDeviceFe queueNextPtr, // pNext 0, // VkDeviceQueueCreateFlags mGraphicsQueueIndex, // queueFamilyIndex - 2, // queueCount + 1, // queueCount queuePriorities, // pQueuePriorities }; @@ -344,7 +350,6 @@ void VulkanManager::initialize() { this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); - mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 1, &mAHBUploadQueue); if (Properties::enablePartialUpdates && Properties::useBufferAge) { mSwapBehavior = SwapBehavior::BufferAge; @@ -353,24 +358,17 @@ void VulkanManager::initialize() { sk_sp<GrDirectContext> VulkanManager::createContext(const GrContextOptions& options, ContextType contextType) { - auto getProc = [](const char* proc_name, VkInstance instance, VkDevice device) { - if (device != VK_NULL_HANDLE) { - return vkGetDeviceProcAddr(device, proc_name); - } - return vkGetInstanceProcAddr(instance, proc_name); - }; GrVkBackendContext backendContext; backendContext.fInstance = mInstance; backendContext.fPhysicalDevice = mPhysicalDevice; backendContext.fDevice = mDevice; - backendContext.fQueue = (contextType == ContextType::kRenderThread) ? mGraphicsQueue - : mAHBUploadQueue; + backendContext.fQueue = mGraphicsQueue; backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex; backendContext.fMaxAPIVersion = mAPIVersion; backendContext.fVkExtensions = &mExtensions; backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2; - backendContext.fGetProc = std::move(getProc); + backendContext.fGetProc = sSkiaGetProp; return GrDirectContext::MakeVulkan(backendContext, options); } @@ -530,6 +528,8 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) ALOGE_IF(VK_SUCCESS != err, "VulkanManager::swapBuffers(): Failed to get semaphore Fd"); } else { ALOGE("VulkanManager::swapBuffers(): Semaphore submission failed"); + + std::lock_guard<std::mutex> lock(mGraphicsQueueMutex); mQueueWaitIdle(mGraphicsQueue); } destroy_semaphore(destroyInfo); @@ -540,6 +540,7 @@ void VulkanManager::swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect) void VulkanManager::destroySurface(VulkanSurface* surface) { // Make sure all submit commands have finished before starting to destroy objects. if (VK_NULL_HANDLE != mGraphicsQueue) { + std::lock_guard<std::mutex> lock(mGraphicsQueueMutex); mQueueWaitIdle(mGraphicsQueue); } mDeviceWaitIdle(mDevice); diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index 7a77466303cd..121afc90cfe5 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -17,6 +17,10 @@ #ifndef VULKANMANAGER_H #define VULKANMANAGER_H +#include <functional> +#include <mutex> + +#include "vulkan/vulkan_core.h" #if !defined(VK_USE_PLATFORM_ANDROID_KHR) #define VK_USE_PLATFORM_ANDROID_KHR #endif @@ -161,8 +165,25 @@ private: VkDevice mDevice = VK_NULL_HANDLE; uint32_t mGraphicsQueueIndex; + + std::mutex mGraphicsQueueMutex; VkQueue mGraphicsQueue = VK_NULL_HANDLE; - VkQueue mAHBUploadQueue = VK_NULL_HANDLE; + + static VKAPI_ATTR VkResult interceptedVkQueueSubmit(VkQueue queue, uint32_t submitCount, + const VkSubmitInfo* pSubmits, + VkFence fence) { + sp<VulkanManager> manager = VulkanManager::getInstance(); + std::lock_guard<std::mutex> lock(manager->mGraphicsQueueMutex); + return manager->mQueueSubmit(queue, submitCount, pSubmits, fence); + } + + static VKAPI_ATTR VkResult interceptedVkQueueWaitIdle(VkQueue queue) { + sp<VulkanManager> manager = VulkanManager::getInstance(); + std::lock_guard<std::mutex> lock(manager->mGraphicsQueueMutex); + return manager->mQueueWaitIdle(queue); + } + + static GrVkGetProc sSkiaGetProp; // Variables saved to populate VkFunctorInitParams. static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0); diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h index c1d8b761514b..771c3452bf84 100644 --- a/libs/hwui/tests/common/TestUtils.h +++ b/libs/hwui/tests/common/TestUtils.h @@ -50,12 +50,12 @@ namespace uirenderer { ADD_FAILURE() << "ClipState not a rect"; \ } -#define INNER_PIPELINE_TEST(test_case_name, test_name, pipeline, functionCall) \ - TEST(test_case_name, test_name##_##pipeline) { \ - RenderPipelineType oldType = Properties::getRenderPipelineType(); \ - Properties::overrideRenderPipelineType(RenderPipelineType::pipeline); \ - functionCall; \ - Properties::overrideRenderPipelineType(oldType); \ +#define INNER_PIPELINE_TEST(test_case_name, test_name, pipeline, functionCall) \ + TEST(test_case_name, test_name##_##pipeline) { \ + RenderPipelineType oldType = Properties::getRenderPipelineType(); \ + Properties::overrideRenderPipelineType(RenderPipelineType::pipeline, true); \ + functionCall; \ + Properties::overrideRenderPipelineType(oldType, true); \ }; #define INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, pipeline) \ @@ -67,29 +67,27 @@ namespace uirenderer { * Like gtest's TEST, but runs on the RenderThread, and 'renderThread' is passed, in top level scope * (for e.g. accessing its RenderState) */ -#define RENDERTHREAD_TEST(test_case_name, test_name) \ - class test_case_name##_##test_name##_RenderThreadTest { \ - public: \ - static void doTheThing(renderthread::RenderThread& renderThread); \ - }; \ - INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \ - /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \ - /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */ \ - void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \ +#define RENDERTHREAD_TEST(test_case_name, test_name) \ + class test_case_name##_##test_name##_RenderThreadTest { \ + public: \ + static void doTheThing(renderthread::RenderThread& renderThread); \ + }; \ + INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \ + INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); \ + void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \ renderthread::RenderThread& renderThread) /** * Like RENDERTHREAD_TEST, but only runs with the Skia RenderPipelineTypes */ -#define RENDERTHREAD_SKIA_PIPELINE_TEST(test_case_name, test_name) \ - class test_case_name##_##test_name##_RenderThreadTest { \ - public: \ - static void doTheThing(renderthread::RenderThread& renderThread); \ - }; \ - INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \ - /* Temporarily disabling Vulkan until we can figure out a way to stub out the driver */ \ - /* INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); */ \ - void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \ +#define RENDERTHREAD_SKIA_PIPELINE_TEST(test_case_name, test_name) \ + class test_case_name##_##test_name##_RenderThreadTest { \ + public: \ + static void doTheThing(renderthread::RenderThread& renderThread); \ + }; \ + INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaGL); \ + INNER_PIPELINE_RENDERTHREAD_TEST(test_case_name, test_name, SkiaVulkan); \ + void test_case_name##_##test_name##_RenderThreadTest::doTheThing( \ renderthread::RenderThread& renderThread) /** |