diff options
Diffstat (limited to 'libs/hwui/renderthread/RenderThread.cpp')
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index f4b44164b84e..1450ec98dabf 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -17,9 +17,13 @@ #include "RenderThread.h" #include "../renderstate/RenderState.h" +#include "../pipeline/skia/SkiaOpenGLReadback.h" #include "CanvasContext.h" #include "EglManager.h" +#include "OpenGLReadback.h" #include "RenderProxy.h" +#include "VulkanManager.h" +#include "utils/FatVector.h" #include <gui/DisplayEventReceiver.h> #include <gui/ISurfaceComposer.h> @@ -94,6 +98,7 @@ void TaskQueue::queue(RenderTask* task) { } void TaskQueue::queueAtFront(RenderTask* task) { + LOG_ALWAYS_FATAL_IF(task->mNext || mHead == task, "Task is already in the queue!"); if (mTail) { task->mNext = mHead; mHead = task; @@ -128,7 +133,7 @@ class DispatchFrameCallbacks : public RenderTask { private: RenderThread* mRenderThread; public: - DispatchFrameCallbacks(RenderThread* rt) : mRenderThread(rt) {} + explicit DispatchFrameCallbacks(RenderThread* rt) : mRenderThread(rt) {} virtual void run() override { mRenderThread->dispatchFrameCallbacks(); @@ -157,7 +162,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); @@ -191,6 +197,31 @@ void RenderThread::initThreadLocals() { mEglManager = new EglManager(*this); mRenderState = new RenderState(*this); mJankTracker = new JankTracker(mDisplayInfo); + mVkManager = new VulkanManager(*this); +} + +Readback& RenderThread::readback() { + + if (!mReadback) { + auto renderType = Properties::getRenderPipelineType(); + switch (renderType) { + case RenderPipelineType::OpenGL: + mReadback = new OpenGLReadbackImpl(*this); + break; + case RenderPipelineType::SkiaGL: + case RenderPipelineType::SkiaVulkan: + // It works to use the OpenGL pipeline for Vulkan but this is not + // ideal as it causes us to create an OpenGL context in addition + // to the Vulkan one. + mReadback = new skiapipeline::SkiaOpenGLReadback(*this); + break; + default: + LOG_ALWAYS_FATAL("canvas context type %d not supported", (int32_t) renderType); + break; + } + } + + return *mReadback; } int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) { @@ -282,10 +313,18 @@ bool RenderThread::threadLoop() { "RenderThread Looper POLL_ERROR!"); nsecs_t nextWakeup; - // Process our queue, if we have anything - while (RenderTask* task = nextTask(&nextWakeup)) { - task->run(); - // task may have deleted itself, do not reference it again + { + FatVector<RenderTask*, 10> workQueue; + // Process our queue, if we have anything. By first acquiring + // all the pending events then processing them we avoid vsync + // starvation if more tasks are queued while we are processing tasks. + while (RenderTask* task = nextTask(&nextWakeup)) { + workQueue.push_back(task); + } + for (auto task : workQueue) { + task->run(); + // task may have deleted itself, do not reference it again + } } if (nextWakeup == LLONG_MAX) { timeoutMillis = -1; @@ -336,7 +375,9 @@ void RenderThread::queueAndWait(RenderTask* task) { AutoMutex _lock(mutex); queue(&syncTask); - condition.wait(mutex); + while (!syncTask.hasRun()) { + condition.wait(mutex); + } } void RenderThread::queueAtFront(RenderTask* task) { |