Android: fix wrong state after immediate sequence pause() / resume() / pause()
authorSylvain Becker <sylvain.becker@gmail.com>
Sat, 05 Jan 2019 22:27:25 +0100
changeset 12505b5f8e6c420c2
parent 12504 74e8ace1b2c3
child 12506 31512aa74164
Android: fix wrong state after immediate sequence pause() / resume() / pause()

It may happen to have the sequence pause()/resume()/pause(), before polling
any events.

Before, it ends in 'resumed' state because as the check is greedy.
Now, always increase the Pause semaphore, and stop at each pause.
It ends in 'paused' state.

Related to bug 3250: set up a reconfiguration of SurfaceView holder.
Turn the screen off manually before the app starts
(repro rate is not 100%..)
src/core/android/SDL_android.c
src/video/android/SDL_androidevents.c
     1.1 --- a/src/core/android/SDL_android.c	Fri Jan 04 22:09:38 2019 -0800
     1.2 +++ b/src/core/android/SDL_android.c	Sat Jan 05 22:27:25 2019 +0100
     1.3 @@ -820,8 +820,10 @@
     1.4          SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
     1.5  
     1.6          /* *After* sending the relevant events, signal the pause semaphore
     1.7 -         * so the event loop knows to pause and (optionally) block itself */
     1.8 -        if (!SDL_SemValue(Android_PauseSem)) SDL_SemPost(Android_PauseSem);
     1.9 +         * so the event loop knows to pause and (optionally) block itself.
    1.10 +         * Sometimes 2 pauses can be queued (eg pause/resume/pause), so it's
    1.11 +         * always increased. */
    1.12 +        SDL_SemPost(Android_PauseSem);
    1.13      }
    1.14  
    1.15      SDL_UnlockMutex(Android_ActivityMutex);
     2.1 --- a/src/video/android/SDL_androidevents.c	Fri Jan 04 22:09:38 2019 -0800
     2.2 +++ b/src/video/android/SDL_androidevents.c	Sat Jan 05 22:27:25 2019 +0100
     2.3 @@ -39,6 +39,13 @@
     2.4  static void ANDROIDAUDIO_PauseDevices(void) {}
     2.5  #endif
     2.6  
     2.7 +/* Number of event types in the event queue */
     2.8 +static int
     2.9 +SDL_NumberOfEvent(Uint32 type)
    2.10 +{
    2.11 +    return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type);
    2.12 +}
    2.13 +
    2.14  static void
    2.15  android_egl_context_restore(SDL_Window *window)
    2.16  {
    2.17 @@ -103,9 +110,10 @@
    2.18          }
    2.19      } else {
    2.20          if (isPausing || SDL_SemTryWait(Android_PauseSem) == 0) {
    2.21 -            /* We've been signaled to pause, but before we block ourselves,
    2.22 -            we need to make sure that the very last event have reached the app */
    2.23 -            if (SDL_HasEvent(SDL_APP_DIDENTERBACKGROUND)) {
    2.24 +            /* We've been signaled to pause (potentially several times), but before we block ourselves,
    2.25 +             * we need to make sure that the very last event (of the first pause sequence, if several)
    2.26 +             * has reached the app */
    2.27 +            if (SDL_NumberOfEvent(SDL_APP_DIDENTERBACKGROUND) > SDL_SemValue(Android_PauseSem)) {
    2.28                  isPausing = 1;
    2.29              }
    2.30              else {