From 68c0e69f0ae3e7a803e8ed2f292cd0a6e165ccb6 Mon Sep 17 00:00:00 2001 From: Sylvain Becker Date: Wed, 9 Jan 2019 22:41:52 +0100 Subject: [PATCH] Android: native_window validity is guaranteed between surfaceCreated and Destroyed It's currently still available after surfaceDestroyed(). And available (but invalid) between surfaceCreated() and surfaceChanged(). Which means ANativewindow_getWidth/Height/Format() fail in those cases. https://developer.android.com/reference/android/view/SurfaceHolder.html#getSurface() --- .../main/java/org/libsdl/app/SDLActivity.java | 2 ++ src/core/android/SDL_android.c | 33 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) 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 ac8515d01fc3d..09cafc55790b6 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 @@ -737,6 +737,7 @@ public static native void onNativeTouch(int touchDevId, int pointerFingerId, float y, float p); public static native void onNativeAccel(float x, float y, float z); public static native void onNativeClipboardChanged(); + public static native void onNativeSurfaceCreated(); public static native void onNativeSurfaceChanged(); public static native void onNativeSurfaceDestroyed(); public static native String nativeGetHint(String name); @@ -1574,6 +1575,7 @@ public Surface getNativeSurface() { @Override public void surfaceCreated(SurfaceHolder holder) { Log.v("SDL", "surfaceCreated()"); + SDLActivity.onNativeSurfaceCreated(); } // Called when we lose the surface diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 7de6b4b1ff81c..8613d45655d2c 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -83,6 +83,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( jint surfaceWidth, jint surfaceHeight, jint deviceWidth, jint deviceHeight, jint format, jfloat rate); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)( + JNIEnv *env, jclass jcls); + JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( JNIEnv *env, jclass jcls); @@ -661,8 +664,25 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( return Android_RemoveHaptic(device_id); } +/* Called from surfaceCreated() */ +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceCreated)(JNIEnv *env, jclass jcls) +{ + SDL_LockMutex(Android_ActivityMutex); + + if (Android_Window && Android_Window->driverdata) + { + SDL_WindowData *data = (SDL_WindowData *) Android_Window->driverdata; + + data->native_window = Android_JNI_GetNativeWindow(); + if (data->native_window == NULL) { + SDL_SetError("Could not fetch native window from UI thread"); + } + } + + SDL_UnlockMutex(Android_ActivityMutex); +} -/* Surface Created */ +/* Called from surfaceChanged() */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, jclass jcls) { SDL_LockMutex(Android_ActivityMutex); @@ -674,10 +694,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j /* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */ if (data->egl_surface == EGL_NO_SURFACE) { - if (data->native_window) { - ANativeWindow_release(data->native_window); - } - data->native_window = Android_JNI_GetNativeWindow(); data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window); } @@ -687,7 +703,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv *env, j SDL_UnlockMutex(Android_ActivityMutex); } -/* Surface Destroyed */ +/* Called from surfaceDestroyed() */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv *env, jclass jcls) { SDL_LockMutex(Android_ActivityMutex); @@ -708,6 +724,11 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv *env, data->egl_surface = EGL_NO_SURFACE; } + if (data->native_window) { + ANativeWindow_release(data->native_window); + } + data->native_window = NULL; + /* GL Context handling is done in the event loop because this function is run from the Java thread */ }