Fix SurfaceTexture listener performance

Attaching & detaching threads from JavaVM isn't cheap. There's
no reason to do a detach anyway, so just don't. This avoids
subsequent callbacks needing to re-attach.

This aligns SurfaceTexture to the common pattern elsewhere
in the platform for attaching as a daemon if it's not a java
thread.

Fixes: 26842782
Test: make
Change-Id: I9bebe288dc8896c1f2c47cc1b02409526926cef7
This commit is contained in:
John Reck
2021-10-19 11:35:14 -04:00
parent b1635458d0
commit ab45cf3da3

View File

@@ -147,8 +147,7 @@ public:
virtual void onFrameAvailable(const BufferItem& item);
private:
static JNIEnv* getJNIEnv(bool* needsDetach);
static void detachJNI();
static JNIEnv* getJNIEnv();
jobject mWeakThiz;
jclass mClazz;
@@ -160,58 +159,40 @@ JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
mClazz((jclass)env->NewGlobalRef(clazz))
{}
JNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
*needsDetach = false;
JNIEnv* JNISurfaceTextureContext::getJNIEnv() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
if (env == NULL) {
JavaVMAttachArgs args = {
JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL };
JavaVM* vm = AndroidRuntime::getJavaVM();
int result = vm->AttachCurrentThread(&env, (void*) &args);
int result = vm->AttachCurrentThreadAsDaemon(&env, (void*)&args);
if (result != JNI_OK) {
ALOGE("thread attach failed: %#x", result);
return NULL;
}
*needsDetach = true;
}
return env;
}
void JNISurfaceTextureContext::detachJNI() {
JavaVM* vm = AndroidRuntime::getJavaVM();
int result = vm->DetachCurrentThread();
if (result != JNI_OK) {
ALOGE("thread detach failed: %#x", result);
}
}
JNISurfaceTextureContext::~JNISurfaceTextureContext()
{
bool needsDetach = false;
JNIEnv* env = getJNIEnv(&needsDetach);
JNIEnv* env = getJNIEnv();
if (env != NULL) {
env->DeleteGlobalRef(mWeakThiz);
env->DeleteGlobalRef(mClazz);
} else {
ALOGW("leaking JNI object references");
}
if (needsDetach) {
detachJNI();
}
}
void JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */)
{
bool needsDetach = false;
JNIEnv* env = getJNIEnv(&needsDetach);
JNIEnv* env = getJNIEnv();
if (env != NULL) {
env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
} else {
ALOGW("onFrameAvailable event will not posted");
}
if (needsDetach) {
detachJNI();
}
}
// ----------------------------------------------------------------------------