summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_view_RenderNode.cpp37
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp33
-rw-r--r--libs/hwui/renderthread/CanvasContext.h18
-rw-r--r--libs/hwui/thread/Barrier.h5
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) {