Ok, while trying to reduce the code down to a test case, I think I figured out why the message was not getting through. It appears that the SDL_SetEventFilter callback is called first and I was returning 0 thus filtering it out. If I instead return 1 from the filter callback, the message show up in the SDL_AddEventWatch callback subsequently.
Code:
int EventWatch(void*, SDL_Event* event)
{
if (event->type == SDL_APP_WILLENTERBACKGROUND)
{
__android_log_print(ANDROID_LOG_INFO, “MyLog”, “EventWatch() received SDL_APP_WILLENTERBACKGROUND”);
}
return 0;
}
int EventFilter(void *, SDL_Event * event)
{
if (event->type == SDL_APP_WILLENTERBACKGROUND)
{
__android_log_print(ANDROID_LOG_INFO, “MyLog”, “EventFilter() received SDL_APP_WILLENTERBACKGROUND”);
}
return 0;
}
void main()
{
__android_log_print(ANDROID_LOG_INFO, “MyLog”, “test() begin”);
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
auto window = SDL_CreateWindow(“test”,
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
1920, 1080,
SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
SDL_AddEventWatch(EventWatch, nullptr);
SDL_SetEventFilter(EventFilter, nullptr);
while (true)
{
SDL_GL_SwapWindow(window);
}
}
yields:
V/SDL (23047): onResume()
V/SDL (23047): surfaceCreated()
V/SDL (23047): surfaceChanged()
V/SDL (23047): pixel format RGB_565
V/SDL (23047): Window size:1794x1080
I/SDL (23047): SDL_Android_Init()
I/SDL (23047): SDL_Android_Init() finished!
I/MyLog (23047): test() begin
I/MyLog (23047): RenderThread() begin
V/SDL (23047): onWindowFocusChanged(): true
E/Prism.WidgetManager( 1158): The same lists. No need to update. skip it.
V/SDL (23047): onPause()
V/SDL (23047): nativePause()
I/MyLog (23047): EventFilter() received SDL_APP_WILLENTERBACKGROUND
V/SDL (23047): surfaceDestroyed()
V/SDL (23047): onWindowFocusChanged(): false
But if I change the return value of EventFilter to 1, I get this:
V/SDL (23216): onResume()
V/SDL (23216): surfaceCreated()
V/SDL (23216): surfaceChanged()
V/SDL (23216): pixel format RGB_565
V/SDL (23216): Window size:1794x1080
I/SDL (23216): SDL_Android_Init()
I/SDL (23216): SDL_Android_Init() finished!
I/MyLog (23216): test() begin
I/MyLog (23216): RenderThread() begin
V/SDL (23216): onWindowFocusChanged(): true
V/SDL (23216): onPause()
V/SDL (23216): nativePause()
I/MyLog (23216): EventFilter() received SDL_APP_WILLENTERBACKGROUND
I/MyLog (23216): EventWatch() received SDL_APP_WILLENTERBACKGROUND
V/SDL (23216): onWindowFocusChanged(): false
V/SDL (23216): surfaceDestroyed()
Note that the above test case doesn’t generate the EGL error or crash. It also makes no difference whether SDL_ANDROID_BLOCK_ON_PAUSE is defined or not, nor whether I run the render loop in a separate thread. However, in my actual app which has multiple threads kept busy for much of the time, the EGL warning is printed before EventFilter ever receives the SDL_APP_WILLENTERBACKGROUND. I can avoid crashing straight away by avoiding rendering, but after SDL_APP_DIDENTERFOREGROUND, the follow call to SDL_GL_SwapWindow results in the GL error state being set.
Here’s the log. (Lines marked crag_log are output from my app):
V/SDL (31907): onResume()
V/SDL (31907): surfaceCreated()
V/SDL (31907): surfaceChanged()
V/SDL (31907): pixel format RGB_565
V/SDL (31907): Window size:1794x1080
I/SDL (31907): SDL_Android_Init()
I/SDL (31907): SDL_Android_Init() finished!
W/crag_log(31907): Crag Demo; Copyright 2010-2013 John McFarlane
W/crag_log(31907): jni/src/…/…/…/src/main.cpp(329):-> CragMain [] main
E/crag_log(31907): Failed to open config file, crag.cfg.
E/crag_log(31907): Failed to open config file, crag.cfg.
W/crag_log(31907): ni/src/…/…/…/src/core/app.cpp( 80):Creating window 1794,1080 [] main
W/crag_log(31907): c/…/…/…/src/smp/scheduler.cpp(495):scheduler using 0 threads. [] main
V/SDL (31907): onWindowFocusChanged(): true
W/crag_log(31907): /src/…/…/…/src/gfx/Engine.cpp(660):Unknown refresh rate; using default_refresh_rate of 50Hz [] render
W/crag_log(31907): …/src/scripts/MonitorOrigin.cpp( 83):Set: -0.276132,9999400.000000,-5.128622 [] sim
V/SDL (31907): onPause()
E/libEGL (31907): call to OpenGL ES API with no current context (logged once per thread)
V/SDL (31907): nativePause()
W/crag_log(31907): jni/src/…/…/…/src/main.cpp(292):SDL_APP_WILLENTERBACKGROUND []
V/SDL (31907): onWindowFocusChanged(): false
V/SDL (31907): surfaceDestroyed()
V/SDL (31907): onResume()
V/SDL (31907): surfaceCreated()
V/SDL (31907): surfaceChanged()
V/SDL (31907): pixel format RGB_565
V/SDL (31907): Window size:1794x1080
V/SDL (31907): onWindowFocusChanged(): true
V/SDL (31907): nativeResume()
W/crag_log(31907): jni/src/…/…/…/src/main.cpp(296):SDL_APP_DIDENTERFOREGROUND []
E/BufferQueue( 237): [SurfaceView] dequeueBuffer: BufferQueue is abandon
W/crag_log(31907): /src/…/…/…/src/gfx/Engine.cpp(902):GL error 505 (GL error) [] render
F/crag (31907): internal error
F/libc (31907): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 31928 (SDLThread)
Note that GL error 0x505 is GL_OUT_OF_MEMORY.
So I’m guessing that some graphical resource or other requires re-initialization on resume and will investigate that. However, any further guidance would be appreciated.