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

Commit 4342391d authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Remove NewWeakGlobalRef from RenderNode"

parents e9b0084f 4f56f99d
Loading
Loading
Loading
Loading
+54 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import libcore.util.NativeAllocationRegistry;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;

/**
 * <p>RenderNode is used to build hardware accelerated rendering hierarchies. Each RenderNode
@@ -263,7 +264,6 @@ public final class RenderNode {
     * @hide
     */
    public interface PositionUpdateListener {

        /**
         * Called by native by a Rendering Worker thread to update window position
         *
@@ -271,6 +271,21 @@ public final class RenderNode {
         */
        void positionChanged(long frameNumber, int left, int top, int right, int bottom);

        /**
         * Called by JNI
         *
         * @hide */
        static boolean callPositionChanged(WeakReference<PositionUpdateListener> weakListener,
                long frameNumber, int left, int top, int right, int bottom) {
            final PositionUpdateListener listener = weakListener.get();
            if (listener != null) {
                listener.positionChanged(frameNumber, left, top, right, bottom);
                return true;
            } else {
                return false;
            }
        }

        /**
         * Call to apply a stretch effect to any child SurfaceControl layers
         *
@@ -285,6 +300,26 @@ public final class RenderNode {
                float maxStretchX, float maxStretchY, float childRelativeLeft,
                float childRelativeTop, float childRelativeRight, float childRelativeBottom) { }

        /**
         * Called by JNI
         *
         * @hide */
        static boolean callApplyStretch(WeakReference<PositionUpdateListener> weakListener,
                long frameNumber, float width, float height,
                float vecX, float vecY,
                float maxStretchX, float maxStretchY, float childRelativeLeft,
                float childRelativeTop, float childRelativeRight, float childRelativeBottom) {
            final PositionUpdateListener listener = weakListener.get();
            if (listener != null) {
                listener.applyStretch(frameNumber, width, height, vecX, vecY, maxStretchX,
                        maxStretchY, childRelativeLeft, childRelativeTop, childRelativeRight,
                        childRelativeBottom);
                return true;
            } else {
                return false;
            }
        }

        /**
         * Called by native on RenderThread to notify that the view is no longer in the
         * draw tree. UI thread is blocked at this point.
@@ -293,6 +328,21 @@ public final class RenderNode {
         */
        void positionLost(long frameNumber);

        /**
         * Called by JNI
         *
         * @hide */
        static boolean callPositionLost(WeakReference<PositionUpdateListener> weakListener,
                long frameNumber) {
            final PositionUpdateListener listener = weakListener.get();
            if (listener != null) {
                listener.positionLost(frameNumber);
                return true;
            } else {
                return false;
            }
        }

    }

    private static final class CompositePositionUpdateListener implements PositionUpdateListener {
@@ -353,7 +403,7 @@ public final class RenderNode {
            comp = comp.with(listener);
        }
        mCompositePositionUpdateListener = comp;
        nRequestPositionUpdates(mNativeRenderNode, comp);
        nRequestPositionUpdates(mNativeRenderNode, new WeakReference<>(comp));
    }

    /**
@@ -368,7 +418,7 @@ public final class RenderNode {
        if (comp != null) {
            comp = comp.without(listener);
            mCompositePositionUpdateListener = comp;
            nRequestPositionUpdates(mNativeRenderNode, comp);
            nRequestPositionUpdates(mNativeRenderNode, new WeakReference<>(comp));
        }
    }

@@ -1575,7 +1625,7 @@ public final class RenderNode {
    private static native int nGetAllocatedSize(long renderNode);

    private static native void nRequestPositionUpdates(long renderNode,
            PositionUpdateListener callback);
            WeakReference<PositionUpdateListener> callback);

    // Animations

+43 −51
Original line number Diff line number Diff line
@@ -547,9 +547,12 @@ static void android_view_RenderNode_endAllAnimators(JNIEnv* env, jobject clazz,
// SurfaceView position callback
// ----------------------------------------------------------------------------

jmethodID gPositionListener_PositionChangedMethod;
jmethodID gPositionListener_ApplyStretchMethod;
jmethodID gPositionListener_PositionLostMethod;
struct {
    jclass clazz;
    jmethodID callPositionChanged;
    jmethodID callApplyStretch;
    jmethodID callPositionLost;
} gPositionListener;

static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
        jlong renderNodePtr, jobject listener) {
@@ -557,16 +560,16 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
    public:
        PositionListenerTrampoline(JNIEnv* env, jobject listener) {
            env->GetJavaVM(&mVm);
            mWeakRef = env->NewWeakGlobalRef(listener);
            mListener = env->NewGlobalRef(listener);
        }

        virtual ~PositionListenerTrampoline() {
            jnienv()->DeleteWeakGlobalRef(mWeakRef);
            mWeakRef = nullptr;
            jnienv()->DeleteGlobalRef(mListener);
            mListener = nullptr;
        }

        virtual void onPositionUpdated(RenderNode& node, const TreeInfo& info) override {
            if (CC_UNLIKELY(!mWeakRef || !info.updateWindowPositions)) return;
            if (CC_UNLIKELY(!mListener || !info.updateWindowPositions)) return;

            Matrix4 transform;
            info.damageAccumulator->computeCurrentTransform(&transform);
@@ -609,7 +612,7 @@ 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 (CC_UNLIKELY(!mListener || (info && !info->updateWindowPositions))) return;

            if (mPreviousPosition.isEmpty()) {
                return;
@@ -618,18 +621,16 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,

            ATRACE_NAME("SurfaceView position lost");
            JNIEnv* env = jnienv();
            jobject localref = env->NewLocalRef(mWeakRef);
            if (CC_UNLIKELY(!localref)) {
                env->DeleteWeakGlobalRef(mWeakRef);
                mWeakRef = nullptr;
                return;
            }
#ifdef __ANDROID__ // Layoutlib does not support CanvasContext
            // TODO: Remember why this is synchronous and then make a comment
            env->CallVoidMethod(localref, gPositionListener_PositionLostMethod,
            jboolean keepListening = env->CallStaticBooleanMethod(
                    gPositionListener.clazz, gPositionListener.callPositionLost, mListener,
                    info ? info->canvasContext.getFrameNumber() : 0);
            if (!keepListening) {
                env->DeleteGlobalRef(mListener);
                mListener = nullptr;
            }
#endif
            env->DeleteLocalRef(localref);
        }

    private:
@@ -684,28 +685,20 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
                StretchEffectBehavior::Shader) {
                JNIEnv* env = jnienv();

                jobject localref = env->NewLocalRef(mWeakRef);
                if (CC_UNLIKELY(!localref)) {
                    env->DeleteWeakGlobalRef(mWeakRef);
                    mWeakRef = nullptr;
                    return;
                }
#ifdef __ANDROID__  // Layoutlib does not support CanvasContext
                SkVector stretchDirection = effect->getStretchDirection();
                env->CallVoidMethod(localref, gPositionListener_ApplyStretchMethod,
                                    info.canvasContext.getFrameNumber(),
                                    result.width,
                                    result.height,
                                    stretchDirection.fX,
                                    stretchDirection.fY,
                                    effect->maxStretchAmountX,
                                    effect->maxStretchAmountY,
                                    childRelativeBounds.left(),
                                    childRelativeBounds.top(),
                                    childRelativeBounds.right(),
                jboolean keepListening = env->CallStaticBooleanMethod(
                        gPositionListener.clazz, gPositionListener.callApplyStretch, mListener,
                        info.canvasContext.getFrameNumber(), result.width, result.height,
                        stretchDirection.fX, stretchDirection.fY, effect->maxStretchAmountX,
                        effect->maxStretchAmountY, childRelativeBounds.left(),
                        childRelativeBounds.top(), childRelativeBounds.right(),
                        childRelativeBounds.bottom());
                if (!keepListening) {
                    env->DeleteGlobalRef(mListener);
                    mListener = nullptr;
                }
#endif
                env->DeleteLocalRef(localref);
            }
        }

@@ -714,14 +707,12 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
            ATRACE_NAME("Update SurfaceView position");

            JNIEnv* env = jnienv();
            jobject localref = env->NewLocalRef(mWeakRef);
            if (CC_UNLIKELY(!localref)) {
                env->DeleteWeakGlobalRef(mWeakRef);
                mWeakRef = nullptr;
            } else {
                env->CallVoidMethod(localref, gPositionListener_PositionChangedMethod,
            jboolean keepListening = env->CallStaticBooleanMethod(
                    gPositionListener.clazz, gPositionListener.callPositionChanged, mListener,
                    frameNumber, left, top, right, bottom);
                env->DeleteLocalRef(localref);
            if (!keepListening) {
                env->DeleteGlobalRef(mListener);
                mListener = nullptr;
            }

            // We need to release ourselves here
@@ -729,7 +720,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
        }

        JavaVM* mVm;
        jobject mWeakRef;
        jobject mListener;
        uirenderer::Rect mPreviousPosition;
    };

@@ -754,7 +745,7 @@ static const JNINativeMethod gMethods[] = {
        {"nGetAllocatedSize", "(J)I", (void*)android_view_RenderNode_getAllocatedSize},
        {"nAddAnimator", "(JJ)V", (void*)android_view_RenderNode_addAnimator},
        {"nEndAllAnimators", "(J)V", (void*)android_view_RenderNode_endAllAnimators},
        {"nRequestPositionUpdates", "(JLandroid/graphics/RenderNode$PositionUpdateListener;)V",
        {"nRequestPositionUpdates", "(JLjava/lang/ref/WeakReference;)V",
         (void*)android_view_RenderNode_requestPositionUpdates},

        // ----------------------------------------------------------------------------
@@ -852,12 +843,13 @@ static const JNINativeMethod gMethods[] = {

int register_android_view_RenderNode(JNIEnv* env) {
    jclass clazz = FindClassOrDie(env, "android/graphics/RenderNode$PositionUpdateListener");
    gPositionListener_PositionChangedMethod = GetMethodIDOrDie(env, clazz,
            "positionChanged", "(JIIII)V");
    gPositionListener_ApplyStretchMethod =
            GetMethodIDOrDie(env, clazz, "applyStretch", "(JFFFFFFFFFF)V");
    gPositionListener_PositionLostMethod = GetMethodIDOrDie(env, clazz,
            "positionLost", "(J)V");
    gPositionListener.clazz = MakeGlobalRefOrDie(env, clazz);
    gPositionListener.callPositionChanged = GetStaticMethodIDOrDie(
            env, clazz, "callPositionChanged", "(Ljava/lang/ref/WeakReference;JIIII)Z");
    gPositionListener.callApplyStretch = GetStaticMethodIDOrDie(
            env, clazz, "callApplyStretch", "(Ljava/lang/ref/WeakReference;JFFFFFFFFFF)Z");
    gPositionListener.callPositionLost = GetStaticMethodIDOrDie(
            env, clazz, "callPositionLost", "(Ljava/lang/ref/WeakReference;J)Z");
    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}