diff options
author | 2016-06-28 01:26:42 +0000 | |
---|---|---|
committer | 2016-06-28 01:26:43 +0000 | |
commit | 8701bff9bacd033ecade271c9f30ef5d734e8cc0 (patch) | |
tree | 915f6c0c457eeb0f372fa1a1d3421e26ddcf8f24 | |
parent | 30a2b43f6d0531c393f21b0d91885aa4ceba4f85 (diff) | |
parent | 7b570deea65bc7ac417a26ce3e4103bcef30e957 (diff) |
Merge "Fix SurfaceViewPositionListener race bugs" into nyc-mr1-dev
-rw-r--r-- | core/jni/android_view_RenderNode.cpp | 51 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 6 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 1 |
3 files changed, 25 insertions, 33 deletions
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp index 4fc546c98e97..b0028e1b6f5b 100644 --- a/core/jni/android_view_RenderNode.cpp +++ b/core/jni/android_view_RenderNode.cpp @@ -573,8 +573,9 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, bounds.roundOut(); } + incStrong(0); auto functor = std::bind( - std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePosition), this, + std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePositionAsync), this, (jlong) info.canvasContext.getFrameNumber(), (jint) bounds.left, (jint) bounds.top, (jint) bounds.right, (jint) bounds.bottom); @@ -585,15 +586,18 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override { if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return; - if (info) { - auto functor = std::bind( - std::mem_fn(&SurfaceViewPositionUpdater::doNotifyPositionLost), this, - (jlong) info->canvasContext.getFrameNumber()); - - info->canvasContext.enqueueFrameWork(std::move(functor)); - } else { - doNotifyPositionLost(0); + ATRACE_NAME("SurfaceView position lost"); + JNIEnv* env = jnienv(); + jobject localref = env->NewLocalRef(mWeakRef); + if (CC_UNLIKELY(!localref)) { + jnienv()->DeleteWeakGlobalRef(mWeakRef); + mWeakRef = nullptr; + return; } + + env->CallVoidMethod(localref, gSurfaceViewPositionLostMethod, + info ? info->canvasContext.getFrameNumber() : 0); + env->DeleteLocalRef(localref); } private: @@ -605,36 +609,23 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject, return env; } - void doUpdatePosition(jlong frameNumber, jint left, jint top, + void doUpdatePositionAsync(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); - } - - void doNotifyPositionLost(jlong frameNumber) { - ATRACE_NAME("SurfaceView position lost"); - - JNIEnv* env = jnienv(); - jobject localref = env->NewLocalRef(mWeakRef); - if (CC_UNLIKELY(!localref)) { - jnienv()->DeleteWeakGlobalRef(mWeakRef); + env->DeleteWeakGlobalRef(mWeakRef); mWeakRef = nullptr; - return; + } else { + env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod, + frameNumber, left, top, right, bottom); + env->DeleteLocalRef(localref); } - env->CallVoidMethod(localref, gSurfaceViewPositionLostMethod, frameNumber); - env->DeleteLocalRef(localref); + // We need to release ourselves here + decStrong(0); } JavaVM* mVm; diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index f80be5ec9ae9..47fef6da355c 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -232,7 +232,7 @@ public: // the frameNumber to appropriately batch/synchronize these transactions. // There is no other filtering/batching to ensure that only the "final" // state called once per frame. - class ANDROID_API PositionListener { + class ANDROID_API PositionListener : public VirtualLightRefBase { public: virtual ~PositionListener() {} // Called when the RenderNode's position changes @@ -247,7 +247,7 @@ public: // before the RenderNode is used for drawing. // RenderNode takes ownership of the pointer ANDROID_API void setPositionListener(PositionListener* listener) { - mPositionListener.reset(listener); + mPositionListener = listener; } // This is only modified in MODE_FULL, so it can be safely accessed @@ -366,7 +366,7 @@ private: // mDisplayList, not mStagingDisplayList. uint32_t mParentCount; - std::unique_ptr<PositionListener> mPositionListener; + sp<PositionListener> mPositionListener; }; // class RenderNode } /* namespace uirenderer */ diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index d4956bed25e8..ceef9c788fc1 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -784,6 +784,7 @@ void CanvasContext::enqueueFrameWork(std::function<void()>&& func) { } sp<FuncTask> task(new FuncTask()); task->func = func; + mFrameFences.push_back(task); mFrameWorkProcessor->add(task); } |