(Android) Teardown more or less works correctly now - have to do

exit() at the end because of the way dynamic libraries stay in
memory and can't be purged - so static variables retain their
state (ie. previous values from the previous session) - see

https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/XDO-Rar3ptY
http://comments.gmane.org/gmane.comp.handhelds.android.ndk/11500
This commit is contained in:
twinaphex 2012-10-21 19:56:36 +02:00
parent 702f99b80e
commit 3342bd4ec6
2 changed files with 79 additions and 79 deletions

View File

@ -36,21 +36,37 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
switch (cmd)
{
case APP_CMD_SAVE_STATE:
RARCH_LOG("engine_handle_cmd: APP_CMD_SAVE_STATE.\n");
// The system has asked us to save our current state. Do so.
g_android.app->savedState = malloc(sizeof(struct saved_state));
*((struct saved_state*)g_android.app->savedState) = g_android.state;
g_android.app->savedStateSize = sizeof(struct saved_state);
break;
case APP_CMD_INIT_WINDOW:
RARCH_LOG("engine_handle_cmd: APP_CMD_INIT_WINDOW.\n");
// The window is being shown, get it ready.
if (g_android.app->window != NULL)
g_android.window_inited = true;
break;
case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
case APP_CMD_START:
RARCH_LOG("engine_handle_cmd: APP_CMD_START.\n");
break;
case APP_CMD_RESUME:
RARCH_LOG("engine_handle_cmd: APP_CMD_RESUME.\n");
break;
case APP_CMD_STOP:
RARCH_LOG("engine_handle_cmd: APP_CMD_STOP.\n");
break;
case APP_CMD_PAUSE:
RARCH_LOG("engine_handle_cmd: APP_CMD_PAUSE.\n");
g_android.init_quit = true;
break;
case APP_CMD_TERM_WINDOW:
RARCH_LOG("engine_handle_cmd: APP_CMD_TERM_WINDOW.\n");
// The window is being hidden or closed, clean it up.
break;
case APP_CMD_GAINED_FOCUS:
RARCH_LOG("engine_handle_cmd: APP_CMD_GAINED_FOCUS.\n");
// When our app gains focus, we start monitoring the accelerometer.
#if 0
if (g_android.accelerometerSensor != NULL)
@ -65,6 +81,7 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd)
#endif
break;
case APP_CMD_LOST_FOCUS:
RARCH_LOG("engine_handle_cmd: APP_CMD_LOST_FOCUS.\n");
// When our app loses focus, we stop monitoring the accelerometer.
// This is to avoid consuming battery while not being used.
if (!g_android.window_inited)
@ -202,4 +219,5 @@ void android_main(struct android_app* state)
RARCH_LOG("Start RetroArch...\n");
rarch_main(argc, argv);
exit(0);
}

View File

