From 8a58858d84caa4c92552b42e78db302e608de800 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 30 Dec 2012 18:24:30 +0100 Subject: [PATCH] Refactor out save stating and reentrancy. It's not really needed. --- android/native/jni/android_general.h | 9 -- android/native/jni/android_glue.h | 5 +- android/native/jni/main.c | 219 +++++++-------------------- driver.h | 3 - gfx/context/androidegl_ctx.c | 7 +- 5 files changed, 62 insertions(+), 181 deletions(-) diff --git a/android/native/jni/android_general.h b/android/native/jni/android_general.h index e11b727cd9..a358f5692f 100644 --- a/android/native/jni/android_general.h +++ b/android/native/jni/android_general.h @@ -20,20 +20,11 @@ #include "android_glue.h" #include "../../../boolean.h" -struct saved_state -{ - int32_t x; - int32_t y; - uint64_t lifecycle_state; -}; - struct droid { struct android_app* app; unsigned width; unsigned height; - struct saved_state state; - int32_t last_orient; bool window_ready; float disp_refresh_rate; jobject class_loader_obj; diff --git a/android/native/jni/android_glue.h b/android/native/jni/android_glue.h index 0c4b5c9608..592191010b 100644 --- a/android/native/jni/android_glue.h +++ b/android/native/jni/android_glue.h @@ -60,7 +60,6 @@ struct android_app int running; int stateSaved; - int destroyed; int redrawNeeded; AInputQueue* pendingInputQueue; ANativeWindow* pendingWindow; @@ -167,12 +166,14 @@ enum { * and waiting for the app thread to clean up and exit before proceeding. */ APP_CMD_DESTROY, + + // Set by thread when it will no longer reply to commands. + APP_CMD_DEAD, }; int8_t android_app_read_cmd(struct android_app* android_app); extern void engine_app_read_cmd(struct android_app *app); extern void engine_handle_cmd(struct android_app* android_app, int32_t cmd); -extern void free_saved_state(struct android_app* android_app); #endif /* _ANDROID_NATIVE_APP_GLUE_H */ diff --git a/android/native/jni/main.c b/android/native/jni/main.c index 3b3a9998c8..44bd238df1 100644 --- a/android/native/jni/main.c +++ b/android/native/jni/main.c @@ -28,20 +28,6 @@ #include "../../../config.def.h" -void free_saved_state(struct android_app* android_app) -{ - pthread_mutex_lock(&android_app->mutex); - - if (android_app->savedState != NULL) - { - free(android_app->savedState); - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } - - pthread_mutex_unlock(&android_app->mutex); -} - static void print_cur_config(struct android_app* android_app) { char lang[2], country[2]; @@ -78,11 +64,13 @@ void engine_handle_cmd(struct android_app* android_app, int32_t cmd) case APP_CMD_INPUT_CHANGED: RARCH_LOG("APP_CMD_INPUT_CHANGED\n"); - /* PRE-EXEC */ pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) AInputQueue_detachLooper(android_app->inputQueue); + android_app->inputQueue = android_app->pendingInputQueue; + if (android_app->inputQueue != NULL) { RARCH_LOG("Attaching input queue to looper"); @@ -90,131 +78,99 @@ void engine_handle_cmd(struct android_app* android_app, int32_t cmd) android_app->looper, LOOPER_ID_INPUT, NULL, NULL); } + pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); break; - case APP_CMD_SAVE_STATE: - RARCH_LOG("engine_handle_cmd: APP_CMD_SAVE_STATE.\n"); - /* EXEC */ - /* The system has asked us to save our current state. Do so. */ - android_app->savedState = malloc(sizeof(struct saved_state)); - *((struct saved_state*)android_app->savedState) = g_android.state; - android_app->savedStateSize = sizeof(struct saved_state); - - /* POSTEXEC */ - pthread_mutex_lock(&android_app->mutex); - android_app->stateSaved = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - - break; case APP_CMD_INIT_WINDOW: RARCH_LOG("engine_handle_cmd: APP_CMD_INIT_WINDOW.\n"); pthread_mutex_lock(&android_app->mutex); - - /* PREEXEC */ - - /* EXEC */ - /* The window is being shown, get it ready. */ android_app->window = android_app->pendingWindow; - - pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); - - break; + case APP_CMD_RESUME: RARCH_LOG("engine_handle_cmd: APP_CMD_RESUME.\n"); - /* PREEXEC */ pthread_mutex_lock(&android_app->mutex); android_app->activityState = cmd; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); - - /* POSTEXEC */ - free_saved_state(android_app); - break; + case APP_CMD_START: RARCH_LOG("engine_handle_cmd: APP_CMD_START.\n"); - /* PREEXEC */ pthread_mutex_lock(&android_app->mutex); android_app->activityState = cmd; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); break; + case APP_CMD_PAUSE: RARCH_LOG("engine_handle_cmd: APP_CMD_PAUSE.\n"); - /* PREEXEC */ pthread_mutex_lock(&android_app->mutex); android_app->activityState = cmd; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); - /* EXEC */ - if(g_extern.lifecycle_state & (1ULL << RARCH_QUIT_KEY)) { } - else + if (!(g_extern.lifecycle_state & (1ULL << RARCH_QUIT_KEY))) { - /* Setting reentrancy */ - RARCH_LOG("Setting up RetroArch re-entrancy...\n"); - g_extern.lifecycle_state |= (1ULL << RARCH_REENTRANT); + RARCH_LOG("Pausing RetroArch.\n"); g_extern.lifecycle_state |= (1ULL << RARCH_PAUSE_TOGGLE); } break; + case APP_CMD_STOP: RARCH_LOG("engine_handle_cmd: APP_CMD_STOP.\n"); - /* PREEXEC */ pthread_mutex_lock(&android_app->mutex); android_app->activityState = cmd; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); break; + case APP_CMD_CONFIG_CHANGED: RARCH_LOG("engine_handle_cmd: APP_CMD_CONFIG_CHANGED.\n"); break; + case APP_CMD_TERM_WINDOW: RARCH_LOG("engine_handle_cmd: APP_CMD_TERM_WINDOW.\n"); pthread_mutex_lock(&android_app->mutex); - /* PREEXEC */ - /* EXEC */ /* The window is being hidden or closed, clean it up. */ /* terminate display/EGL context here */ - if(g_extern.lifecycle_state & (1ULL << RARCH_REENTRANT)) + if (g_extern.lifecycle_state & (1ULL << RARCH_PAUSE_TOGGLE)) { uninit_drivers(); g_android.window_ready = false; } + else + RARCH_WARN("Window is terminated outside PAUSED state.\n"); - /* POSTEXEC */ android_app->window = NULL; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); break; + case APP_CMD_GAINED_FOCUS: RARCH_LOG("engine_handle_cmd: APP_CMD_GAINED_FOCUS.\n"); g_extern.lifecycle_state &= ~(1ULL << RARCH_PAUSE_TOGGLE); - /* EXEC */ break; + case APP_CMD_LOST_FOCUS: RARCH_LOG("engine_handle_cmd: APP_CMD_LOST_FOCUS.\n"); - - /* EXEC */ break; + case APP_CMD_DESTROY: RARCH_LOG("engine_handle_cmd: APP_CMD_DESTROY\n"); - - /* PREEXEC */ g_extern.lifecycle_state |= (1ULL << RARCH_QUIT_KEY); break; } @@ -230,19 +186,14 @@ static bool android_run_events(struct android_app* android_app) { int8_t cmd; - if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) - { - if(cmd == APP_CMD_SAVE_STATE) - free_saved_state(android_app); - } - else + if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd)) cmd = -1; engine_handle_cmd(android_app, cmd); if (cmd == APP_CMD_INIT_WINDOW) { - if (g_extern.lifecycle_state & (1ULL << RARCH_REENTRANT)) + if (g_extern.lifecycle_state & (1ULL << RARCH_PAUSE_TOGGLE)) init_drivers(); if (android_app->window != NULL) @@ -366,6 +317,7 @@ static int android_app_set_argv(char** argv) static void* android_app_entry(void* param) { struct android_app* android_app = (struct android_app*)param; + int init_ret = -1; android_app->config = AConfiguration_new(); AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); @@ -387,30 +339,13 @@ static void* android_app_entry(void* param) char *argv[MAX_ARGS] = {NULL}; int argc = android_app_set_argv(argv); - if (android_app->savedState != NULL) - { - // We are starting with a previous saved state; restore from it. - RARCH_LOG("Restoring reentrant savestate.\n"); - g_android.state = *(struct saved_state*)android_app->savedState; - g_extern.lifecycle_state = g_android.state.lifecycle_state; - } - - bool rarch_reentrant = (g_extern.lifecycle_state & (1ULL << RARCH_REENTRANT)); - - if (rarch_reentrant) - RARCH_LOG("Native Activity started (reentrant).\n"); - else - { - RARCH_LOG("Native Activity started.\n"); - rarch_main_clear_state(); - } + RARCH_LOG("Native Activity started.\n"); + rarch_main_clear_state(); g_extern.verbose = true; bool disp_refresh_read = refreshrate > 0.0f; - g_android.disp_refresh_rate = refresh_rate; - if (disp_refresh_read) { if (refreshrate < refresh_rate) @@ -422,27 +357,14 @@ static void* android_app_entry(void* param) RARCH_LOG("Setting RetroArch video refresh rate to: %.2fHz.\n", g_android.disp_refresh_rate); - while(!g_android.window_ready) + while (!g_android.window_ready) { - if(!android_run_events(android_app)) + if (!android_run_events(android_app)) goto exit; } - int init_ret; - - if (rarch_reentrant) - { - init_ret = 0; - - /* We've done everything state-wise needed for RARCH_REENTRANT, - * get rid of it now */ - g_extern.lifecycle_state &= ~(1ULL << RARCH_REENTRANT); - } - else if ((init_ret = rarch_main_init(argc, argv)) != 0) - { + if ((init_ret = rarch_main_init(argc, argv)) != 0) RARCH_LOG("Initialization failed.\n"); - g_extern.lifecycle_state |= (1ULL << RARCH_QUIT_KEY); - } else RARCH_LOG("Initializing succeeded.\n"); @@ -451,41 +373,38 @@ static void* android_app_entry(void* param) RARCH_LOG("RetroArch started.\n"); rarch_init_msg_queue(); driver_set_monitor_refresh_rate(g_android.disp_refresh_rate); - while((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? android_run_events(g_android.app) : rarch_main_iterate()); + + while ((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? + android_run_events(g_android.app) : + rarch_main_iterate()); + RARCH_LOG("RetroArch stopped.\n"); } exit: - if(g_extern.lifecycle_state & (1ULL << RARCH_QUIT_KEY)) - { - RARCH_LOG("Deinitializing RetroArch...\n"); + g_android.app->activityState = APP_CMD_DEAD; + RARCH_LOG("Deinitializing RetroArch...\n"); + + if (init_ret == 0) rarch_main_deinit(); - rarch_deinit_msg_queue(); + + rarch_deinit_msg_queue(); #ifdef PERF_TEST - rarch_perf_log(); + rarch_perf_log(); #endif - rarch_main_clear_state(); + rarch_main_clear_state(); - /* Quit RetroArch */ - RARCH_LOG("android_app_destroy!"); - free_saved_state(android_app); - pthread_mutex_lock(&android_app->mutex); + RARCH_LOG("android_app_destroy!"); + if (android_app->inputQueue != NULL) + AInputQueue_detachLooper(android_app->inputQueue); + AConfiguration_delete(android_app->config); - if (android_app->inputQueue != NULL) - AInputQueue_detachLooper(android_app->inputQueue); - - AConfiguration_delete(android_app->config); - android_app->destroyed = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - // Can't touch android_app object after this. - exit(0); - } - - return NULL; + // exit() here is nasty. + // pthread_exit(NULL) or return NULL; causes hanging ... + // Should probably called ANativeActivity_finsih(), but it's bugged, it will hang our app. + exit(init_ret); } - static inline void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) @@ -523,9 +442,12 @@ static void android_app_set_activity_state(struct android_app* android_app, int8 { pthread_mutex_lock(&android_app->mutex); android_app_write_cmd(android_app, cmd); - while (android_app->activityState != cmd) + while (android_app->activityState != cmd && android_app->activityState != APP_CMD_DEAD) pthread_cond_wait(&android_app->cond, &android_app->mutex); pthread_mutex_unlock(&android_app->mutex); + + if (android_app->activityState == APP_CMD_DEAD) + RARCH_LOG("RetroArch thread is dead.\n"); } static void onDestroy(ANativeActivity* activity) @@ -533,11 +455,10 @@ static void onDestroy(ANativeActivity* activity) RARCH_LOG("Destroy: %p\n", activity); struct android_app* android_app = (struct android_app*)activity->instance; - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, APP_CMD_DESTROY); - while (!android_app->destroyed) - pthread_cond_wait(&android_app->cond, &android_app->mutex); - pthread_mutex_unlock(&android_app->mutex); + RARCH_LOG("Joining with RetroArch thread.\n"); + pthread_join(android_app->thread, NULL); + android_app->thread = 0; + RARCH_LOG("Joined with RetroArch thread.\n"); close(android_app->msgread); close(android_app->msgwrite); @@ -560,27 +481,8 @@ static void onResume(ANativeActivity* activity) static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { - struct android_app* android_app = (struct android_app*)activity->instance; - void* savedState = NULL; - - RARCH_LOG("SaveInstanceState: %p\n", activity); - pthread_mutex_lock(&android_app->mutex); - android_app->stateSaved = 0; - android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); - while (!android_app->stateSaved) - pthread_cond_wait(&android_app->cond, &android_app->mutex); - - if (android_app->savedState != NULL) - { - savedState = android_app->savedState; - *outLen = android_app->savedStateSize; - android_app->savedState = NULL; - android_app->savedStateSize = 0; - } - - pthread_mutex_unlock(&android_app->mutex); - - return savedState; + *outLen = 0; + return NULL; } static void onPause(ANativeActivity* activity) @@ -618,8 +520,6 @@ static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* wind static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { RARCH_LOG("NativeWindowDestroyed: %p -- %p\n", activity, window); - - android_app_set_window((struct android_app*)activity->instance, NULL); } @@ -685,10 +585,7 @@ void ANativeActivity_onCreate(ANativeActivity* activity, android_app->msgread = msgpipe[0]; android_app->msgwrite = msgpipe[1]; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&android_app->thread, &attr, android_app_entry, android_app); + pthread_create(&android_app->thread, NULL, android_app_entry, android_app); // Wait for thread to start. pthread_mutex_lock(&android_app->mutex); diff --git a/driver.h b/driver.h index aa300c1ae3..c010394d42 100644 --- a/driver.h +++ b/driver.h @@ -109,9 +109,6 @@ enum // RetroArch specific bind IDs. RARCH_RMENU_TOGGLE, RARCH_RMENU_QUICKMENU_TOGGLE, #endif -#if defined(ANDROID) || defined(RARCH_CONSOLE) - RARCH_REENTRANT, -#endif RARCH_BIND_LIST_END, RARCH_BIND_LIST_END_NULL diff --git a/gfx/context/androidegl_ctx.c b/gfx/context/androidegl_ctx.c index baaf82cb80..1f9cafebf2 100644 --- a/gfx/context/androidegl_ctx.c +++ b/gfx/context/androidegl_ctx.c @@ -186,12 +186,7 @@ static void gfx_ctx_check_window(bool *quit, { int8_t cmd; - if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) - { - if(cmd == APP_CMD_SAVE_STATE) - free_saved_state(android_app); - } - else + if (read(android_app->msgread, &cmd, sizeof(cmd)) != sizeof(cmd)) cmd = -1; engine_handle_cmd(android_app, cmd);