From 35722b64232301fefc87548f26acc544fc45941e Mon Sep 17 00:00:00 2001 From: Sylvain Becker Date: Sat, 5 Jan 2019 22:27:25 +0100 Subject: [PATCH] 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 | 6 ++++-- src/video/android/SDL_androidevents.c | 14 +++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index ed1879608179a..ad305229bb550 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -820,8 +820,10 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)( SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); /* *After* sending the relevant events, signal the pause semaphore - * so the event loop knows to pause and (optionally) block itself */ - if (!SDL_SemValue(Android_PauseSem)) SDL_SemPost(Android_PauseSem); + * so the event loop knows to pause and (optionally) block itself. + * Sometimes 2 pauses can be queued (eg pause/resume/pause), so it's + * always increased. */ + SDL_SemPost(Android_PauseSem); } SDL_UnlockMutex(Android_ActivityMutex); diff --git a/src/video/android/SDL_androidevents.c b/src/video/android/SDL_androidevents.c index ac23741442a11..a0367ca2d70a2 100644 --- a/src/video/android/SDL_androidevents.c +++ b/src/video/android/SDL_androidevents.c @@ -39,6 +39,13 @@ static void ANDROIDAUDIO_ResumeDevices(void) {} static void ANDROIDAUDIO_PauseDevices(void) {} #endif +/* Number of event types in the event queue */ +static int +SDL_NumberOfEvent(Uint32 type) +{ + return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type); +} + static void android_egl_context_restore(SDL_Window *window) { @@ -103,9 +110,10 @@ Android_PumpEvents(_THIS) } } else { if (isPausing || SDL_SemTryWait(Android_PauseSem) == 0) { - /* We've been signaled to pause, but before we block ourselves, - we need to make sure that the very last event have reached the app */ - if (SDL_HasEvent(SDL_APP_DIDENTERBACKGROUND)) { + /* We've been signaled to pause (potentially several times), but before we block ourselves, + * we need to make sure that the very last event (of the first pause sequence, if several) + * has reached the app */ + if (SDL_NumberOfEvent(SDL_APP_DIDENTERBACKGROUND) > SDL_SemValue(Android_PauseSem)) { isPausing = 1; } else {