ANDROID: Store JNI environment in a thread local variable
This avoids to query JVM every time we need to do a JNI call. A different environment is attached to each thread, hence the TLS variable.
This commit is contained in:
parent
54fd20c36c
commit
e17b34c9dc
3 changed files with 40 additions and 9 deletions
|
@ -24,6 +24,12 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <android/asset_manager.h>
|
||||||
|
#include <android/asset_manager_jni.h>
|
||||||
|
|
||||||
|
#include "backends/platform/android/jni-android.h"
|
||||||
|
#include "backends/platform/android/asset-archive.h"
|
||||||
|
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include "common/stream.h"
|
#include "common/stream.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
@ -31,12 +37,6 @@
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
#include "backends/platform/android/jni-android.h"
|
|
||||||
#include "backends/platform/android/asset-archive.h"
|
|
||||||
|
|
||||||
#include <android/asset_manager.h>
|
|
||||||
#include <android/asset_manager_jni.h>
|
|
||||||
|
|
||||||
class AssetInputStream : public Common::SeekableReadStream {
|
class AssetInputStream : public Common::SeekableReadStream {
|
||||||
public:
|
public:
|
||||||
AssetInputStream(AAssetManager *as, const Common::String &path);
|
AssetInputStream(AAssetManager *as, const Common::String &path);
|
||||||
|
|
|
@ -58,6 +58,8 @@ jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
|
||||||
return JNI::onLoad(vm);
|
return JNI::onLoad(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_key_t JNI::_env_tls;
|
||||||
|
|
||||||
JavaVM *JNI::_vm = 0;
|
JavaVM *JNI::_vm = 0;
|
||||||
jobject JNI::_jobj = 0;
|
jobject JNI::_jobj = 0;
|
||||||
jobject JNI::_jobj_audio_track = 0;
|
jobject JNI::_jobj_audio_track = 0;
|
||||||
|
@ -141,6 +143,10 @@ JNI::~JNI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
jint JNI::onLoad(JavaVM *vm) {
|
jint JNI::onLoad(JavaVM *vm) {
|
||||||
|
if (pthread_key_create(&_env_tls, NULL)) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
_vm = vm;
|
_vm = vm;
|
||||||
|
|
||||||
JNIEnv *env;
|
JNIEnv *env;
|
||||||
|
@ -148,6 +154,10 @@ jint JNI::onLoad(JavaVM *vm) {
|
||||||
if (_vm->GetEnv((void **)&env, JNI_VERSION_1_2))
|
if (_vm->GetEnv((void **)&env, JNI_VERSION_1_2))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
|
if (pthread_setspecific(_env_tls, env)) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
jclass cls = env->FindClass("org/scummvm/scummvm/ScummVM");
|
jclass cls = env->FindClass("org/scummvm/scummvm/ScummVM");
|
||||||
if (cls == 0)
|
if (cls == 0)
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
@ -158,8 +168,8 @@ jint JNI::onLoad(JavaVM *vm) {
|
||||||
return JNI_VERSION_1_2;
|
return JNI_VERSION_1_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEnv *JNI::getEnv() {
|
JNIEnv *JNI::fetchEnv() {
|
||||||
JNIEnv *env = 0;
|
JNIEnv *env;
|
||||||
|
|
||||||
jint res = _vm->GetEnv((void **)&env, JNI_VERSION_1_2);
|
jint res = _vm->GetEnv((void **)&env, JNI_VERSION_1_2);
|
||||||
|
|
||||||
|
@ -168,6 +178,8 @@ JNIEnv *JNI::getEnv() {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_setspecific(_env_tls, env);
|
||||||
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,9 +192,16 @@ void JNI::attachThread() {
|
||||||
LOGE("AttachCurrentThread() failed: %d", res);
|
LOGE("AttachCurrentThread() failed: %d", res);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pthread_setspecific(_env_tls, env)) {
|
||||||
|
LOGE("pthread_setspecific() failed");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JNI::detachThread() {
|
void JNI::detachThread() {
|
||||||
|
pthread_setspecific(_env_tls, NULL);
|
||||||
|
|
||||||
jint res = _vm->DetachCurrentThread();
|
jint res = _vm->DetachCurrentThread();
|
||||||
|
|
||||||
if (res != JNI_OK) {
|
if (res != JNI_OK) {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "common/fs.h"
|
#include "common/fs.h"
|
||||||
#include "common/archive.h"
|
#include "common/archive.h"
|
||||||
|
@ -59,7 +60,14 @@ public:
|
||||||
|
|
||||||
static jint onLoad(JavaVM *vm);
|
static jint onLoad(JavaVM *vm);
|
||||||
|
|
||||||
static JNIEnv *getEnv();
|
static inline JNIEnv *getEnv() {
|
||||||
|
JNIEnv *env = (JNIEnv*) pthread_getspecific(_env_tls);
|
||||||
|
if (env != nullptr) {
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fetchEnv();
|
||||||
|
}
|
||||||
|
|
||||||
static void attachThread();
|
static void attachThread();
|
||||||
static void detachThread();
|
static void detachThread();
|
||||||
|
@ -102,6 +110,8 @@ public:
|
||||||
static bool isDirectoryWritableWithSAF(const Common::String &dirPath);
|
static bool isDirectoryWritableWithSAF(const Common::String &dirPath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static pthread_key_t _env_tls;
|
||||||
|
|
||||||
static JavaVM *_vm;
|
static JavaVM *_vm;
|
||||||
// back pointer to (java) peer instance
|
// back pointer to (java) peer instance
|
||||||
static jobject _jobj;
|
static jobject _jobj;
|
||||||
|
@ -172,6 +182,8 @@ private:
|
||||||
static Common::U32String convertFromJString(JNIEnv *env, const jstring &jstr);
|
static Common::U32String convertFromJString(JNIEnv *env, const jstring &jstr);
|
||||||
|
|
||||||
static PauseToken _pauseToken;
|
static PauseToken _pauseToken;
|
||||||
|
|
||||||
|
static JNIEnv *fetchEnv();
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool JNI::haveSurface() {
|
inline bool JNI::haveSurface() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue