Comments on Android issue

Hi,

I’ve talked before about this issue here before, although it got no
attention:
http://bugzilla.libsdl.org/show_bug.cgi?id=1425

I’ve been trying to find the source of the bug. The problem is, as I
understand it, this:
Some devices, at least those I’ve tried this in (HTC Wildfire android 2.2
and Samsung Tablet Galaxy 10.1 android:3.2) seem to cause this problem when
you call an OpenGLES function when there is no current EGL window. That
happens if the SDL thread (or OpenGLES thread for that matter) keeps
working when your app has been signaled to pause (onPause method is
called). And that happens because of how the SDL model is tied to the
Android model. Android uses a GUI thread + OpenGLES thread approach (2
threads), but SDL uses and event loop approach (1 thread). When the GUI
thread in Android is asked to pause via the Activity’s onPause(), it
immediately should stop the OpenGLES thread, but it doesn’t. Instead, it
places an event in SDL’s event loop that is read in the next loop run.
However, prior to that reading, we might (and probaly will) call more
OpenGLES functions. There are 3 options:

  • Use NativeActivity, which is built on the event model and fits better the
    SDL model
  • Use GLSurfaceView, which forces us to let Android control the graphic
    loop (not SDL’s way, making it incompatible with SDL cross-platform
    intentions).
  • Re-work the Activity, using a thread manager and signaling
    wait/notify/interrupt to avoid any GL call once the app has been paused,
    and properly re-create the surface when resumed if necessary. I still have
    to figure out exactly how it should be done, but I think is possible.
    Actually, this is how GLSurfaceView is implemented.

Any ideas/proposals?

Best regards

Hi,

what about using the same approach as for ios? Some sort of push events
via SDL_SetEventFilter.

See the discussions in “How to make SDL 2.0, iOS work together. (Game
Center too)” for more information.

MartinAm 28.05.2012 11:34, schrieb ?lvaro Castro-Castilla:

Hi,

I’ve talked before about this issue here before, although it got no
attention:
http://bugzilla.libsdl.org/show_bug.cgi?id=1425

I’ve been trying to find the source of the bug. The problem is, as I
understand it, this:
Some devices, at least those I’ve tried this in (HTC Wildfire android
2.2 and Samsung Tablet Galaxy 10.1 android:3.2) seem to cause this
problem when you call an OpenGLES function when there is no current
EGL window. That happens if the SDL thread (or OpenGLES thread for
that matter) keeps working when your app has been signaled to pause
(onPause method is called). And that happens because of how the SDL
model is tied to the Android model. Android uses a GUI thread +
OpenGLES thread approach (2 threads), but SDL uses and event loop
approach (1 thread). When the GUI thread in Android is asked to pause
via the Activity’s onPause(), it immediately should stop the OpenGLES
thread, but it doesn’t. Instead, it places an event in SDL’s event
loop that is read in the next loop run. However, prior to that
reading, we might (and probaly will) call more OpenGLES functions.
There are 3 options:

  • Use NativeActivity, which is built on the event model and fits
    better the SDL model
  • Use GLSurfaceView, which forces us to let Android control the
    graphic loop (not SDL’s way, making it incompatible with SDL
    cross-platform intentions).
  • Re-work the Activity, using a thread manager and signaling
    wait/notify/interrupt to avoid any GL call once the app has been
    paused, and properly re-create the surface when resumed if necessary.
    I still have to figure out exactly how it should be done, but I think
    is possible. Actually, this is how GLSurfaceView is implemented.

Any ideas/proposals?

Best regards

Currently is done via pushing events, but openglES calls are usually done
before the event queue is read, leading to this issue. Unless you check the
event queue after each openglES call…
I’d go for the NativeActivity route, actually. The only problem would be
that it could target only 2.3+, but that’s over 80% of the market and
growing.On Mon, May 28, 2012 at 12:04 PM, Martin Gerhardy <martin.gerhardy at gmail.com wrote:

Am 28.05.2012 11:34, schrieb ?lvaro Castro-Castilla:

Hi,

I’ve talked before about this issue here before, although it got no
attention:
http://bugzilla.libsdl.org/**show_bug.cgi?id=1425http://bugzilla.libsdl.org/show_bug.cgi?id=1425

I’ve been trying to find the source of the bug. The problem is, as I
understand it, this:
Some devices, at least those I’ve tried this in (HTC Wildfire android 2.2
and Samsung Tablet Galaxy 10.1 android:3.2) seem to cause this problem when
you call an OpenGLES function when there is no current EGL window. That
happens if the SDL thread (or OpenGLES thread for that matter) keeps
working when your app has been signaled to pause (onPause method is
called). And that happens because of how the SDL model is tied to the
Android model. Android uses a GUI thread + OpenGLES thread approach (2
threads), but SDL uses and event loop approach (1 thread). When the GUI
thread in Android is asked to pause via the Activity’s onPause(), it
immediately should stop the OpenGLES thread, but it doesn’t. Instead, it
places an event in SDL’s event loop that is read in the next loop run.
However, prior to that reading, we might (and probaly will) call more
OpenGLES functions. There are 3 options:

  • Use NativeActivity, which is built on the event model and fits better
    the SDL model
  • Use GLSurfaceView, which forces us to let Android control the graphic
    loop (not SDL’s way, making it incompatible with SDL cross-platform
    intentions).
  • Re-work the Activity, using a thread manager and signaling
    wait/notify/interrupt to avoid any GL call once the app has been paused,
    and properly re-create the surface when resumed if necessary. I still have
    to figure out exactly how it should be done, but I think is possible.
    Actually, this is how GLSurfaceView is implemented.

