Android SDL_APP_DIDENTERBACKGROUND gives no time for GL calls

Hey,

I’m using the SDL_APP_DIDENTERBACKGROUND event on iOS to save state (as
directed by comments in README-ios) when my app is sent to the background.
However, the same code won’t work right on Android.

Specifically, I’m saving the contents of a texture to disk. This requires
a GL call, but Android is ruining my GL context before I get a chance to do
anything about the event:
“SDL_APP_DIDENTERBACKGROUND
Saving state…
E/libEGL(8572): call to OpenGL ES API with no current context (logged once
per thread)
Saved in 0.053 seconds.
onWindowFocusChanged(): false
surfaceDestroyed()”

Saving on the SDL_APP_WILLENTERBACKGROUND event doesn’t appear to give any
additional time with the GL context.

Would it be possible to make SDL wait somewhere until the event is handled
(i.e. check if there’s an event filter installed and wait for that to
handle the event)? Do you think the GL context would still be valid at
that point? Is there another way?

Jonny D

Does disabling SDL_ANDROID_BLOCK_ON_PAUSE stop the context from being
destroyed? Docs imply it does. I haven’t gone there, myself.

Realistically even then, your GL calls are asynchronous and, by going into
the background while pulling pixel data, you are tempting driver bugs to
appear on various EGL driver implementations which may assume certain
things about the graphics state while backgrounded. Android EGL
implementations do not always do the right thing.

I would consider having a recent copy of the texture in the gameplay thread
before SDL_APP_DIDENTERBACKGROUND is ever called.On Mon, Nov 2, 2015 at 3:55 PM, Jonathan Dearborn wrote:

Hey,

I’m using the SDL_APP_DIDENTERBACKGROUND event on iOS to save state (as
directed by comments in README-ios) when my app is sent to the background.
However, the same code won’t work right on Android.

Specifically, I’m saving the contents of a texture to disk. This requires
a GL call, but Android is ruining my GL context before I get a chance to do
anything about the event:
“SDL_APP_DIDENTERBACKGROUND
Saving state…
E/libEGL(8572): call to OpenGL ES API with no current context (logged once
per thread)
Saved in 0.053 seconds.
onWindowFocusChanged(): false
surfaceDestroyed()”

Saving on the SDL_APP_WILLENTERBACKGROUND event doesn’t appear to give any
additional time with the GL context.

Would it be possible to make SDL wait somewhere until the event is handled
(i.e. check if there’s an event filter installed and wait for that to
handle the event)? Do you think the GL context would still be valid at
that point? Is there another way?

Jonny D


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

No, sadly SDL_ANDROID_BLOCK_ON_PAUSE=0 doesn’t affect it. It’s normal
behavior for Android to invalidate the context, even for Java apps; I just
don’t have the chance to react.

Jonny DOn Mon, Nov 2, 2015 at 8:21 PM, Michael Labbe wrote:

Does disabling SDL_ANDROID_BLOCK_ON_PAUSE stop the context from being
destroyed? Docs imply it does. I haven’t gone there, myself.

Realistically even then, your GL calls are asynchronous and, by going into
the background while pulling pixel data, you are tempting driver bugs to
appear on various EGL driver implementations which may assume certain
things about the graphics state while backgrounded. Android EGL
implementations do not always do the right thing.

I would consider having a recent copy of the texture in the gameplay
thread before SDL_APP_DIDENTERBACKGROUND is ever called.

On Mon, Nov 2, 2015 at 3:55 PM, Jonathan Dearborn <@Jonathan_Dearborn> wrote:

Hey,

I’m using the SDL_APP_DIDENTERBACKGROUND event on iOS to save state (as
directed by comments in README-ios) when my app is sent to the background.
However, the same code won’t work right on Android.

Specifically, I’m saving the contents of a texture to disk. This
requires a GL call, but Android is ruining my GL context before I get a
chance to do anything about the event:
“SDL_APP_DIDENTERBACKGROUND
Saving state…
E/libEGL(8572): call to OpenGL ES API with no current context (logged
once per thread)
Saved in 0.053 seconds.
onWindowFocusChanged(): false
surfaceDestroyed()”

Saving on the SDL_APP_WILLENTERBACKGROUND event doesn’t appear to give
any additional time with the GL context.

