Merge "Fix SurfaceViewPositionListener race bugs"
This commit is contained in:
@@ -573,8 +573,9 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
|||||||
bounds.roundOut();
|
bounds.roundOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
incStrong(0);
|
||||||
auto functor = std::bind(
|
auto functor = std::bind(
|
||||||
std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePosition), this,
|
std::mem_fn(&SurfaceViewPositionUpdater::doUpdatePositionAsync), this,
|
||||||
(jlong) info.canvasContext.getFrameNumber(),
|
(jlong) info.canvasContext.getFrameNumber(),
|
||||||
(jint) bounds.left, (jint) bounds.top,
|
(jint) bounds.left, (jint) bounds.top,
|
||||||
(jint) bounds.right, (jint) bounds.bottom);
|
(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 {
|
virtual void onPositionLost(RenderNode& node, const TreeInfo* info) override {
|
||||||
if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return;
|
if (CC_UNLIKELY(!mWeakRef || (info && !info->updateWindowPositions))) return;
|
||||||
|
|
||||||
if (info) {
|
ATRACE_NAME("SurfaceView position lost");
|
||||||
auto functor = std::bind(
|
JNIEnv* env = jnienv();
|
||||||
std::mem_fn(&SurfaceViewPositionUpdater::doNotifyPositionLost), this,
|
jobject localref = env->NewLocalRef(mWeakRef);
|
||||||
(jlong) info->canvasContext.getFrameNumber());
|
if (CC_UNLIKELY(!localref)) {
|
||||||
|
jnienv()->DeleteWeakGlobalRef(mWeakRef);
|
||||||
info->canvasContext.enqueueFrameWork(std::move(functor));
|
mWeakRef = nullptr;
|
||||||
} else {
|
return;
|
||||||
doNotifyPositionLost(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
env->CallVoidMethod(localref, gSurfaceViewPositionLostMethod,
|
||||||
|
info ? info->canvasContext.getFrameNumber() : 0);
|
||||||
|
env->DeleteLocalRef(localref);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -605,36 +609,23 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doUpdatePosition(jlong frameNumber, jint left, jint top,
|
void doUpdatePositionAsync(jlong frameNumber, jint left, jint top,
|
||||||
jint right, jint bottom) {
|
jint right, jint bottom) {
|
||||||
ATRACE_NAME("Update SurfaceView position");
|
ATRACE_NAME("Update SurfaceView position");
|
||||||
|
|
||||||
JNIEnv* env = jnienv();
|
JNIEnv* env = jnienv();
|
||||||
jobject localref = env->NewLocalRef(mWeakRef);
|
jobject localref = env->NewLocalRef(mWeakRef);
|
||||||
if (CC_UNLIKELY(!localref)) {
|
if (CC_UNLIKELY(!localref)) {
|
||||||
jnienv()->DeleteWeakGlobalRef(mWeakRef);
|
env->DeleteWeakGlobalRef(mWeakRef);
|
||||||
mWeakRef = nullptr;
|
mWeakRef = nullptr;
|
||||||
return;
|
} else {
|
||||||
|
env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod,
|
||||||
|
frameNumber, left, top, right, bottom);
|
||||||
|
env->DeleteLocalRef(localref);
|
||||||
}
|
}
|
||||||
|
|
||||||
env->CallVoidMethod(localref, gSurfaceViewPositionUpdateMethod,
|
// We need to release ourselves here
|
||||||
frameNumber, left, top, right, bottom);
|
decStrong(0);
|
||||||
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);
|
|
||||||
mWeakRef = nullptr;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
env->CallVoidMethod(localref, gSurfaceViewPositionLostMethod, frameNumber);
|
|
||||||
env->DeleteLocalRef(localref);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaVM* mVm;
|
JavaVM* mVm;
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ public:
|
|||||||
// the frameNumber to appropriately batch/synchronize these transactions.
|
// the frameNumber to appropriately batch/synchronize these transactions.
|
||||||
// There is no other filtering/batching to ensure that only the "final"
|
// There is no other filtering/batching to ensure that only the "final"
|
||||||
// state called once per frame.
|
// state called once per frame.
|
||||||
class ANDROID_API PositionListener {
|
class ANDROID_API PositionListener : public VirtualLightRefBase {
|
||||||
public:
|
public:
|
||||||
virtual ~PositionListener() {}
|
virtual ~PositionListener() {}
|
||||||
// Called when the RenderNode's position changes
|
// Called when the RenderNode's position changes
|
||||||
@@ -247,7 +247,7 @@ public:
|
|||||||
// before the RenderNode is used for drawing.
|
// before the RenderNode is used for drawing.
|
||||||
// RenderNode takes ownership of the pointer
|
// RenderNode takes ownership of the pointer
|
||||||
ANDROID_API void setPositionListener(PositionListener* listener) {
|
ANDROID_API void setPositionListener(PositionListener* listener) {
|
||||||
mPositionListener.reset(listener);
|
mPositionListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only modified in MODE_FULL, so it can be safely accessed
|
// This is only modified in MODE_FULL, so it can be safely accessed
|
||||||
@@ -366,7 +366,7 @@ private:
|
|||||||
// mDisplayList, not mStagingDisplayList.
|
// mDisplayList, not mStagingDisplayList.
|
||||||
uint32_t mParentCount;
|
uint32_t mParentCount;
|
||||||
|
|
||||||
std::unique_ptr<PositionListener> mPositionListener;
|
sp<PositionListener> mPositionListener;
|
||||||
}; // class RenderNode
|
}; // class RenderNode
|
||||||
|
|
||||||
} /* namespace uirenderer */
|
} /* namespace uirenderer */
|
||||||
|
|||||||
@@ -783,6 +783,7 @@ void CanvasContext::enqueueFrameWork(std::function<void()>&& func) {
|
|||||||
}
|
}
|
||||||
sp<FuncTask> task(new FuncTask());
|
sp<FuncTask> task(new FuncTask());
|
||||||
task->func = func;
|
task->func = func;
|
||||||
|
mFrameFences.push_back(task);
|
||||||
mFrameWorkProcessor->add(task);
|
mFrameWorkProcessor->add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user