diff options
-rw-r--r-- | graphics/java/android/graphics/HardwareRenderer.java | 4 | ||||
-rw-r--r-- | libs/hwui/jni/android_graphics_HardwareRenderer.cpp | 34 |
2 files changed, 34 insertions, 4 deletions
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java index 954d062b55e9..6aa74cb415f9 100644 --- a/graphics/java/android/graphics/HardwareRenderer.java +++ b/graphics/java/android/graphics/HardwareRenderer.java @@ -753,8 +753,12 @@ public class HardwareRenderer { nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater()); } + private ASurfaceTransactionCallback mASurfaceTransactionCallback; + /** @hide */ public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) { + // ensure callback is kept alive on the java side since weak ref is used in native code + mASurfaceTransactionCallback = callback; nSetASurfaceTransactionCallback(mNativeProxy, callback); } diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp index 602c32a966d3..819a34b21a05 100644 --- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp +++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp @@ -500,6 +500,28 @@ private: jobject mObject; }; +class JWeakGlobalRefHolder { +public: + JWeakGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm) { + mWeakRef = getenv(vm)->NewWeakGlobalRef(object); + } + + virtual ~JWeakGlobalRefHolder() { + if (mWeakRef != nullptr) getenv(mVm)->DeleteWeakGlobalRef(mWeakRef); + mWeakRef = nullptr; + } + + jobject ref() { return mWeakRef; } + JavaVM* vm() { return mVm; } + +private: + JWeakGlobalRefHolder(const JWeakGlobalRefHolder&) = delete; + void operator=(const JWeakGlobalRefHolder&) = delete; + + JavaVM* mVm; + jobject mWeakRef; +}; + using TextureMap = std::unordered_map<uint32_t, sk_sp<SkImage>>; struct PictureCaptureState { @@ -633,15 +655,19 @@ static void android_view_ThreadedRenderer_setASurfaceTransactionCallback( } else { JavaVM* vm = nullptr; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); - auto globalCallbackRef = std::make_shared<JGlobalRefHolder>( - vm, env->NewGlobalRef(aSurfaceTransactionCallback)); + auto globalCallbackRef = + std::make_shared<JWeakGlobalRefHolder>(vm, aSurfaceTransactionCallback); proxy->setASurfaceTransactionCallback( [globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) { JNIEnv* env = getenv(globalCallbackRef->vm()); - env->CallVoidMethod(globalCallbackRef->object(), - gASurfaceTransactionCallback.onMergeTransaction, + jobject localref = env->NewLocalRef(globalCallbackRef->ref()); + if (CC_UNLIKELY(!localref)) { + return; + } + env->CallVoidMethod(localref, gASurfaceTransactionCallback.onMergeTransaction, static_cast<jlong>(transObj), static_cast<jlong>(scObj), static_cast<jlong>(frameNr)); + env->DeleteLocalRef(localref); }); } } |