Would it be possible to make SDL wait somewhere until the event is
handled (i.e. check if there’s an event filter installed and wait for that
to handle the event)? Do you think the GL context would still be valid at
that point? Is there another way?

Jonny D


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Well, what I wanted to be done looks like it’s already done…
SDL_PushAppEvent() calls SDL_PushEvent(), which does immediately pass
execution through the event filter callback. This seems to mean that at no
point (in the native code, at least) does SDL get any chance to react
before the GL context is gone.

My only thought at this point is from arbitrary search results, because I’m
not very experienced in the Android API. Perhaps SDL’s SDLSurface class
could extend GLSurfaceView instead of SurfaceView and
call setPreserveEGLContextOnPause(true). Not sure if that would totally
mess up SDL’s native EGL handling and it’s hardware implementation
dependent.

Jonny DOn Mon, Nov 2, 2015 at 10:56 PM, Jonathan Dearborn <@Jonathan_Dearborn> wrote:

No, sadly SDL_ANDROID_BLOCK_ON_PAUSE=0 doesn’t affect it. It’s normal
behavior for Android to invalidate the context, even for Java apps; I just
don’t have the chance to react.

Jonny D

On Mon, Nov 2, 2015 at 8:21 PM, Michael Labbe wrote:

Does disabling SDL_ANDROID_BLOCK_ON_PAUSE stop the context from being
destroyed? Docs imply it does. I haven’t gone there, myself.

Realistically even then, your GL calls are asynchronous and, by going
into the background while pulling pixel data, you are tempting driver bugs
to appear on various EGL driver implementations which may assume certain
things about the graphics state while backgrounded. Android EGL
implementations do not always do the right thing.

I would consider having a recent copy of the texture in the gameplay
thread before SDL_APP_DIDENTERBACKGROUND is ever called.

On Mon, Nov 2, 2015 at 3:55 PM, Jonathan Dearborn <@Jonathan_Dearborn> wrote:

Hey,

I’m using the SDL_APP_DIDENTERBACKGROUND event on iOS to save state (as
directed by comments in README-ios) when my app is sent to the background.
However, the same code won’t work right on Android.

Specifically, I’m saving the contents of a texture to disk. This
requires a GL call, but Android is ruining my GL context before I get a
chance to do anything about the event:
“SDL_APP_DIDENTERBACKGROUND
Saving state…
E/libEGL(8572): call to OpenGL ES API with no current context (logged
once per thread)
Saved in 0.053 seconds.
onWindowFocusChanged(): false
surfaceDestroyed()”

Saving on the SDL_APP_WILLENTERBACKGROUND event doesn’t appear to give
any additional time with the GL context.

Would it be possible to make SDL wait somewhere until the event is
handled (i.e. check if there’s an event filter installed and wait for that
to handle the event)? Do you think the GL context would still be valid at
that point? Is there another way?

Jonny D


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Well, what I wanted to be done looks like it’s already done…
SDL_PushAppEvent() calls SDL_PushEvent(), which does immediately pass
execution through the event filter callback. This seems to mean that at no
point (in the native code, at least) does SDL get any chance to react
before the GL context is gone.

My only thought at this point is from arbitrary search results, because
I’m not very experienced in the Android API. Perhaps SDL’s SDLSurface
class could extend GLSurfaceView instead of SurfaceView and
call setPreserveEGLContextOnPause(true). Not sure if that would totally
mess up SDL’s native EGL handling and it’s hardware implementation
dependent.

Jonny D

For GLSurfaceView, if the context isn’t destroyed until you call onPause
then you can probably call into a native function to save your texture.

MyActivity {
onPause() { super.onPause(); saveTexture(); glSurfaceView.onPause(); }
}

With SDL I’m not really sure. You have the ability to create your own
Activity that derives from SDLActivity. Maybe something like the following
would work:

public class MyActivity extends SDLActivity {
onPause() { saveTexture(); super.onPause(); }
private void native saveTexture();
}

You’d implement saveTexture() in your native code using JNI. I think you
would need to surround the function with MakeCurrent(context…) and
MakeCurrent(NULL…) to set and release the context for the thread that
calls into saveTexture since I don’t think it will be the thread that does
the rendering.On Mon, Nov 2, 2015 at 11:23 PM, Jonathan Dearborn wrote: