ANDROID: Various cleanups in JNI
Mostly fixing memory leaks (Java references). No need to preinit semaphore (sem_init is called). First initialize methods ID before starting anything. Aborts if a method is not found.
This commit is contained in:
parent
9631567923
commit
c60ad0a554
1 changed files with 38 additions and 25 deletions
|
@ -71,7 +71,7 @@ Common::Archive *JNI::_asset_archive = 0;
|
||||||
OSystem_Android *JNI::_system = 0;
|
OSystem_Android *JNI::_system = 0;
|
||||||
|
|
||||||
bool JNI::pause = false;
|
bool JNI::pause = false;
|
||||||
sem_t JNI::pause_sem = { 0 };
|
sem_t JNI::pause_sem;
|
||||||
|
|
||||||
int JNI::surface_changeid = 0;
|
int JNI::surface_changeid = 0;
|
||||||
int JNI::egl_surface_width = 0;
|
int JNI::egl_surface_width = 0;
|
||||||
|
@ -165,6 +165,7 @@ jint JNI::onLoad(JavaVM *vm) {
|
||||||
if (env->RegisterNatives(cls, _natives, ARRAYSIZE(_natives)) < 0)
|
if (env->RegisterNatives(cls, _natives, ARRAYSIZE(_natives)) < 0)
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
|
env->DeleteLocalRef(cls);
|
||||||
return JNI_VERSION_1_2;
|
return JNI_VERSION_1_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,6 +551,7 @@ void JNI::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
|
||||||
|
|
||||||
env->DeleteLocalRef(path_obj);
|
env->DeleteLocalRef(path_obj);
|
||||||
}
|
}
|
||||||
|
env->DeleteLocalRef(array);
|
||||||
|
|
||||||
// add the internal asset (android's structure) with a lower priority,
|
// add the internal asset (android's structure) with a lower priority,
|
||||||
// since:
|
// since:
|
||||||
|
@ -576,6 +578,7 @@ bool JNI::initSurface() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_jobj_egl_surface = env->NewGlobalRef(obj);
|
_jobj_egl_surface = env->NewGlobalRef(obj);
|
||||||
|
env->DeleteLocalRef(obj);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -583,6 +586,9 @@ bool JNI::initSurface() {
|
||||||
void JNI::deinitSurface() {
|
void JNI::deinitSurface() {
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
env->DeleteGlobalRef(_jobj_egl_surface);
|
||||||
|
_jobj_egl_surface = 0;
|
||||||
|
|
||||||
env->CallVoidMethod(_jobj, _MID_deinitSurface);
|
env->CallVoidMethod(_jobj, _MID_deinitSurface);
|
||||||
|
|
||||||
if (env->ExceptionCheck()) {
|
if (env->ExceptionCheck()) {
|
||||||
|
@ -591,9 +597,6 @@ void JNI::deinitSurface() {
|
||||||
env->ExceptionDescribe();
|
env->ExceptionDescribe();
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
}
|
}
|
||||||
|
|
||||||
env->DeleteGlobalRef(_jobj_egl_surface);
|
|
||||||
_jobj_egl_surface = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void JNI::setAudioPause() {
|
void JNI::setAudioPause() {
|
||||||
|
@ -649,19 +652,11 @@ void JNI::setAudioStop() {
|
||||||
void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||||
jobject egl, jobject egl_display,
|
jobject egl, jobject egl_display,
|
||||||
jobject at, jint audio_sample_rate, jint audio_buffer_size) {
|
jobject at, jint audio_sample_rate, jint audio_buffer_size) {
|
||||||
LOGI("%s", gScummVMFullVersion);
|
LOGI("Native version: %s", gScummVMFullVersion);
|
||||||
|
|
||||||
assert(!_system);
|
assert(!_system);
|
||||||
|
|
||||||
pause = false;
|
// Resolve every JNI method before anything else in case we need it
|
||||||
// initial value of zero!
|
|
||||||
sem_init(&pause_sem, 0, 0);
|
|
||||||
|
|
||||||
_asset_archive = new AndroidAssetArchive(asset_manager);
|
|
||||||
assert(_asset_archive);
|
|
||||||
|
|
||||||
_system = new OSystem_Android(audio_sample_rate, audio_buffer_size);
|
|
||||||
assert(_system);
|
|
||||||
|
|
||||||
// weak global ref to allow class to be unloaded
|
// weak global ref to allow class to be unloaded
|
||||||
// ... except dalvik implements NewWeakGlobalRef only on froyo
|
// ... except dalvik implements NewWeakGlobalRef only on froyo
|
||||||
|
@ -673,8 +668,10 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||||
|
|
||||||
#define FIND_METHOD(prefix, name, signature) do { \
|
#define FIND_METHOD(prefix, name, signature) do { \
|
||||||
_MID_ ## prefix ## name = env->GetMethodID(cls, #name, signature); \
|
_MID_ ## prefix ## name = env->GetMethodID(cls, #name, signature); \
|
||||||
if (_MID_ ## prefix ## name == 0) \
|
if (_MID_ ## prefix ## name == 0) { \
|
||||||
return; \
|
LOGE("Can't find function %s", #name); \
|
||||||
|
abort(); \
|
||||||
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
FIND_METHOD(, setWindowCaption, "(Ljava/lang/String;)V");
|
FIND_METHOD(, setWindowCaption, "(Ljava/lang/String;)V");
|
||||||
|
@ -703,6 +700,8 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||||
_jobj_egl = env->NewGlobalRef(egl);
|
_jobj_egl = env->NewGlobalRef(egl);
|
||||||
_jobj_egl_display = env->NewGlobalRef(egl_display);
|
_jobj_egl_display = env->NewGlobalRef(egl_display);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(cls);
|
||||||
|
|
||||||
cls = env->GetObjectClass(_jobj_egl);
|
cls = env->GetObjectClass(_jobj_egl);
|
||||||
|
|
||||||
FIND_METHOD(EGL10_, eglSwapBuffers,
|
FIND_METHOD(EGL10_, eglSwapBuffers,
|
||||||
|
@ -711,6 +710,8 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||||
|
|
||||||
_jobj_audio_track = env->NewGlobalRef(at);
|
_jobj_audio_track = env->NewGlobalRef(at);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(cls);
|
||||||
|
|
||||||
cls = env->GetObjectClass(_jobj_audio_track);
|
cls = env->GetObjectClass(_jobj_audio_track);
|
||||||
|
|
||||||
FIND_METHOD(AudioTrack_, flush, "()V");
|
FIND_METHOD(AudioTrack_, flush, "()V");
|
||||||
|
@ -719,8 +720,19 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
|
||||||
FIND_METHOD(AudioTrack_, stop, "()V");
|
FIND_METHOD(AudioTrack_, stop, "()V");
|
||||||
FIND_METHOD(AudioTrack_, write, "([BII)I");
|
FIND_METHOD(AudioTrack_, write, "([BII)I");
|
||||||
|
|
||||||
|
env->DeleteLocalRef(cls);
|
||||||
#undef FIND_METHOD
|
#undef FIND_METHOD
|
||||||
|
|
||||||
|
pause = false;
|
||||||
|
// initial value of zero!
|
||||||
|
sem_init(&pause_sem, 0, 0);
|
||||||
|
|
||||||
|
_asset_archive = new AndroidAssetArchive(asset_manager);
|
||||||
|
assert(_asset_archive);
|
||||||
|
|
||||||
|
_system = new OSystem_Android(audio_sample_rate, audio_buffer_size);
|
||||||
|
assert(_system);
|
||||||
|
|
||||||
g_system = _system;
|
g_system = _system;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,6 +905,8 @@ jint JNI::getAndroidSDKVersionId() {
|
||||||
|
|
||||||
jint sdkInt = env->GetStaticIntField(versionClass, sdkIntFieldID);
|
jint sdkInt = env->GetStaticIntField(versionClass, sdkIntFieldID);
|
||||||
//LOGD("sdkInt = %d", sdkInt);
|
//LOGD("sdkInt = %d", sdkInt);
|
||||||
|
|
||||||
|
env->DeleteLocalRef(versionClass);
|
||||||
return sdkInt;
|
return sdkInt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -917,7 +931,7 @@ Common::U32String JNI::convertFromJString(JNIEnv *env, const jstring &jstr) {
|
||||||
|
|
||||||
// TODO should this be a U32String array?
|
// TODO should this be a U32String array?
|
||||||
Common::Array<Common::String> JNI::getAllStorageLocations() {
|
Common::Array<Common::String> JNI::getAllStorageLocations() {
|
||||||
Common::Array<Common::String> *res = new Common::Array<Common::String>();
|
Common::Array<Common::String> res;
|
||||||
|
|
||||||
JNIEnv *env = JNI::getEnv();
|
JNIEnv *env = JNI::getEnv();
|
||||||
|
|
||||||
|
@ -930,7 +944,7 @@ Common::Array<Common::String> JNI::getAllStorageLocations() {
|
||||||
env->ExceptionDescribe();
|
env->ExceptionDescribe();
|
||||||
env->ExceptionClear();
|
env->ExceptionClear();
|
||||||
|
|
||||||
return *res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
jsize size = env->GetArrayLength(array);
|
jsize size = env->GetArrayLength(array);
|
||||||
|
@ -939,14 +953,15 @@ Common::Array<Common::String> JNI::getAllStorageLocations() {
|
||||||
const char *path = env->GetStringUTFChars(path_obj, 0);
|
const char *path = env->GetStringUTFChars(path_obj, 0);
|
||||||
|
|
||||||
if (path != 0) {
|
if (path != 0) {
|
||||||
res->push_back(path);
|
res.push_back(path);
|
||||||
env->ReleaseStringUTFChars(path_obj, path);
|
env->ReleaseStringUTFChars(path_obj, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
env->DeleteLocalRef(path_obj);
|
env->DeleteLocalRef(path_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *res;
|
env->DeleteLocalRef(array);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JNI::createDirectoryWithSAF(const Common::String &dirPath) {
|
bool JNI::createDirectoryWithSAF(const Common::String &dirPath) {
|
||||||
|
@ -1018,6 +1033,4 @@ bool JNI::isDirectoryWritableWithSAF(const Common::String &dirPath) {
|
||||||
|
|
||||||
return isWritable;
|
return isWritable;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue