Browse Source

Android: concurrency issues, make sure Activity is in running State when calling
functions like SDL_CreateWindow, SDL_CreateRenderer, Android_GLES_CreateContext

Bugs 4694, 4681, 4142

Sylvain Becker 5 years ago
parent
commit
22a2decf64

+ 20 - 0
src/core/android/SDL_android.c

@@ -24,6 +24,7 @@
 #include "SDL_hints.h"
 #include "SDL_log.h"
 #include "SDL_main.h"
+#include "SDL_timer.h"
 
 #ifdef __ANDROID__
 
@@ -720,6 +721,25 @@ void Android_ActivityMutex_Unlock() {
     SDL_UnlockMutex(Android_ActivityMutex);
 }
 
+/* Lock the Mutex when the Activity is in its 'Running' state */
+void Android_ActivityMutex_Lock_Running() {
+    int pauseSignaled = 0;
+    int resumeSignaled = 0;
+
+retry:
+
+    SDL_LockMutex(Android_ActivityMutex);
+
+    pauseSignaled = SDL_SemValue(Android_PauseSem);
+    resumeSignaled = SDL_SemValue(Android_ResumeSem);
+
+    if (pauseSignaled > resumeSignaled) {
+        SDL_UnlockMutex(Android_ActivityMutex);
+        SDL_Delay(50);
+        goto retry;
+    }
+}
+
 /* Set screen resolution */
 JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetScreenResolution)(
                                     JNIEnv *env, jclass jcls,

+ 1 - 0
src/core/android/SDL_android.h

@@ -133,6 +133,7 @@ SDL_bool SDL_IsDeXMode(void);
 
 void Android_ActivityMutex_Lock(void);
 void Android_ActivityMutex_Unlock(void);
+void Android_ActivityMutex_Lock_Running(void);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus

+ 14 - 0
src/render/SDL_render.c

@@ -29,6 +29,9 @@
 #include "SDL_sysrender.h"
 #include "software/SDL_render_sw_c.h"
 
+#if defined(__ANDROID__)
+#  include "../core/android/SDL_android.h"
+#endif
 
 #define SDL_WINDOWRENDERDATA    "_SDL_WindowRenderData"
 
@@ -837,6 +840,10 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
     SDL_bool batching = SDL_TRUE;
     const char *hint;
 
+#if defined(__ANDROID__)
+    Android_ActivityMutex_Lock_Running();
+#endif
+
     if (!window) {
         SDL_SetError("Invalid window");
         goto error;
@@ -951,9 +958,16 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
     SDL_LogInfo(SDL_LOG_CATEGORY_RENDER,
                 "Created renderer: %s", renderer->info.name);
 
+#if defined(__ANDROID__)
+    Android_ActivityMutex_Unlock();
+#endif
     return renderer;
 
 error:
+
+#if defined(__ANDROID__)
+    Android_ActivityMutex_Unlock();
+#endif
     return NULL;
 
 #else

+ 9 - 1
src/video/android/SDL_androidgl.c

@@ -49,7 +49,15 @@ Android_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 SDL_GLContext
 Android_GLES_CreateContext(_THIS, SDL_Window * window)
 {
-    return SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+    SDL_GLContext ret;
+
+    Android_ActivityMutex_Lock_Running();
+
+    ret = SDL_EGL_CreateContext(_this, ((SDL_WindowData *) window->driverdata)->egl_surface);
+
+    SDL_UnlockMutex(Android_ActivityMutex);
+
+    return ret;
 }
 
 int

+ 1 - 1
src/video/android/SDL_androidwindow.c

@@ -42,7 +42,7 @@ Android_CreateWindow(_THIS, SDL_Window * window)
     SDL_WindowData *data;
     int retval = 0;
 
-    SDL_LockMutex(Android_ActivityMutex);
+    Android_ActivityMutex_Lock_Running();
 
     if (Android_Window) {
         retval = SDL_SetError("Android only supports one window");