Loading libs/hwui/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ hwui_src_files := \ renderthread/OpenGLPipeline.cpp \ renderthread/DrawFrameTask.cpp \ renderthread/EglManager.cpp \ renderthread/VulkanManager.cpp \ renderthread/RenderProxy.cpp \ renderthread/RenderTask.cpp \ renderthread/RenderThread.cpp \ Loading libs/hwui/hwui_static_deps.mk +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ LOCAL_SHARED_LIBRARIES += \ libutils \ libEGL \ libGLESv2 \ libvulkan \ libskia \ libui \ libgui \ Loading libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +30 −32 Original line number Diff line number Diff line Loading @@ -23,37 +23,43 @@ #include "SkiaPipeline.h" #include "SkiaProfileRenderer.h" #include <SkSurface.h> #include <SkTypes.h> #include <WindowContextFactory_android.h> #include <VulkanWindowContext.h> #include <GrContext.h> #include <GrTypes.h> #include <vk/GrVkTypes.h> #include <android/native_window.h> #include <cutils/properties.h> #include <strings.h> using namespace android::uirenderer::renderthread; using namespace sk_app; namespace android { namespace uirenderer { namespace skiapipeline { SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) , mVkManager(thread.vulkanManager()) {} MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { return (mWindowContext != nullptr) ? MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed; return MakeCurrentResult::AlreadyCurrent; } Frame SkiaVulkanPipeline::getFrame() { LOG_ALWAYS_FATAL_IF(mWindowContext == nullptr, "Tried to draw into null vulkan context!"); mBackbuffer = mWindowContext->getBackbufferSurface(); if (mBackbuffer.get() == nullptr) { // try recreating the context? LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with no surface!"); SkSurface* backBuffer = mVkManager.getBackbufferSurface(mVkSurface); if (backBuffer == nullptr) { SkDebugf("failed to get backbuffer"); return Frame(-1, -1, 0); } // TODO: support buffer age if Vulkan API can do it Frame frame(mBackbuffer->width(), mBackbuffer->height(), 0); Frame frame(backBuffer->width(), backBuffer->height(), 0); return frame; } Loading @@ -66,16 +72,18 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { if (mBackbuffer.get() == nullptr) { sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface(); if (backBuffer.get() == nullptr) { return false; } renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, mBackbuffer); SkiaPipeline::updateLighting(lightGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer); layerUpdateQueue->clear(); // Draw visual debugging features if (CC_UNLIKELY(Properties::showDirtyRegions || ProfileType::None != Properties::getProfileType())) { SkCanvas* profileCanvas = mBackbuffer->getCanvas(); SkCanvas* profileCanvas = backBuffer->getCanvas(); SkiaProfileRenderer profileRenderer(profileCanvas); profiler->draw(profileRenderer); profileCanvas->flush(); Loading @@ -99,11 +107,9 @@ bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, currentFrameInfo->markSwapBuffers(); if (*requireSwap) { mWindowContext->swapBuffers(); mVkManager.swapBuffers(mVkSurface); } mBackbuffer.reset(); return *requireSwap; } Loading @@ -113,6 +119,7 @@ bool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bi } DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() { mVkManager.initialize(); Layer* layer = new Layer(mRenderThread.renderState(), 0, 0); return new DeferredLayerUpdater(layer); } Loading @@ -121,33 +128,24 @@ void SkiaVulkanPipeline::onStop() { } bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) { if (mWindowContext) { delete mWindowContext; mWindowContext = nullptr; if (mVkSurface) { mVkManager.destroySurface(mVkSurface); mVkSurface = nullptr; } if (surface) { DisplayParams displayParams; mWindowContext = window_context_factory::NewVulkanForAndroid(surface, displayParams); if (mWindowContext) { DeviceInfo::initialize(mWindowContext->getGrContext()->caps()->maxRenderTargetSize()); } mVkSurface = mVkManager.createSurface(surface); } // this doesn't work for if there is more than one CanvasContext available at one time! mRenderThread.setGrContext(mWindowContext ? mWindowContext->getGrContext() : nullptr); return mWindowContext != nullptr; return mVkSurface != nullptr; } bool SkiaVulkanPipeline::isSurfaceReady() { return CC_LIKELY(mWindowContext != nullptr) && mWindowContext->isValid(); return CC_UNLIKELY(mVkSurface != nullptr); } bool SkiaVulkanPipeline::isContextReady() { return CC_LIKELY(mWindowContext != nullptr); return CC_LIKELY(mVkManager.hasVkContext()); } void SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) { Loading libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +4 −8 Original line number Diff line number Diff line Loading @@ -17,11 +17,7 @@ #pragma once #include "SkiaPipeline.h" #include <SkSurface.h> namespace sk_app { class WindowContext; } #include "renderthread/VulkanManager.h" namespace android { namespace uirenderer { Loading @@ -29,7 +25,7 @@ namespace skiapipeline { class SkiaVulkanPipeline : public SkiaPipeline { public: SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {} SkiaVulkanPipeline(renderthread::RenderThread& thread); virtual ~SkiaVulkanPipeline() {} renderthread::MakeCurrentResult makeCurrent() override; Loading @@ -53,8 +49,8 @@ public: static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor); private: sk_app::WindowContext* mWindowContext = nullptr; sk_sp<SkSurface> mBackbuffer; renderthread::VulkanManager& mVkManager; renderthread::VulkanSurface* mVkSurface = nullptr; }; } /* namespace skiapipeline */ Loading libs/hwui/renderthread/RenderThread.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "CanvasContext.h" #include "EglManager.h" #include "RenderProxy.h" #include "VulkanManager.h" #include <gui/DisplayEventReceiver.h> #include <gui/ISurfaceComposer.h> Loading Loading @@ -157,7 +158,8 @@ RenderThread::RenderThread() : Thread(true) , mFrameCallbackTaskPending(false) , mFrameCallbackTask(nullptr) , mRenderState(nullptr) , mEglManager(nullptr) { , mEglManager(nullptr) , mVkManager(nullptr) { Properties::load(); mFrameCallbackTask = new DispatchFrameCallbacks(this); mLooper = new Looper(false); Loading Loading @@ -191,6 +193,7 @@ void RenderThread::initThreadLocals() { mEglManager = new EglManager(*this); mRenderState = new RenderState(*this); mJankTracker = new JankTracker(mDisplayInfo); mVkManager = new VulkanManager(*this); } int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { Loading Loading
libs/hwui/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ hwui_src_files := \ renderthread/OpenGLPipeline.cpp \ renderthread/DrawFrameTask.cpp \ renderthread/EglManager.cpp \ renderthread/VulkanManager.cpp \ renderthread/RenderProxy.cpp \ renderthread/RenderTask.cpp \ renderthread/RenderThread.cpp \ Loading
libs/hwui/hwui_static_deps.mk +1 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ LOCAL_SHARED_LIBRARIES += \ libutils \ libEGL \ libGLESv2 \ libvulkan \ libskia \ libui \ libgui \ Loading
libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp +30 −32 Original line number Diff line number Diff line Loading @@ -23,37 +23,43 @@ #include "SkiaPipeline.h" #include "SkiaProfileRenderer.h" #include <SkSurface.h> #include <SkTypes.h> #include <WindowContextFactory_android.h> #include <VulkanWindowContext.h> #include <GrContext.h> #include <GrTypes.h> #include <vk/GrVkTypes.h> #include <android/native_window.h> #include <cutils/properties.h> #include <strings.h> using namespace android::uirenderer::renderthread; using namespace sk_app; namespace android { namespace uirenderer { namespace skiapipeline { SkiaVulkanPipeline::SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) , mVkManager(thread.vulkanManager()) {} MakeCurrentResult SkiaVulkanPipeline::makeCurrent() { return (mWindowContext != nullptr) ? MakeCurrentResult::AlreadyCurrent : MakeCurrentResult::Failed; return MakeCurrentResult::AlreadyCurrent; } Frame SkiaVulkanPipeline::getFrame() { LOG_ALWAYS_FATAL_IF(mWindowContext == nullptr, "Tried to draw into null vulkan context!"); mBackbuffer = mWindowContext->getBackbufferSurface(); if (mBackbuffer.get() == nullptr) { // try recreating the context? LOG_ALWAYS_FATAL_IF(mVkSurface == nullptr, "drawRenderNode called on a context with no surface!"); SkSurface* backBuffer = mVkManager.getBackbufferSurface(mVkSurface); if (backBuffer == nullptr) { SkDebugf("failed to get backbuffer"); return Frame(-1, -1, 0); } // TODO: support buffer age if Vulkan API can do it Frame frame(mBackbuffer->width(), mBackbuffer->height(), 0); Frame frame(backBuffer->width(), backBuffer->height(), 0); return frame; } Loading @@ -66,16 +72,18 @@ bool SkiaVulkanPipeline::draw(const Frame& frame, const SkRect& screenDirty, const std::vector<sp<RenderNode>>& renderNodes, FrameInfoVisualizer* profiler) { if (mBackbuffer.get() == nullptr) { sk_sp<SkSurface> backBuffer = mVkSurface->getBackBufferSurface(); if (backBuffer.get() == nullptr) { return false; } renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, mBackbuffer); SkiaPipeline::updateLighting(lightGeometry, lightInfo); renderFrame(*layerUpdateQueue, dirty, renderNodes, opaque, contentDrawBounds, backBuffer); layerUpdateQueue->clear(); // Draw visual debugging features if (CC_UNLIKELY(Properties::showDirtyRegions || ProfileType::None != Properties::getProfileType())) { SkCanvas* profileCanvas = mBackbuffer->getCanvas(); SkCanvas* profileCanvas = backBuffer->getCanvas(); SkiaProfileRenderer profileRenderer(profileCanvas); profiler->draw(profileRenderer); profileCanvas->flush(); Loading @@ -99,11 +107,9 @@ bool SkiaVulkanPipeline::swapBuffers(const Frame& frame, bool drew, currentFrameInfo->markSwapBuffers(); if (*requireSwap) { mWindowContext->swapBuffers(); mVkManager.swapBuffers(mVkSurface); } mBackbuffer.reset(); return *requireSwap; } Loading @@ -113,6 +119,7 @@ bool SkiaVulkanPipeline::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bi } DeferredLayerUpdater* SkiaVulkanPipeline::createTextureLayer() { mVkManager.initialize(); Layer* layer = new Layer(mRenderThread.renderState(), 0, 0); return new DeferredLayerUpdater(layer); } Loading @@ -121,33 +128,24 @@ void SkiaVulkanPipeline::onStop() { } bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior) { if (mWindowContext) { delete mWindowContext; mWindowContext = nullptr; if (mVkSurface) { mVkManager.destroySurface(mVkSurface); mVkSurface = nullptr; } if (surface) { DisplayParams displayParams; mWindowContext = window_context_factory::NewVulkanForAndroid(surface, displayParams); if (mWindowContext) { DeviceInfo::initialize(mWindowContext->getGrContext()->caps()->maxRenderTargetSize()); } mVkSurface = mVkManager.createSurface(surface); } // this doesn't work for if there is more than one CanvasContext available at one time! mRenderThread.setGrContext(mWindowContext ? mWindowContext->getGrContext() : nullptr); return mWindowContext != nullptr; return mVkSurface != nullptr; } bool SkiaVulkanPipeline::isSurfaceReady() { return CC_LIKELY(mWindowContext != nullptr) && mWindowContext->isValid(); return CC_UNLIKELY(mVkSurface != nullptr); } bool SkiaVulkanPipeline::isContextReady() { return CC_LIKELY(mWindowContext != nullptr); return CC_LIKELY(mVkManager.hasVkContext()); } void SkiaVulkanPipeline::invokeFunctor(const RenderThread& thread, Functor* functor) { Loading
libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +4 −8 Original line number Diff line number Diff line Loading @@ -17,11 +17,7 @@ #pragma once #include "SkiaPipeline.h" #include <SkSurface.h> namespace sk_app { class WindowContext; } #include "renderthread/VulkanManager.h" namespace android { namespace uirenderer { Loading @@ -29,7 +25,7 @@ namespace skiapipeline { class SkiaVulkanPipeline : public SkiaPipeline { public: SkiaVulkanPipeline(renderthread::RenderThread& thread) : SkiaPipeline(thread) {} SkiaVulkanPipeline(renderthread::RenderThread& thread); virtual ~SkiaVulkanPipeline() {} renderthread::MakeCurrentResult makeCurrent() override; Loading @@ -53,8 +49,8 @@ public: static void invokeFunctor(const renderthread::RenderThread& thread, Functor* functor); private: sk_app::WindowContext* mWindowContext = nullptr; sk_sp<SkSurface> mBackbuffer; renderthread::VulkanManager& mVkManager; renderthread::VulkanSurface* mVkSurface = nullptr; }; } /* namespace skiapipeline */ Loading
libs/hwui/renderthread/RenderThread.cpp +4 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include "CanvasContext.h" #include "EglManager.h" #include "RenderProxy.h" #include "VulkanManager.h" #include <gui/DisplayEventReceiver.h> #include <gui/ISurfaceComposer.h> Loading Loading @@ -157,7 +158,8 @@ RenderThread::RenderThread() : Thread(true) , mFrameCallbackTaskPending(false) , mFrameCallbackTask(nullptr) , mRenderState(nullptr) , mEglManager(nullptr) { , mEglManager(nullptr) , mVkManager(nullptr) { Properties::load(); mFrameCallbackTask = new DispatchFrameCallbacks(this); mLooper = new Looper(false); Loading Loading @@ -191,6 +193,7 @@ void RenderThread::initThreadLocals() { mEglManager = new EglManager(*this); mRenderState = new RenderState(*this); mJankTracker = new JankTracker(mDisplayInfo); mVkManager = new VulkanManager(*this); } int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { Loading