From d23c2f07e3c994b99e4646ce3c1cad413a1a5a74 Mon Sep 17 00:00:00 2001 From: Sylvain Becker Date: Thu, 10 Jan 2019 18:05:56 +0100 Subject: [PATCH] Fixed bug 3930 - Android, set thread priorities and names 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). --- .../main/java/org/libsdl/app/SDLActivity.java | 13 +++++++++++ .../java/org/libsdl/app/SDLAudioManager.java | 23 +++++++++++++++++-- src/audio/SDL_audio.c | 16 +++++++++++++ src/core/android/SDL_android.c | 11 ++++++++- src/core/android/SDL_android.h | 1 + 5 files changed, 61 insertions(+), 3 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 44cee5a9d65ff..d88cde9e7594e 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 @@ -193,6 +193,12 @@ protected void onCreate(Bundle savedInstanceState) { Log.v(TAG, "onCreate()"); super.onCreate(savedInstanceState); + try { + Thread.currentThread().setName("SDLActivity"); + } catch (Exception e) { + Log.v(TAG, "modify thread properties failed " + e.toString()); + } + // Load shared libraries String errorMsgBrokenLib = ""; try { @@ -1494,7 +1500,14 @@ public void run() { String function = SDLActivity.mSingleton.getMainFunction(); String[] arguments = SDLActivity.mSingleton.getArguments(); + try { + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY); + } catch (Exception e) { + Log.v("SDL", "modify thread properties failed " + e.toString()); + } + Log.v("SDL", "Running main function " + function + " from library " + library); + SDLActivity.nativeRunMain(library, function, arguments); Log.v("SDL", "Finished main function"); diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java b/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java index bed0eb5c3c77c..0714419c2925a 100644 --- a/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java +++ b/android-project/app/src/main/java/org/libsdl/app/SDLAudioManager.java @@ -73,7 +73,7 @@ protected static int[] open(boolean isCapture, int sampleRate, int audioFormat, sampleSize = 2; break; } - + if (isCapture) { switch (desiredChannels) { case 1: @@ -298,7 +298,7 @@ public static void audioWriteByteBuffer(byte[] buffer) { Log.e(TAG, "Attempted to make audio call with uninitialized audio!"); return; } - + for (int i = 0; i < buffer.length; ) { int result = mAudioTrack.write(buffer, i, buffer.length - i); if (result > 0) { @@ -364,5 +364,24 @@ public static void captureClose() { } } + /** This method is called by SDL using JNI. */ + public static void audioSetThreadPriority(boolean iscapture, int device_id) { + try { + + /* Set thread name */ + if (iscapture) { + Thread.currentThread().setName("SDLAudioC" + device_id); + } else { + Thread.currentThread().setName("SDLAudioP" + device_id); + } + + /* Set thread priority */ + android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); + + } catch (Exception e) { + Log.v(TAG, "modify thread properties failed " + e.toString()); + } + } + public static native int nativeSetupJNI(); } diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index d8218fe56541d..0343052a1998e 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -695,8 +695,16 @@ SDL_RunAudio(void *devicep) SDL_assert(!device->iscapture); +#if SDL_AUDIO_DRIVER_ANDROID + { + /* Set thread priority to THREAD_PRIORITY_AUDIO */ + extern void Android_JNI_AudioSetThreadPriority(int, int); + Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); + } +#else /* The audio mixing is always a high priority thread */ SDL_SetThreadPriority(SDL_THREAD_PRIORITY_TIME_CRITICAL); +#endif /* Perform any thread setup */ device->threadid = SDL_ThreadID(); @@ -792,8 +800,16 @@ SDL_CaptureAudio(void *devicep) SDL_assert(device->iscapture); +#if SDL_AUDIO_DRIVER_ANDROID + { + /* Set thread priority to THREAD_PRIORITY_AUDIO */ + extern void Android_JNI_AudioSetThreadPriority(int, int); + Android_JNI_AudioSetThreadPriority(device->iscapture, device->id); + } +#else /* The audio mixing is always a high priority thread */ SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); +#endif /* Perform any thread setup */ device->threadid = SDL_ThreadID(); diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 0a51f037b49d8..0afaa76a7bd25 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -268,6 +268,7 @@ static jmethodID midCaptureReadByteBuffer; static jmethodID midCaptureReadShortBuffer; static jmethodID midCaptureReadFloatBuffer; static jmethodID midCaptureClose; +static jmethodID midAudioSetThreadPriority; /* controller manager */ static jclass mControllerManagerClass; @@ -442,9 +443,11 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *mEnv, jc "captureReadFloatBuffer", "([FZ)I"); midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "captureClose", "()V"); + midAudioSetThreadPriority = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioSetThreadPriority", "(ZI)V"); if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose || - !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) { + !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); } @@ -1467,6 +1470,12 @@ void Android_JNI_CloseAudioDevice(const int iscapture) } } +void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id) +{ + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioSetThreadPriority, iscapture, device_id); +} + /* Test for an exception and call SDL_SetError with its detail if one occurs */ /* If the parameter silent is truthy then SDL_SetError() will not be called. */ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h index ea35f59028794..f8830cce8a14b 100644 --- a/src/core/android/SDL_android.h +++ b/src/core/android/SDL_android.h @@ -55,6 +55,7 @@ extern void Android_JNI_WriteAudioBuffer(void); extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); extern void Android_JNI_FlushCapturedAudio(void); extern void Android_JNI_CloseAudioDevice(const int iscapture); +extern void Android_JNI_AudioSetThreadPriority(int iscapture, int device_id); /* Detecting device type */ extern SDL_bool Android_IsDeXMode();