diff options
author | 2019-02-13 14:24:33 -0500 | |
---|---|---|
committer | 2019-02-13 15:55:45 -0500 | |
commit | 981afe773aa5b7535f36b126a0b7d6fd4cc78d03 (patch) | |
tree | c0d8584bbd28f485b9435a69373d052f3b09a2bf | |
parent | 74d6997124a55043cccf505e7091ba326d51d6f8 (diff) |
Decouple VulkanManager from RenderThread
This CL allows for more than one VulkanManager to exist.
VulkanManager ctor are public allowing for classes other
than RenderThread to instantiate it.
Secondary VulkanManager can be used to render on a thread
other than RT.
Test: Ran HWUI unit tests and several apps
Change-Id: Ibfd76c86ff67e01617a500902bba7431b928f5c0
-rw-r--r-- | libs/hwui/Readback.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 26 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.h | 3 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.cpp | 69 | ||||
-rw-r--r-- | libs/hwui/renderthread/VulkanManager.h | 23 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.cpp | 2 |
7 files changed, 73 insertions, 57 deletions
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index 76c56609ef47..2ffda839c210 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -107,7 +107,7 @@ CopyResult Readback::copyImageInto(const sk_sp<SkImage>& image, Matrix4& texTran if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { mRenderThread.requireGlContext(); } else { - mRenderThread.vulkanManager().initialize(); + mRenderThread.requireVkContext(); } if (!image.get()) { return CopyResult::UnknownError; diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp index 15f53f286261..87cffb52c150 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp @@ -120,7 +120,7 @@ bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, const SkRect } DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() { - mVkManager.initialize(); + mRenderThread.requireVkContext(); return new DeferredLayerUpdater(mRenderThread.renderState()); } @@ -136,8 +136,9 @@ bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBeh setSurfaceColorProperties(colorMode); if (surface) { + mRenderThread.requireVkContext(); mVkSurface = mVkManager.createSurface(surface, colorMode, mSurfaceColorSpace, - mSurfaceColorType); + mSurfaceColorType, mRenderThread.getGrContext()); } return mVkSurface != nullptr; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 3904ed20fd77..fc63819120d6 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -173,10 +173,10 @@ void RenderThread::initThreadLocals() { initializeDisplayEventReceiver(); mEglManager = new EglManager(); mRenderState = new RenderState(*this); - mVkManager = new VulkanManager(*this); + mVkManager = new VulkanManager(); mCacheManager = new CacheManager(mDisplayInfo); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { - mVkManager->initialize(); + requireVkContext(); } } @@ -195,8 +195,7 @@ void RenderThread::requireGlContext() { LOG_ALWAYS_FATAL_IF(!glInterface.get()); GrContextOptions options; - options.fPreferExternalImagesOverES3 = true; - options.fDisableDistanceFieldPaths = true; + initGrContextOptions(options); auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION)); auto size = glesVersion ? strlen(glesVersion) : -1; cacheManager().configureContext(&options, glesVersion, size); @@ -205,6 +204,25 @@ void RenderThread::requireGlContext() { setGrContext(grContext); } +void RenderThread::requireVkContext() { + if (mVkManager->hasVkContext()) { + return; + } + mVkManager->initialize(); + GrContextOptions options; + initGrContextOptions(options); + // TODO: get a string describing the SPIR-V compiler version and use it here + cacheManager().configureContext(&options, nullptr, 0); + sk_sp<GrContext> grContext = mVkManager->createContext(options); + LOG_ALWAYS_FATAL_IF(!grContext.get()); + setGrContext(grContext); +} + +void RenderThread::initGrContextOptions(GrContextOptions& options) { + options.fPreferExternalImagesOverES3 = true; + options.fDisableDistanceFieldPaths = true; +} + void RenderThread::destroyRenderingContext() { mFunctorManager.onContextDestroyed(); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) { diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index b18292820c6b..419e7c7a6b51 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -112,6 +112,7 @@ public: void dumpGraphicsMemory(int fd); void requireGlContext(); + void requireVkContext(); void destroyRenderingContext(); /** @@ -122,6 +123,8 @@ public: */ static bool isCurrent(); + static void initGrContextOptions(GrContextOptions& options); + protected: virtual bool threadLoop() override; diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp index 90397fddf618..1e685abd8afa 100644 --- a/libs/hwui/renderthread/VulkanManager.cpp +++ b/libs/hwui/renderthread/VulkanManager.cpp @@ -55,11 +55,7 @@ static void free_features_extensions_structs(const VkPhysicalDeviceFeatures2& fe #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) -VulkanManager::VulkanManager(RenderThread& thread) : mRenderThread(thread) {} - void VulkanManager::destroy() { - mRenderThread.setGrContext(nullptr); - // 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; @@ -333,29 +329,10 @@ void VulkanManager::initialize() { LOG_ALWAYS_FATAL_IF(mEnumerateInstanceVersion(&instanceVersion)); LOG_ALWAYS_FATAL_IF(instanceVersion < VK_MAKE_VERSION(1, 1, 0)); - GrVkExtensions extensions; - this->setupDevice(extensions, mPhysicalDeviceFeatures2); + this->setupDevice(mExtensions, mPhysicalDeviceFeatures2); mGetDeviceQueue(mDevice, mGraphicsQueueIndex, 0, &mGraphicsQueue); - 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 = mGraphicsQueue; - backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex; - backendContext.fMaxAPIVersion = mAPIVersion; - backendContext.fVkExtensions = &extensions; - backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2; - backendContext.fGetProc = std::move(getProc); - // create the command pool for the command buffers if (VK_NULL_HANDLE == mCommandPool) { VkCommandPoolCreateInfo commandPoolInfo; @@ -376,22 +353,35 @@ void VulkanManager::initialize() { } LOG_ALWAYS_FATAL_IF(mDummyCB == VK_NULL_HANDLE); - mGetDeviceQueue(mDevice, mPresentQueueIndex, 0, &mPresentQueue); - GrContextOptions options; - options.fDisableDistanceFieldPaths = true; - // TODO: get a string describing the SPIR-V compiler version and use it here - mRenderThread.cacheManager().configureContext(&options, nullptr, 0); - sk_sp<GrContext> grContext(GrContext::MakeVulkan(backendContext, options)); - LOG_ALWAYS_FATAL_IF(!grContext.get()); - mRenderThread.setGrContext(grContext); - if (Properties::enablePartialUpdates && Properties::useBufferAge) { mSwapBehavior = SwapBehavior::BufferAge; } } +sk_sp<GrContext> VulkanManager::createContext(GrContextOptions options) { + 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 = mGraphicsQueue; + backendContext.fGraphicsQueueIndex = mGraphicsQueueIndex; + backendContext.fMaxAPIVersion = mAPIVersion; + backendContext.fVkExtensions = &mExtensions; + backendContext.fDeviceFeatures2 = &mPhysicalDeviceFeatures2; + backendContext.fGetProc = std::move(getProc); + + return GrContext::MakeVulkan(backendContext, options); +} + VkFunctorInitParams VulkanManager::getVkFunctorInitParams() const { return VkFunctorInitParams{ .instance = mInstance, @@ -470,8 +460,9 @@ SkSurface* VulkanManager::getBackbufferSurface(VulkanSurface** surfaceOut) { ColorMode colorMode = surface->mColorMode; sk_sp<SkColorSpace> colorSpace = surface->mColorSpace; SkColorType colorType = surface->mColorType; + GrContext* grContext = surface->mGrContext; destroySurface(surface); - *surfaceOut = createSurface(window, colorMode, colorSpace, colorType); + *surfaceOut = createSurface(window, colorMode, colorSpace, colorType, grContext); surface = *surfaceOut; if (!surface) { return nullptr; @@ -650,7 +641,7 @@ void VulkanManager::createBuffers(VulkanSurface* surface, VkFormat format, VkExt VulkanSurface::ImageInfo& imageInfo = surface->mImageInfos[i]; imageInfo.mSurface = SkSurface::MakeFromBackendRenderTarget( - mRenderThread.getGrContext(), backendRT, kTopLeft_GrSurfaceOrigin, + surface->mGrContext, backendRT, kTopLeft_GrSurfaceOrigin, surface->mColorType, surface->mColorSpace, &props); } @@ -880,15 +871,15 @@ bool VulkanManager::createSwapchain(VulkanSurface* surface) { VulkanSurface* VulkanManager::createSurface(ANativeWindow* window, ColorMode colorMode, sk_sp<SkColorSpace> surfaceColorSpace, - SkColorType surfaceColorType) { - initialize(); - + SkColorType surfaceColorType, + GrContext* grContext) { + LOG_ALWAYS_FATAL_IF(!hasVkContext(), "Not initialized"); if (!window) { return nullptr; } VulkanSurface* surface = new VulkanSurface(colorMode, window, surfaceColorSpace, - surfaceColorType); + surfaceColorType, grContext); VkAndroidSurfaceCreateInfoKHR surfaceCreateInfo; memset(&surfaceCreateInfo, 0, sizeof(VkAndroidSurfaceCreateInfoKHR)); diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h index 1fe6c65b35b8..97636865a629 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -22,6 +22,8 @@ #endif #include <vulkan/vulkan.h> +#include <GrContextOptions.h> +#include <vk/GrVkExtensions.h> #include <SkSurface.h> #include <ui/Fence.h> #include <utils/StrongPointer.h> @@ -39,9 +41,9 @@ class RenderThread; class VulkanSurface { public: VulkanSurface(ColorMode colorMode, ANativeWindow* window, sk_sp<SkColorSpace> colorSpace, - SkColorType colorType) + SkColorType colorType, GrContext* grContext) : mColorMode(colorMode), mNativeWindow(window), mColorSpace(colorSpace), - mColorType(colorType) {} + mColorType(colorType), mGrContext(grContext) {} sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; } @@ -93,6 +95,7 @@ private: SkColorType mColorType; VkSurfaceTransformFlagBitsKHR mTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; SkMatrix mPreTransform; + GrContext* mGrContext; }; // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, @@ -100,6 +103,9 @@ private: // windowing contexts. The VulkanManager must be initialized before use. class VulkanManager { public: + explicit VulkanManager() {} + ~VulkanManager() { destroy(); } + // Sets up the vulkan context that is shared amonst all clients of the VulkanManager. This must // be call once before use of the VulkanManager. Multiple calls after the first will simiply // return. @@ -112,7 +118,8 @@ public: // VulkanSurface object which is returned. VulkanSurface* createSurface(ANativeWindow* window, ColorMode colorMode, sk_sp<SkColorSpace> surfaceColorSpace, - SkColorType surfaceColorType); + SkColorType surfaceColorType, + GrContext* grContext); // Destroy the VulkanSurface and all associated vulkan objects. void destroySurface(VulkanSurface* surface); @@ -143,12 +150,9 @@ public: // Returned pointers are owned by VulkanManager. VkFunctorInitParams getVkFunctorInitParams() const; -private: - friend class RenderThread; - - explicit VulkanManager(RenderThread& thread); - ~VulkanManager() { destroy(); } + sk_sp<GrContext> createContext(GrContextOptions options); +private: // Sets up the VkInstance and VkDevice objects. Also fills out the passed in // VkPhysicalDeviceFeatures struct. void setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&); @@ -231,8 +235,6 @@ private: VkPtr<PFN_vkWaitForFences> mWaitForFences; VkPtr<PFN_vkResetFences> mResetFences; - RenderThread& mRenderThread; - VkInstance mInstance = VK_NULL_HANDLE; VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; VkDevice mDevice = VK_NULL_HANDLE; @@ -256,6 +258,7 @@ private: BufferAge, }; SwapBehavior mSwapBehavior = SwapBehavior::Discard; + GrVkExtensions mExtensions; }; } /* namespace renderthread */ diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index a9f651d38a06..e8ba15fe92af 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -100,7 +100,7 @@ void TestUtils::TestTask::run() { // RenderState only valid once RenderThread is running, so queried here renderthread::RenderThread& renderThread = renderthread::RenderThread::getInstance(); if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) { - renderThread.vulkanManager().initialize(); + renderThread.requireVkContext(); } else { renderThread.requireGlContext(); } |