Merge "Fix potential ASurfaceTransactionCallback leaks" into sc-dev

This commit is contained in:
Huihong Luo
2021-06-17 16:32:06 +00:00
committed by Android (Google) Code Review
2 changed files with 34 additions and 4 deletions

View File

@@ -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);
}

View File

@@ -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);
});
}
}