mirror of
https://github.com/libretro/RetroArch
synced 2025-02-19 12:41:00 +00:00
Refactor out save stating and reentrancy.
It's not really needed.
This commit is contained in:
parent
45fa3d7ba7
commit
8a58858d84
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
3
driver.h
3
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
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user