summaryrefslogtreecommitdiff
path: root/libs/hwui/renderthread/RenderThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui/renderthread/RenderThread.cpp')
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp55
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) {