diff options
-rw-r--r-- | backends/platform/android/android.cpp | 25 | ||||
-rw-r--r-- | backends/platform/android/jni.cpp | 29 | ||||
-rw-r--r-- | backends/platform/android/jni.h | 4 |
3 files changed, 53 insertions, 5 deletions
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp index 484f6886ec..d4a2253c30 100644 --- a/backends/platform/android/android.cpp +++ b/backends/platform/android/android.cpp @@ -151,6 +151,12 @@ void *OSystem_Android::timerThreadFunc(void *arg) { tv.tv_nsec = 100 * 1000 * 1000; // 100ms while (!system->_timer_thread_exit) { + if (JNI::pause) { + LOGD("timer thread going to sleep"); + sem_wait(&JNI::pause_sem); + LOGD("timer thread woke up"); + } + timer->handler(); nanosleep(&tv, 0); } @@ -192,6 +198,12 @@ void *OSystem_Android::audioThreadFunc(void *arg) { uint silence_count = 33; while (!system->_audio_thread_exit) { + if (JNI::pause) { + LOGD("audio thread going to sleep"); + sem_wait(&JNI::pause_sem); + LOGD("audio thread woke up"); + } + buf = (byte *)env->GetPrimitiveArrayCritical(bufa, 0); assert(buf); @@ -401,6 +413,19 @@ bool OSystem_Android::pollEvent(Common::Event &event) { _screen_changeid = JNI::surface_changeid; JNI::deinitSurface(); } + + if (JNI::pause) { + // release some resources + // TODO + // free textures? they're garbled anyway since no engine + // respects EVENT_SCREEN_CHANGED + LOGD("deinitialiting surface"); + JNI::deinitSurface(); + + LOGD("main thread going to sleep"); + sem_wait(&JNI::pause_sem); + LOGD("main thread woke up"); + } } lockMutex(_event_queue_lock); diff --git a/backends/platform/android/jni.cpp b/backends/platform/android/jni.cpp index 1e28b065b4..9ecd9577e7 100644 --- a/backends/platform/android/jni.cpp +++ b/backends/platform/android/jni.cpp @@ -48,6 +48,9 @@ jobject JNI::_jobj_egl_surface = 0; Common::Archive *JNI::_asset_archive = 0; OSystem_Android *JNI::_system = 0; +bool JNI::pause = false; +sem_t JNI::pause_sem = { 0 }; + int JNI::surface_changeid = 0; int JNI::egl_surface_width = 0; int JNI::egl_surface_height = 0; @@ -417,6 +420,10 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager, jobject at, jint audio_sample_rate, jint audio_buffer_size) { assert(!_system); + pause = false; + // initial value of zero! + sem_init(&pause_sem, 0, 0); + _asset_archive = new AndroidAssetArchive(asset_manager); assert(_asset_archive); @@ -477,6 +484,8 @@ void JNI::destroy(JNIEnv *env, jobject self) { g_system = 0; _system = 0; + sem_destroy(&pause_sem); + // see above //JNI::getEnv()->DeleteWeakGlobalRef(_jobj); @@ -616,13 +625,23 @@ void JNI::enableZoning(JNIEnv *env, jobject self, jboolean enable) { _system->enableZoning(enable); } -void JNI::pauseEngine(JNIEnv *env, jobject self, jboolean pause) { - if (!_system || !g_engine) +void JNI::pauseEngine(JNIEnv *env, jobject self, jboolean value) { + if (!_system) return; - if ((pause && !g_engine->isPaused()) || (!pause && g_engine->isPaused())) { - LOGD("pauseEngine: %d", pause); - g_engine->pauseEngine(pause); + if (g_engine) + if ((value && !g_engine->isPaused()) || + (!value && g_engine->isPaused())) { + LOGD("pauseEngine: %d", value); + g_engine->pauseEngine(value); + } + + pause = value; + + if (!pause) { + // wake up all threads + for (uint i = 0; i < 3; ++i) + sem_post(&pause_sem); } } diff --git a/backends/platform/android/jni.h b/backends/platform/android/jni.h index 7eb10791aa..569a3dd79b 100644 --- a/backends/platform/android/jni.h +++ b/backends/platform/android/jni.h @@ -29,6 +29,7 @@ #if defined(__ANDROID__) #include <jni.h> +#include <semaphore.h> #include "common/fs.h" #include "common/archive.h" @@ -41,6 +42,9 @@ private: virtual ~JNI(); public: + static bool pause; + static sem_t pause_sem; + static int surface_changeid; static int egl_surface_width; static int egl_surface_height; |