Merge "Decouple VulkanManager from RenderThread"

This commit is contained in:
TreeHugger Robot
2019-02-13 23:33:17 +00:00
committed by Android (Google) Code Review
7 changed files with 73 additions and 57 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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));

View File

@@ -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 */

View File

@@ -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();
}