Android: create Pause/ResumeSem semaphore at higher level than CreateWindow() - If you call onPause() before CreateWindow(), SDLThread will run in infinite loop in background. - If you call onPause() between a DestroyWindow() and a new CreateWindow(), semaphores are invalids. SDLActivity.java: the first resume() starts the SDLThread, don't call nativeResume() as it would post ResumeSem. And the first pause would automatically be resumed.
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/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index 2806029..7e4f363 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -505,10 +505,14 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
mSDLThread = new Thread(new SDLMain(), "SDLThread");
mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
mSDLThread.start();
+
+ // No nativeResume(), don't signal Android_ResumeSem
+ mSurface.handleResume();
+ } else {
+ nativeResume();
+ mSurface.handleResume();
}
- nativeResume();
- mSurface.handleResume();
mCurrentNativeState = mNextNativeState;
}
}
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index b7e1947..c6795f0 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -439,6 +439,17 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
__android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_ActivityMutex mutex");
}
+
+ Android_PauseSem = SDL_CreateSemaphore(0);
+ if (Android_PauseSem == NULL) {
+ __android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_PauseSem semaphore");
+ }
+
+ Android_ResumeSem = SDL_CreateSemaphore(0);
+ if (Android_ResumeSem == NULL) {
+ __android_log_print(ANDROID_LOG_ERROR, "SDL", "failed to create Android_ResumeSem semaphore");
+ }
+
mActivityClass = (jclass)((*env)->NewGlobalRef(env, cls));
midGetNativeSurface = (*env)->GetStaticMethodID(env, mActivityClass,
@@ -961,6 +972,16 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
Android_ActivityMutex = NULL;
}
+ if (Android_PauseSem) {
+ SDL_DestroySemaphore(Android_PauseSem);
+ Android_PauseSem = NULL;
+ }
+
+ if (Android_ResumeSem) {
+ SDL_DestroySemaphore(Android_ResumeSem);
+ Android_ResumeSem = NULL;
+ }
+
str = SDL_GetError();
if (str && str[0]) {
__android_log_print(ANDROID_LOG_ERROR, "SDL", "SDLActivity thread ends (error=%s)", str);
@@ -982,14 +1003,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)(
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
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.
- * Sometimes 2 pauses can be queued (eg pause/resume/pause), so it's
- * always increased. */
- SDL_SemPost(Android_PauseSem);
}
+ /* *After* sending the relevant events, signal the pause semaphore
+ * 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);
}
@@ -1006,13 +1027,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)(
SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0);
- /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context
- * We can't restore the GL Context here because it needs to be done on the SDL main thread
- * and this function will be called from the Java thread instead.
- */
- SDL_SemPost(Android_ResumeSem);
}
+ /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context
+ * We can't restore the GL Context here because it needs to be done on the SDL main thread
+ * and this function will be called from the Java thread instead.
+ */
+ SDL_SemPost(Android_ResumeSem);
+
SDL_UnlockMutex(Android_ActivityMutex);
}
diff --git a/src/video/android/SDL_androidwindow.c b/src/video/android/SDL_androidwindow.c
index 638eef3..5e34c28 100644
--- a/src/video/android/SDL_androidwindow.c
+++ b/src/video/android/SDL_androidwindow.c
@@ -49,9 +49,6 @@ Android_CreateWindow(_THIS, SDL_Window * window)
goto endfunction;
}
- Android_PauseSem = SDL_CreateSemaphore(0);
- Android_ResumeSem = SDL_CreateSemaphore(0);
-
/* Set orientation */
Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
@@ -171,10 +168,6 @@ Android_DestroyWindow(_THIS, SDL_Window *window)
if (window == Android_Window) {
Android_Window = NULL;
- if (Android_PauseSem) SDL_DestroySemaphore(Android_PauseSem);
- if (Android_ResumeSem) SDL_DestroySemaphore(Android_ResumeSem);
- Android_PauseSem = NULL;
- Android_ResumeSem = NULL;
if (window->driverdata) {
SDL_WindowData *data = (SDL_WindowData *) window->driverdata;