summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android/graphics/SurfaceTexture.cpp41
1 files changed, 31 insertions, 10 deletions
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 30ef8dfad904..dd8b3780f06c 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -91,7 +91,8 @@ public:
virtual void onFrameAvailable();
private:
- static JNIEnv* getJNIEnv();
+ static JNIEnv* getJNIEnv(bool* needsDetach);
+ static void detachJNI();
jobject mWeakThiz;
jclass mClazz;
@@ -103,37 +104,57 @@ JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env,
mClazz((jclass)env->NewGlobalRef(clazz))
{}
-JNIEnv* JNISurfaceTextureContext::getJNIEnv() {
- JNIEnv* env;
- JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
+JNIEnv* JNISurfaceTextureContext::getJNIEnv(bool* needsDetach) {
+ *needsDetach = false;
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (env == NULL) {
+ JavaVMAttachArgs args = {JNI_VERSION_1_4, NULL, NULL};
+ JavaVM* vm = AndroidRuntime::getJavaVM();
+ int result = vm->AttachCurrentThread(&env, (void*) &args);
+ if (result != JNI_OK) {
+ LOGE("thread attach failed: %#x", result);
+ return NULL;
+ }
+ *needsDetach = true;
+ }
+ return env;
+}
+
+void JNISurfaceTextureContext::detachJNI() {
JavaVM* vm = AndroidRuntime::getJavaVM();
- int result = vm->AttachCurrentThread(&env, (void*) &args);
+ int result = vm->DetachCurrentThread();
if (result != JNI_OK) {
- LOGE("thread attach failed: %#x", result);
- return NULL;
+ LOGE("thread detach failed: %#x", result);
}
- return env;
}
JNISurfaceTextureContext::~JNISurfaceTextureContext()
{
- JNIEnv* env = getJNIEnv();
+ bool needsDetach = false;
+ JNIEnv* env = getJNIEnv(&needsDetach);
if (env != NULL) {
env->DeleteGlobalRef(mWeakThiz);
env->DeleteGlobalRef(mClazz);
} else {
LOGW("leaking JNI object references");
}
+ if (needsDetach) {
+ detachJNI();
+ }
}
void JNISurfaceTextureContext::onFrameAvailable()
{
- JNIEnv *env = getJNIEnv();
+ bool needsDetach = false;
+ JNIEnv* env = getJNIEnv(&needsDetach);
if (env != NULL) {
env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz);
} else {
LOGW("onFrameAvailable event will not posted");
}
+ if (needsDetach) {
+ detachJNI();
+ }
}
// ----------------------------------------------------------------------------