Any ideas/proposals?

Best regards

Hi,

what about using the same approach as for ios? Some sort of push events
via SDL_SetEventFilter.

See the discussions in “How to make SDL 2.0, iOS work together. (Game
Center too)” for more information.

Martin
_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

that’s the point - with the event filter you can handle the event at the
time android triggers it - without passing it to the queue. and it looks
like the ios port is using it, too (sooner or later). so instead of
reinventing the wheel it should be used for android, too (imo)

regards
martinAm 28.05.2012 13:14, schrieb ?lvaro Castro-Castilla:

Currently is done via pushing events, but openglES calls are usually
done before the event queue is read, leading to this issue. Unless you
check the event queue after each openglES call…
I’d go for the NativeActivity route, actually. The only problem would
be that it could target only 2.3+, but that’s over 80% of the market
and growing.

That would be nice, but how is it exactly working in iOS? Because we have
the same problem as using directly the Java Activities methods, since the
event filters are executed in a different thread than the graphic loop.

From http://wiki.libsdl.org/moin.cgi/SDL_SetEventFilter

[image: /!] Be very careful of what you do in the event filter function,
as it may run in a different thread!On Mon, May 28, 2012 at 1:19 PM, Martin Gerhardy <martin.gerhardy at gmail.com>wrote:

Am 28.05.2012 13:14, schrieb ?lvaro Castro-Castilla:

Currently is done via pushing events, but openglES calls are usually done

before the event queue is read, leading to this issue. Unless you check the
event queue after each openglES call…
I’d go for the NativeActivity route, actually. The only problem would be
that it could target only 2.3+, but that’s over 80% of the market and
growing.

that’s the point - with the event filter you can handle the event at the
time android triggers it - without passing it to the queue. and it looks
like the ios port is using it, too (sooner or later). so instead of
reinventing the wheel it should be used for android, too (imo)

regards

martin
_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2012/5/28 Martin Gerhardy <martin.gerhardy at gmail.com>> Am 28.05.2012 11:34, schrieb ?lvaro Castro-Castilla:

Hi,

I’ve talked before about this issue here before, although it got no
attention:
http://bugzilla.libsdl.org/**show_bug.cgi?id=1425http://bugzilla.libsdl.org/show_bug.cgi?id=1425

I’ve been trying to find the source of the bug. The problem is, as I
understand it, this:
Some devices, at least those I’ve tried this in (HTC Wildfire android 2.2
and Samsung Tablet Galaxy 10.1 android:3.2) seem to cause this problem when
you call an OpenGLES function when there is no current EGL window. That
happens if the SDL thread (or OpenGLES thread for that matter) keeps
working when your app has been signaled to pause (onPause method is
called). And that happens because of how the SDL model is tied to the
Android model. Android uses a GUI thread + OpenGLES thread approach (2
threads), but SDL uses and event loop approach (1 thread). When the GUI
thread in Android is asked to pause via the Activity’s onPause(), it
immediately should stop the OpenGLES thread, but it doesn’t. Instead, it
places an event in SDL’s event loop that is read in the next loop run.
However, prior to that reading, we might (and probaly will) call more
OpenGLES functions. There are 3 options:

  • Use NativeActivity, which is built on the event model and fits better
    the SDL model
  • Use GLSurfaceView, which forces us to let Android control the graphic
    loop (not SDL’s way, making it incompatible with SDL cross-platform
    intentions).
  • Re-work the Activity, using a thread manager and signaling
    wait/notify/interrupt to avoid any GL call once the app has been paused,
    and properly re-create the surface when resumed if necessary. I still have
    to figure out exactly how it should be done, but I think is possible.
    Actually, this is how GLSurfaceView is implemented.

Any ideas/proposals?

Best regards

Hi,

what about using the same approach as for ios? Some sort of push events
via SDL_SetEventFilter.

See the discussions in “How to make SDL 2.0, iOS work together. (Game
Center too)” for more information.

Martin

I think Android is more forgiving than iOS, at least in the devices I’ve
experimented with, so there’s no need for callbacks…I’ve submitted a
small patch to http://bugzilla.libsdl.org/show_bug.cgi?id=1425 and it seems
that and a call to SDL_GL_CreateContext in response to
SDL_WINDOWEVENT_RESTORED is all that’s required to properly support
Pause/Resume on Android > 3.0. On older versions of Android, or Android
devices whose chipset does not support multiple GL contexts, or situations
where the available contexts are exhausted, the app should still restore
all its textures (or as I say in my comment for the patch, we could try to
do some magic storing/restoring of textures in Java, I’m not sure if it’s
possible). What’s needed is an additional message
(like SDL_WINDOWEVENT_RESTORED/SDL_WINDOWEVENT_HIDDEN) to signal that the
app should reload it’s textures when the context can not be restored and
has to be recreated.
My rationale for doing an automagic storing/restoring of textures (if
possible at all) is that Android seems to be the only platform that suffers
from this problem, and it would be nice to have some consistency in this
regard.


Gabriel.