Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2dc11c05 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Fix SurfaceViewPositionListener race bugs"

parents 5c043f51 85ddb2df
Loading
Loading
Loading
Loading
+21 −30
Original line number Diff line number Diff line
@@ -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);
                env->DeleteWeakGlobalRef(mWeakRef);
                mWeakRef = nullptr;
                return;
            }

            } else {
                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);
                mWeakRef = nullptr;
                return;
            }

            env->CallVoidMethod(localref, gSurfaceViewPositionLostMethod, frameNumber);
            env->DeleteLocalRef(localref);
            // We need to release ourselves here
            decStrong(0);
        }

        JavaVM* mVm;
+3 −3
Original line number Diff line number Diff line
@@ -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 */
+1 −0
Original line number Diff line number Diff line
@@ -783,6 +783,7 @@ void CanvasContext::enqueueFrameWork(std::function<void()>&& func) {
    }
    sp<FuncTask> task(new FuncTask());
    task->func = func;
    mFrameFences.push_back(task);
    mFrameWorkProcessor->add(task);
}