SDLThread is a Java Thread, it's not needed to call 'Detach' from the JVM.
Clear mThreadKey, so that the pthread_create destructor is not called for this
thread.
SDLActivity thread priority is unchanged, by default -10 (THREAD_PRIORITY_VIDEO).
SDLAudio thread priority was -4 (SDL_SetThreadPriority was ignored) and is now -16 (THREAD_PRIORITY_AUDIO).
SDLThread thread priority was 0 (THREAD_PRIORITY_DEFAULT) and is -4 (THREAD_PRIORITY_DISPLAY).
Can be check by adding in build.grable:
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}
}
SDLActivity.java:1691: warning: [deprecation] A_8 in PixelFormat has been deprecated
case PixelFormat.A_8:
SDLActivity.java:1694: warning: [deprecation] LA_88 in PixelFormat has been deprecated
SDLActivity.java:1697: warning: [deprecation] L_8 in PixelFormat has been deprecated
SDLActivity.java:1700: warning: [deprecation] RGBA_4444 in PixelFormat has been deprecated
SDLActivity.java:1704: warning: [deprecation] RGBA_5551 in PixelFormat has been deprecated
SDLActivity.java:1716: warning: [deprecation] RGB_332 in PixelFormat has been deprecated
- destroy Android_ActivityMutex
- display any SDL error message that may have occured in this thread,
since SDL_GetError() is thread specific, and user has no access to it.
In the usual case, first call to onNativeOrientationChanged() is done before
SDL has been initialised and would just set an error message
"Video subsystem has not been initialized" without sending the event.
First error could happen if Android_SetWindowFullscreen somehow gets
called between SurfaceDestroyed() and SurfaceCreated()
Second error should not happen has native_window validity is guaranteed.
(It would happens previously with error -19)
It accesses data->native_window, which can be changed by onNativeSurfacedChanged().
Currently, Android_SetWindowFullscreen() may access data->native_window after it
has been released, and before a new reference is acquired.
(can be reproduced by adding some SDL_Delay() in onNativeSurfacedChanged and
Android_SetWindowFullscreen() ).
Default launch mode (standard) allows multiple instances of the SDLActivity.
( https://developer.android.com/guide/topics/manifest/activity-element#lmode )
Not sure this is intended in SDL as this doesn't work. There are static
variables in Java, in C code which make this impossible (allow one android_window) and
also Audio print errors.
There is also some code added in onDestroy as if it would be able to
re-initialize: https://hg.libsdl.org/SDL/rev/27686adb08c3
Bug Android activity life-cycle seems to show there is not transition to get out
of onDestroy()
https://developer.android.com/reference/android/app/Activity#ActivityLifecycle
( can be tested with "adb shell am start my.package.org/.MainActivity"
and "adb shell am start -n my.package.org/.MainActivity" )
Send me a message if there are real use-case for this !
Make sure there is not pending Pause accumulated, so the the application doesn't
remain paused and stucked in onDestroy().
Can be tested by adding:
SDLActivity.nativePause();
SDLActivity.nativePause();
mSingleton.finish();
Doesn't seem to happen manually, but symetrical to the pause handling.
Can be tested by adding:
mNextNativeState = SDLActivity.NativeState.PAUSED;
handleNativeState();
mNextNativeState = SDLActivity.NativeState.RESUMED;
handleNativeState();
mNextNativeState = SDLActivity.NativeState.PAUSED;
handleNativeState();
mNextNativeState = SDLActivity.NativeState.RESUMED;
handleNativeState();
Before, it ends in 'paused' state.
Now, it ends in 'resumed' state.
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%..)
"Pause" transition will add events:
SDL_WINDOWEVENT_ENTER
SDL_WINDOWEVENT_FOCUS_LOST
SDL_WINDOWEVENT_MINIMIZED
SDL_APP_WILL ENTER BACKGROUND
SDL_APP_DID ENTER BACKGROUND
"Resume" transition will add events:
SDL_APP_WILL ENTER FOREGROUND
SDL_APP_DID ENTER FOREGROUND
SDL_WINDOWEVENT_FOCUS_GAINED
SDL_WINDOWEVENT_RESTORED
If Android application doesn't empty the event loop in between, it enters in
"paused" state when SDL_WINDOWEVENT_RESTORED is fetched.
See bug 3250 for pratical case.
Occurs when application goes to background:
- Java activity is destroying SurfaceView holder and "egl_surface" (in onNativeSurfaceDestroyed())
- While native thread is in Android_GLES_SwapWindow(), prepared to call SDL_EGL_SwapBuffers()
The error is "call to eglSwapBuffers failed, reporting an error of EGL_BAD_SURFACE"
It an be reproduced easily by adding a SDL_Delay(100) at the begining of SDL_EGL_SwapBuffers(),
and putting the application into background.
Use a semaphore to prevent concurrency issues between Java Activity and Native thread code, when using 'Android_Window'.
(Eg. Java sending Touch events, while native code is destroying the main SDL_Window. )
This is the best option for macOS and iOS, the only platforms with Metal.
Pre-Metal versions of these platforms will fall back to OpenGL (ES), as
appropriate.
Huge thanks to Alexander Szpakowski, who worked incredibly hard to get the
Metal renderer to such a high-quality state!
Not only does this fix macOS 10.14 ("Mojave")'s broken NSOpenGLCPSwapInterval
support, it also lets us implement "adaptive vsync" on macOS!
CVDisplayLink is supported back to macOS 10.4 ("Tiger"), so we just use it
universally without version checks and dump NSOpenGLCPSwapInterval, Mojave or
not.
Switching between renderers "software -> opengl -> opengles2 -> software" fails.
"opengl -> opengles2" calls SDL_RecreateWindow() and frees "window->surface"
without marking it as "surface_invalid".