diff options
| -rw-r--r-- | core/jni/android_view_RenderNode.cpp | 37 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 33 | ||||
| -rw-r--r-- | libs/hwui/renderthread/CanvasContext.h | 18 | ||||
| -rw-r--r-- | libs/hwui/thread/Barrier.h | 5 |
4 files changed, 76 insertions, 17 deletions
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index a9003c1888d2..a7ac5b8aae66 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -28,6 +28,7 @@ #include <DamageAccumulator.h> #include <Matrix.h> #include <RenderNode.h> +#include <renderthread/CanvasContext.h> #include <TreeInfo.h> #include <Paint.h> @@ -487,15 +488,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override { if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return; - ATRACE_NAME("Update SurfaceView position"); - JNIEnv* env = jnienv(); - jobject localref = env->NewLocalRef(mWeakRef); - if (CC_UNLIKELY(!localref)) { - jnienv()->DeleteWeakGlobalRef(mWeakRef); - mWeakRef = nullptr; - return; - } Matrix4 transform; info.damageAccumulator->computeCurrentTransform(&transform); const RenderProperties& props = node.properties(); @@ -505,10 +498,13 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, bounds.right -= info.windowInsetLeft; bounds.top -= info.windowInsetTop; bounds.bottom -= info.windowInsetTop; - env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod, - (jlong) info.frameNumber, (jint) bounds.left, (jint) bounds.top, - (jint) bounds.right, (jint) bounds.bottom); - env->DeleteLocalRef(localref); + + auto functor = std::bind( + std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePosition), this, + (jlong) info.frameNumber, (jint) bounds.left, (jint) bounds.top, + (jint) bounds.right, (jint) bounds.bottom); + + info.canvasContext.enqueueFrameWork(std::move(functor)); } private: @@ -520,6 +516,23 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, return env; } + void doUpdatePosition(jlong frameNumber, jint left, jint top, + jint right, jint bottom) { + ATRACE_NAME("Update SurfaceView position"); + + JNIEnv* env = jnienv(); + jobject localref = env->NewLocalRef(mWeakRef); + if (CC_UNLIKELY(!localref)) { + jnienv()->DeleteWeakGlobalRef(mWeakRef); + mWeakRef = nullptr; + return; + } + + env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod, + frameNumber, left, top, right, bottom); + env->DeleteLocalRef(localref); + } + JavaVM* mVm; jobject mWeakRef; }; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index a496b4966456..c539d63daed3 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -484,6 +484,8 @@ void CanvasContext::draw() { bool drew = mCanvas->finish(); #endif + waitOnFences(); + GL_CHECKPOINT(LOW); // Even if we decided to cancel the frame, from the perspective of jank @@ -726,6 +728,37 @@ void CanvasContext::serializeDisplayListTree() { #endif } +void CanvasContext::waitOnFences() { + if (mFrameFences.size()) { + ATRACE_CALL(); + for (auto& fence : mFrameFences) { + fence->getResult(); + } + mFrameFences.clear(); + } +} + +class CanvasContext::FuncTaskProcessor : public TaskProcessor<bool> { +public: + FuncTaskProcessor(Caches& caches) + : TaskProcessor<bool>(&caches.tasks) {} + + virtual void onProcess(const sp<Task<bool> >& task) override { + FuncTask* t = static_cast<FuncTask*>(task.get()); + t->func(); + task->setResult(true); + } +}; + +void CanvasContext::enqueueFrameWork(std::function<void()>&& func) { + if (!mFrameWorkProcessor.get()) { + mFrameWorkProcessor = new FuncTaskProcessor(Caches::getInstance()); + } + sp<FuncTask> task(new FuncTask()); + task->func = func; + mFrameWorkProcessor->add(task); +} + } /* namespace renderthread */ } /* namespace uirenderer */ } /* namespace android */ diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index cb61e51a2158..6706c30f148b 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -24,6 +24,8 @@ #include "IContextFactory.h" #include "LayerUpdateQueue.h" #include "RenderNode.h" +#include "thread/Task.h" +#include "thread/TaskProcessor.h" #include "utils/RingBuffer.h" #include "renderthread/RenderTask.h" #include "renderthread/RenderThread.h" @@ -41,6 +43,7 @@ #include <utils/Functor.h> #include <gui/Surface.h> +#include <functional> #include <set> #include <string> #include <vector> @@ -159,6 +162,9 @@ public: } } + // Used to queue up work that needs to be completed before this frame completes + ANDROID_API void enqueueFrameWork(std::function<void()>&& func); + private: friend class RegisterFrameCallbackTask; // TODO: Replace with something better for layer & other GL object @@ -170,6 +176,8 @@ private: void freePrefetechedLayers(); + void waitOnFences(); + EGLint mLastFrameWidth = 0; EGLint mLastFrameHeight = 0; @@ -213,6 +221,16 @@ private: // Stores the bounds of the main content. Rect mContentDrawBounds; + + // TODO: This is really a Task<void> but that doesn't really work + // when Future<> expects to be able to get/set a value + struct FuncTask : public Task<bool> { + std::function<void()> func; + }; + class FuncTaskProcessor; + + std::vector< sp<FuncTask> > mFrameFences; + sp<TaskProcessor<bool> > mFrameWorkProcessor; }; } /* namespace renderthread */ diff --git a/libs/hwui/thread/Barrier.h b/libs/hwui/thread/Barrier.h index 6cb23e54943b..0a7acb0fbbfd 100644 --- a/libs/hwui/thread/Barrier.h +++ b/libs/hwui/thread/Barrier.h @@ -33,11 +33,6 @@ public: mCondition.signal(mType); } - void close() { - Mutex::Autolock l(mLock); - mOpened = false; - } - void wait() const { Mutex::Autolock l(mLock); while (!mOpened) { |