@ -41,28 +41,31 @@ static float gfx_ctx_get_aspect_ratio(void)
static void gfx_ctx_set_swap_interval(unsigned interval)
{
RARCH_LOG("gfx_ctx_set_swap_interval(%d).\n", interval);
eglSwapInterval(g_egl_dpy, interval);
}
static void gfx_ctx_destroy(void)
{
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(g_egl_dpy, g_egl_ctx);
eglDestroySurface(g_egl_dpy, g_egl_surf);
eglTerminate(g_egl_dpy);
g_egl_dpy = EGL_NO_DISPLAY;
g_egl_surf = EGL_NO_SURFACE;
g_egl_ctx = EGL_NO_CONTEXT;
g_config = 0;
RARCH_LOG("gfx_ctx_destroy().\n");
eglMakeCurrent(g_egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(g_egl_dpy, g_egl_ctx);
eglDestroySurface(g_egl_dpy, g_egl_surf);
eglTerminate(g_egl_dpy);
g_android.width = 0;
g_android.height = 0;
g_android.animating = 0;
g_egl_dpy = EGL_NO_DISPLAY;
g_egl_surf = EGL_NO_SURFACE;
g_egl_ctx = EGL_NO_CONTEXT;
g_config = 0;
g_android.width = 0;
g_android.height = 0;
g_android.animating = 0;
}
static bool gfx_ctx_init(void)
{
RARCH_LOG("gfx_ctx_init().\n");
const EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
@ -70,80 +73,60 @@ static bool gfx_ctx_init(void)
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_NONE
};
EGLConfig config;
EGLint numConfigs;
EGLint format;
EGLint width;
EGLint height;
GLfloat ratio;
};
EGLConfig config;
EGLint num_config;
EGLint egl_version_major, egl_version_minor;
EGLint format;
EGLint width;
EGLint height;
GLfloat ratio;
EGLint context_attributes[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
RARCH_LOG("Initializing context\n");
RARCH_LOG("Initializing context\n");
if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) {
RARCH_ERR("eglGetDisplay() returned error %d.\n", eglGetError());
return false;
}
if ((g_egl_dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
goto error;
EGLint egl_major, egl_minor;
if (!eglInitialize(g_egl_dpy, &egl_major, &egl_minor)) {
RARCH_ERR("eglInitialize() returned error %d.\n", eglGetError());
return false;
}
if (!eglInitialize(g_egl_dpy, &egl_version_major, &egl_version_minor))
goto error;
RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_major, egl_minor);
RARCH_LOG("[ANDROID/EGL]: EGL version: %d.%d\n", egl_version_major, egl_version_minor);
EGLint num_configs;
if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &numConfigs)) {
RARCH_ERR("eglChooseConfig() returned error %d.\n", eglGetError());
gfx_ctx_destroy();
return false;
}
if (!eglChooseConfig(g_egl_dpy, attribs, &g_config, 1, &num_config))
goto error;
if (!eglGetConfigAttrib(g_egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format)) {
RARCH_ERR("eglGetConfigAttrib() returned error %d.\n", eglGetError());
gfx_ctx_destroy();
return false;
}
if (!eglGetConfigAttrib(g_egl_dpy, config, EGL_NATIVE_VISUAL_ID, &format))
goto error;
ANativeWindow_setBuffersGeometry(g_android.app->window, 0, 0, format);
ANativeWindow_setBuffersGeometry(g_android.app->window, 0, 0, format);
if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, config, g_android.app->window, 0))) {
RARCH_ERR("eglCreateWindowSurface() returned error %d.\n", eglGetError());
gfx_ctx_destroy();
return false;
}
if (!(g_egl_surf = eglCreateWindowSurface(g_egl_dpy, config, g_android.app->window, 0)))
goto error;
EGLint ctx_attribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
if (!(g_egl_ctx = eglCreateContext(g_egl_dpy, config, 0, ctx_attribs))) {
RARCH_ERR("eglCreateContext() returned error %d.\n", eglGetError());
gfx_ctx_destroy();
return false;
}
if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx)) {
RARCH_ERR("eglMakeCurrent() returned error %d.\n", eglGetError());
gfx_ctx_destroy();
return false;
}
if (!(g_egl_ctx = eglCreateContext(g_egl_dpy, config, 0, context_attributes)))
goto error;
if (!eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width) ||
!eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height)) {
RARCH_ERR("eglQuerySurface() returned error %d.\n", eglGetError());
gfx_ctx_destroy();
return false;
}
if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx))
goto error;
g_android.width = width;
g_android.height = height;
g_android.state.angle = 0;
if (!eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &width) ||
!eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &height))
goto error;
return true;
g_android.width = width;
g_android.height = height;
g_android.state.angle = 0;
return true;
error:
gfx_ctx_destroy();
return false;
}
static void gfx_ctx_swap_buffers(void)
@ -248,8 +231,7 @@ static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
if (g_egl_dpy)
{
EGLint gl_width;
EGLint gl_height;
EGLint gl_width, gl_height;
eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &gl_width);
eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &gl_height);
*width = gl_width;