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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index b0a2be3..918df7b 100644
--- a/src/core/android/SDL_android.c
+++ b/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,
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index b345b05..480d57c 100644
--- a/src/core/android/SDL_android.h
+++ b/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
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index abdca68..5b0c1bf 100644
--- a/src/render/SDL_render.c
+++ b/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
diff --git a/src/video/android/SDL_androidgl.c b/src/video/android/SDL_androidgl.c
index d71cd9b..4dd982b 100644
--- a/src/video/android/SDL_androidgl.c
+++ b/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
diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c
index 96a94e1..64eff52 100644
--- a/src/video/android/SDL_androidwindow.c
+++ b/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");