Skip to content

Commit 7f7471e

Browse files
authored
Preserve the OpenGL context on Android when the app is paused (#18484)
1 parent 80bf5d8 commit 7f7471e

33 files changed

Lines changed: 444 additions & 37 deletions

gfx/common/egl_common.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,16 +688,38 @@ bool egl_create_surface(egl_ctx_data_t *egl, void *native_window)
688688
EGL_NONE,
689689
};
690690

691+
if (!egl_destroy_surface(egl))
692+
return false;
693+
691694
egl->surf = _egl_create_window_surface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs);
692695

693696
if (egl->surf == EGL_NO_SURFACE)
694697
return false;
695698

696699
/* Connect the context to the surface. */
697700
if (!_egl_make_current(egl->dpy, egl->surf, egl->surf, egl->ctx))
701+
{
702+
_egl_destroy_surface(egl->dpy, egl->surf);
703+
egl->surf = EGL_NO_SURFACE;
698704
return false;
705+
}
699706

700707
RARCH_LOG("[EGL] Current context: %p.\n", (void*)_egl_get_current_context());
701708

702709
return true;
703710
}
711+
712+
bool egl_destroy_surface(egl_ctx_data_t *egl)
713+
{
714+
if (egl->surf == EGL_NO_SURFACE)
715+
return true;
716+
717+
if (!_egl_make_current(egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
718+
return false;
719+
720+
if (!_egl_destroy_surface(egl->dpy, egl->surf))
721+
return false;
722+
723+
egl->surf = EGL_NO_SURFACE;
724+
return true;
725+
}

gfx/common/egl_common.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs);
118118

119119
bool egl_create_surface(egl_ctx_data_t *egl, void *native_window);
120120

121+
bool egl_destroy_surface(egl_ctx_data_t *egl);
122+
121123
bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value);
122124

123125
bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config,

gfx/drivers_context/android_ctx.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,27 @@ static uint32_t android_gfx_ctx_get_flags(void *data)
274274

275275
static void android_gfx_ctx_set_flags(void *data, uint32_t flags) { }
276276

277+
static bool android_gfx_ctx_create_surface(void *data)
278+
{
279+
#ifdef HAVE_EGL
280+
struct android_app *android_app = (struct android_app*)g_android;
281+
android_ctx_data_t *and = (android_ctx_data_t*)data;
282+
return egl_create_surface(&and->egl, android_app->window);
283+
#else
284+
return false;
285+
#endif
286+
}
287+
288+
static bool android_gfx_ctx_destroy_surface(void *data)
289+
{
290+
#ifdef HAVE_EGL
291+
android_ctx_data_t *and = (android_ctx_data_t*)data;
292+
return egl_destroy_surface(&and->egl);
293+
#else
294+
return false;
295+
#endif
296+
}
297+
277298
const gfx_ctx_driver_t gfx_ctx_android = {
278299
android_gfx_ctx_init,
279300
android_gfx_ctx_destroy,
@@ -309,5 +330,7 @@ const gfx_ctx_driver_t gfx_ctx_android = {
309330
android_gfx_ctx_set_flags,
310331
android_gfx_ctx_bind_hw_render,
311332
NULL,
312-
NULL
333+
NULL,
334+
android_gfx_ctx_create_surface,
335+
android_gfx_ctx_destroy_surface
313336
};

gfx/drivers_context/android_vk_ctx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,5 +280,7 @@ const gfx_ctx_driver_t gfx_ctx_vk_android = {
280280
android_gfx_ctx_vk_set_flags,
281281
android_gfx_ctx_vk_bind_hw_render,
282282
android_gfx_ctx_vk_get_context_data,
283-
NULL /* make_current */
283+
NULL, /* make_current */
284+
NULL, /* create_surface */
285+
NULL /* destroy_surface */
284286
};

gfx/drivers_context/cocoa_gl_ctx.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,5 +636,7 @@ static void cocoa_gl_gfx_ctx_get_video_output_size(void *data,
636636
cocoa_gl_gfx_ctx_set_flags,
637637
cocoa_gl_gfx_ctx_bind_hw_render,
638638
NULL, /* get_context_data */
639-
NULL /* make_current */
639+
NULL, /* make_current */
640+
NULL, /* create_surface */
641+
NULL /* destroy_surface */
640642
};

gfx/drivers_context/cocoa_vk_ctx.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,5 +438,7 @@ static void cocoa_vk_gfx_ctx_get_video_output_size(void *data,
438438
cocoa_vk_gfx_ctx_set_flags,
439439
cocoa_vk_gfx_ctx_bind_hw_render,
440440
cocoa_vk_gfx_ctx_get_context_data,
441-
NULL /* make_current */
441+
NULL, /* make_current */
442+
NULL, /* create_surface */
443+
NULL /* destroy_surface */
442444
};

gfx/drivers_context/drm_ctx.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,26 @@ static void gfx_ctx_drm_set_flags(void *data, uint32_t flags)
10651065
drm->core_hw_context_enable = true;
10661066
}
10671067

