Merge "Decouple VulkanManager from RenderThread"
This commit is contained in:
committed by
Android (Google) Code Review
commit
cb26eb117b
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
sk_sp<GrContext> createContext(GrContextOptions options);
|
||||
|
||||
private:
|
||||
friend class RenderThread;
|
||||
|
||||
explicit VulkanManager(RenderThread& thread);
|
||||
~VulkanManager() { destroy(); }
|
||||
|
||||
// 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 */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user