SDL: fixed multithreaded video rendering crashing
This commit is contained in:
@@ -138,5 +138,4 @@ class Globals
|
||||
public static boolean MultiThreadedVideo = false;
|
||||
|
||||
public static boolean OuyaEmulation = false; // For debugging
|
||||
public static boolean RedirectStdout = false; // For debugging
|
||||
}
|
||||
|
||||
@@ -714,7 +714,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
nativeInit( Globals.DataDir,
|
||||
Globals.CommandLine,
|
||||
( (Globals.SwVideoMode && Globals.MultiThreadedVideo) || Globals.CompatibilityHacksVideo ) ? 1 : 0,
|
||||
Globals.RedirectStdout ? 1 : 0 );
|
||||
0 );
|
||||
System.exit(0); // The main() returns here - I don't bother with deinit stuff, just terminate process
|
||||
}
|
||||
|
||||
@@ -958,7 +958,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
|
||||
}
|
||||
|
||||
private native void nativeInitJavaCallbacks();
|
||||
private native void nativeInit(String CurrentPath, String CommandLine, int multiThreadedVideo, int isDebuggerConnected);
|
||||
private native void nativeInit(String CurrentPath, String CommandLine, int multiThreadedVideo, int unused);
|
||||
private native void nativeResize(int w, int h, int keepAspectRatio);
|
||||
private native void nativeDone();
|
||||
private native void nativeGlContextLost();
|
||||
|
||||
@@ -79,7 +79,10 @@ extern DECLSPEC int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int x, int y);
|
||||
extern DECLSPEC int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void);
|
||||
|
||||
|
||||
/** Exports for Java environment and Video object instance */
|
||||
/** Exports for Java environment and Video object instance.
|
||||
To get JNIEnv pointer, use following code:
|
||||
JNIEnv *env = NULL;
|
||||
(*SDL_ANDROID_JavaVM())->GetEnv(SDL_ANDROID_JavaVM(), &env, JNI_VERSION_1_6); */
|
||||
extern DECLSPEC JavaVM* SDL_ANDROID_JavaVM();
|
||||
|
||||
/*
|
||||
|
||||
@@ -410,7 +410,7 @@ JNIEXPORT jint JNICALL JAVA_EXPORT_NAME(AudioThread_nativeAudioInitJavaCallbacks
|
||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
jniVM = vm;
|
||||
return JNI_VERSION_1_2;
|
||||
return JNI_VERSION_1_6;
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
|
||||
|
||||
@@ -1383,7 +1383,7 @@ int ANDROID_VideoInitMT(_THIS, SDL_PixelFormat *vformat)
|
||||
|
||||
SDL_Surface *ANDROID_SetVideoModeMT(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags)
|
||||
{
|
||||
if( flags & SDL_OPENGL || flags & SDL_HWSURFACE )
|
||||
if( flags & SDL_OPENGL || (flags & SDL_HWSURFACE && !SDL_ANDROID_VideoForceSoftwareMode) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -66,7 +66,6 @@ SDL_Rect SDL_ANDROID_ForceClearScreenRect[4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
|
||||
int SDL_ANDROID_ForceClearScreenRectAmount = 0;
|
||||
|
||||
// Extremely wicked JNI environment to call Java functions from C code
|
||||
static JNIEnv* JavaEnv = NULL;
|
||||
static jclass JavaRendererClass = NULL;
|
||||
static jobject JavaRenderer = NULL;
|
||||
static jmethodID JavaSwapBuffers = NULL;
|
||||
@@ -114,14 +113,23 @@ static void appRestoredCallbackDefault(void)
|
||||
SDL_ANDROID_ResumeAudioPlayback();
|
||||
}
|
||||
|
||||
|
||||
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackgroundCallback = appPutToBackgroundCallbackDefault;
|
||||
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestoredCallback = appRestoredCallbackDefault;
|
||||
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALPutToBackgroundCallback = NULL;
|
||||
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALRestoredCallback = NULL;
|
||||
|
||||
static inline JNIEnv *GetJavaEnv(void)
|
||||
{
|
||||
JavaVM *vm = SDL_ANDROID_JavaVM();
|
||||
JNIEnv *ret = NULL;
|
||||
(*vm)->GetEnv(vm, &ret, JNI_VERSION_1_6);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDL_ANDROID_CallJavaSwapBuffers()
|
||||
{
|
||||
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
if( !glContextLost )
|
||||
{
|
||||
// Clear part of screen not used by SDL - on Android the screen contains garbage after each frame
|
||||
@@ -236,12 +244,14 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextRecreated) ( JNIEnv* env, jobject
|
||||
|
||||
int SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput(void)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleScreenKeyboardWithoutTextInput );
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SDL_ANDROID_ToggleInternalScreenKeyboard(SDL_InternalKeyboard_t keyboard)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleInternalScreenKeyboard, (jint)keyboard );
|
||||
return 1;
|
||||
}
|
||||
@@ -254,6 +264,8 @@ extern SDL_Surface *SDL_GetVideoSurface(void);
|
||||
|
||||
void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf, int outBufLen)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
|
||||
// Clear mouse button state, to avoid repeated clicks on the text field in some apps
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT );
|
||||
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT );
|
||||
@@ -302,6 +314,7 @@ void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf,
|
||||
|
||||
void SDL_ANDROID_CallJavaHideScreenKeyboard()
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaHideScreenKeyboard );
|
||||
}
|
||||
|
||||
@@ -318,6 +331,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeScreenKeyboardShown) ( JNIEnv* env, jo
|
||||
|
||||
void SDL_ANDROID_CallJavaSetScreenKeyboardHintMessage(const char *hint)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->PushLocalFrame(JavaEnv, 1);
|
||||
jstring s = hint ? (*JavaEnv)->NewStringUTF(JavaEnv, hint) : NULL;
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetScreenKeyboardHintMessage, s );
|
||||
@@ -328,13 +342,14 @@ void SDL_ANDROID_CallJavaSetScreenKeyboardHintMessage(const char *hint)
|
||||
|
||||
void SDL_ANDROID_CallJavaStartAccelerometerGyroscope(int start)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaStartAccelerometerGyroscope, (jint) start );
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject thiz )
|
||||
{
|
||||
JavaEnv = env;
|
||||
JNIEnv *JavaEnv = env;
|
||||
JavaRenderer = (*JavaEnv)->NewGlobalRef( JavaEnv, thiz );
|
||||
|
||||
JavaRendererClass = (*JavaEnv)->GetObjectClass(JavaEnv, thiz);
|
||||
@@ -433,6 +448,7 @@ void SDLCALL SDL_ANDROID_GetClipboardText(char * buf, int len)
|
||||
|
||||
int SDLCALL SDL_SetClipboardText(const char *text)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->PushLocalFrame(JavaEnv, 1);
|
||||
jstring s = (*JavaEnv)->NewStringUTF(JavaEnv, text);
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetClipboardText, s );
|
||||
@@ -444,6 +460,7 @@ int SDLCALL SDL_SetClipboardText(const char *text)
|
||||
char * SDLCALL SDL_GetClipboardText(void)
|
||||
{
|
||||
char *buf = NULL;
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->PushLocalFrame( JavaEnv, 1 );
|
||||
jstring s = (jstring) (*JavaEnv)->CallObjectMethod( JavaEnv, JavaRenderer, JavaGetClipboardText );
|
||||
if( s )
|
||||
@@ -489,6 +506,7 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeClipboardChanged) ( JNIEnv* env, jobject thi
|
||||
int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position)
|
||||
{
|
||||
jint arr[5];
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->PushLocalFrame( JavaEnv, 1 );
|
||||
jintArray elemArr = (*JavaEnv)->NewIntArray(JavaEnv, 5);
|
||||
if (elemArr == NULL)
|
||||
@@ -511,16 +529,19 @@ int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * positio
|
||||
}
|
||||
int SDLCALL SDL_ANDROID_SetAdvertisementVisible(int visible)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementVisible, (jint)visible );
|
||||
return 1;
|
||||
}
|
||||
int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int left, int top)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementPosition, (jint)left, (jint)top );
|
||||
return 1;
|
||||
}
|
||||
int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestNewAdvertisement );
|
||||
return 1;
|
||||
}
|
||||
@@ -528,6 +549,7 @@ int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void)
|
||||
int SDLCALL SDL_ANDROID_CloudSave(const char *filename, const char *saveId, const char *dialogTitle,
|
||||
const char *description, const char *screenshotFile, uint64_t playedTimeMs)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_CloudSave: played time %llu", playedTimeMs);
|
||||
if( !filename )
|
||||
return 0;
|
||||
@@ -557,6 +579,7 @@ int SDLCALL SDL_ANDROID_CloudSave(const char *filename, const char *saveId, cons
|
||||
|
||||
int SDLCALL SDL_ANDROID_CloudLoad(const char *filename, const char *saveId, const char *dialogTitle)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
if( !filename )
|
||||
return 0;
|
||||
if( !saveId )
|
||||
@@ -577,6 +600,7 @@ int SDLCALL SDL_ANDROID_CloudLoad(const char *filename, const char *saveId, cons
|
||||
|
||||
void SDLCALL SDL_ANDROID_OpenExternalApp(const char *package, const char *activity, const char *data)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->PushLocalFrame(JavaEnv, 3);
|
||||
jstring s1 = package ? (*JavaEnv)->NewStringUTF(JavaEnv, package) : (*JavaEnv)->NewStringUTF(JavaEnv, "");
|
||||
jstring s2 = activity ? (*JavaEnv)->NewStringUTF(JavaEnv, activity) : (*JavaEnv)->NewStringUTF(JavaEnv, "");
|
||||
@@ -590,6 +614,7 @@ void SDLCALL SDL_ANDROID_OpenExternalApp(const char *package, const char *activi
|
||||
|
||||
void SDLCALL SDL_ANDROID_RestartMyself(const char *restartParams)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->PushLocalFrame(JavaEnv, 1);
|
||||
jstring s1 = restartParams ? (*JavaEnv)->NewStringUTF(JavaEnv, restartParams) : (*JavaEnv)->NewStringUTF(JavaEnv, "");
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestRestartMyself, s1 );
|
||||
@@ -599,6 +624,7 @@ void SDLCALL SDL_ANDROID_RestartMyself(const char *restartParams)
|
||||
|
||||
void SDLCALL SDL_ANDROID_SetConfigOption(int option, int value)
|
||||
{
|
||||
JNIEnv *JavaEnv = GetJavaEnv();
|
||||
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestSetConfigOption, (jint)option, (jint)value );
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls);
|
||||
// Library init
|
||||
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
return JNI_VERSION_1_4;
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
// Start up the SDL app
|
||||
|
||||
@@ -44,26 +44,17 @@ jobject SDL_ANDROID_JniVideoObject()
|
||||
return static_thiz;
|
||||
}
|
||||
|
||||
void redirectStdout()
|
||||
{
|
||||
freopen( "stdout.log", "w", stdout );
|
||||
dup2( fileno(stdout), fileno(stderr) );
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST(1,3,0)
|
||||
#else
|
||||
extern void SDL_ANDROID_MultiThreadedVideoLoopInit();
|
||||
extern void SDL_ANDROID_MultiThreadedVideoLoop();
|
||||
|
||||
static int threadedMain(void * waitForDebugger);
|
||||
static int threadedMain(void * unused);
|
||||
|
||||
int threadedMain(void * waitForDebugger)
|
||||
int threadedMain(void * unused)
|
||||
{
|
||||
if( waitForDebugger )
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "We are being debugged - waiting for debugger for 7 seconds");
|
||||
//usleep(7000000);
|
||||
}
|
||||
static JNIEnv *JavaEnv = NULL;
|
||||
(*SDL_ANDROID_JavaVM())->AttachCurrentThread(SDL_ANDROID_JavaVM(), &JavaEnv, NULL);
|
||||
SDL_main( argc, argv );
|
||||
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Application closed, calling exit(0)");
|
||||
exit(0);
|
||||
@@ -71,7 +62,7 @@ int threadedMain(void * waitForDebugger)
|
||||
#endif
|
||||
|
||||
extern C_LINKAGE void
|
||||
JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz, jstring jcurdir, jstring cmdline, jint multiThreadedVideo, jint waitForDebugger )
|
||||
JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz, jstring jcurdir, jstring cmdline, jint multiThreadedVideo, jint unused )
|
||||
{
|
||||
int i = 0;
|
||||
char curdir[PATH_MAX] = "";
|
||||
@@ -93,9 +84,6 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz, jstring
|
||||
setenv("HOME", curdir, 1);
|
||||
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Changing curdir to \"%s\"", curdir);
|
||||
|
||||
if( waitForDebugger )
|
||||
redirectStdout();
|
||||
|
||||
jstr = (*env)->GetStringUTFChars(env, cmdline, NULL);
|
||||
|
||||
if (jstr != NULL && strlen(jstr) > 0)
|
||||
@@ -147,17 +135,12 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz, jstring
|
||||
#else
|
||||
if( ! multiThreadedVideo )
|
||||
{
|
||||
if( waitForDebugger )
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "We are being debugged - waiting for debugger for 7 seconds");
|
||||
//usleep(7000000);
|
||||
}
|
||||
SDL_main( argc, argv );
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_ANDROID_MultiThreadedVideoLoopInit();
|
||||
SDL_CreateThread(threadedMain, (void *)waitForDebugger);
|
||||
SDL_CreateThread(threadedMain, NULL);
|
||||
SDL_ANDROID_MultiThreadedVideoLoop();
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user