1068+
static bool gfx_ctx_drm_create_surface(void *data)
1069+
{
1070+
#ifdef HAVE_EGL
1071+
gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data;
1072+
return egl_create_surface(&drm->egl, (EGLNativeWindowType)drm->gbm_surface);
1073+
#else
1074+
return false;
1075+
#endif
1076+
}
1077+
1078+
static bool gfx_ctx_drm_destroy_surface(void *data)
1079+
{
1080+
#ifdef HAVE_EGL
1081+
gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data;
1082+
return egl_destroy_surface(&drm->egl);
1083+
#else
1084+
return false;
1085+
#endif
1086+
}
1087+
10681088
const gfx_ctx_driver_t gfx_ctx_drm = {
10691089
gfx_ctx_drm_init,
10701090
gfx_ctx_drm_destroy,
@@ -1100,5 +1120,7 @@ const gfx_ctx_driver_t gfx_ctx_drm = {
11001120
gfx_ctx_drm_set_flags,
11011121
gfx_ctx_drm_bind_hw_render,
11021122
NULL,
1103-
NULL
1123+
NULL,
1124+
gfx_ctx_drm_create_surface,
1125+
gfx_ctx_drm_destroy_surface
11041126
};

gfx/drivers_context/drm_go2_ctx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,5 +424,7 @@ const gfx_ctx_driver_t gfx_ctx_go2_drm = {
424424
gfx_ctx_go2_drm_set_flags,
425425
gfx_ctx_go2_drm_bind_hw_render,
426426
NULL,
427-
NULL
427+
NULL,
428+
NULL, /* create_surface */
429+
NULL /* destroy_surface */
428430
};

gfx/drivers_context/emscriptenegl_ctx.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,26 @@ static uint32_t gfx_ctx_emscripten_get_flags(void *data)
245245

246246
static void gfx_ctx_emscripten_set_flags(void *data, uint32_t flags) { }
247247

248+
static bool gfx_ctx_emscripten_create_surface(void *data)
249+
{
250+
#ifdef HAVE_EGL
251+
emscripten_ctx_data_t *emscripten = (emscripten_ctx_data_t*)data;
252+
return egl_create_surface(&emscripten->egl, 0);
253+
#else
254+
return false;
255+
#endif
256+
}
257+
258+
static bool gfx_ctx_emscripten_destroy_surface(void *data)
259+
{
260+
#ifdef HAVE_EGL
261+
emscripten_ctx_data_t *emscripten = (emscripten_ctx_data_t*)data;
262+
return egl_destroy_surface(&emscripten->egl);
263+
#else
264+
return false;
265+
#endif
266+
}
267+
248268
const gfx_ctx_driver_t gfx_ctx_emscripten = {
249269
gfx_ctx_emscripten_init,
250270
gfx_ctx_emscripten_destroy,
@@ -280,5 +300,7 @@ const gfx_ctx_driver_t gfx_ctx_emscripten = {
280300
gfx_ctx_emscripten_set_flags,
281301
gfx_ctx_emscripten_bind_hw_render,
282302
NULL, /* get_context_data */
283-
NULL /* make_current */
303+
NULL, /* make_current */
304+
gfx_ctx_emscripten_create_surface,
305+
gfx_ctx_emscripten_destroy_surface
284306
};

gfx/drivers_context/emscriptenwebgl_ctx.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,5 +248,7 @@ const gfx_ctx_driver_t gfx_ctx_emscripten_webgl = {
248248
gfx_ctx_emscripten_webgl_set_flags,
249249
gfx_ctx_emscripten_webgl_bind_hw_render,
250250
NULL, /* get_context_data */
251-
NULL /* make_current */
251+
NULL, /* make_current */
252+
NULL, /* create_surface */
253+
NULL /* destroy_surface */
252254
};

0 commit comments

Comments
 (0)