SDL: fixed multithreaded video rendering crashing

This commit is contained in:
pelya
2016-08-14 23:51:11 +03:00
parent b4cbc0aa75
commit fe7c6be644
8 changed files with 44 additions and 33 deletions

View File

@@ -138,5 +138,4 @@ class Globals
public static boolean MultiThreadedVideo = false; public static boolean MultiThreadedVideo = false;
public static boolean OuyaEmulation = false; // For debugging public static boolean OuyaEmulation = false; // For debugging
public static boolean RedirectStdout = false; // For debugging
} }

View File

@@ -714,7 +714,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer
nativeInit( Globals.DataDir, nativeInit( Globals.DataDir,
Globals.CommandLine, Globals.CommandLine,
( (Globals.SwVideoMode && Globals.MultiThreadedVideo) || Globals.CompatibilityHacksVideo ) ? 1 : 0, ( (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 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 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 nativeResize(int w, int h, int keepAspectRatio);
private native void nativeDone(); private native void nativeDone();
private native void nativeGlContextLost(); private native void nativeGlContextLost();

View File

@@ -79,7 +79,10 @@ extern DECLSPEC int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int x, int y);
extern DECLSPEC int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void); 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(); extern DECLSPEC JavaVM* SDL_ANDROID_JavaVM();
/* /*

View File

@@ -410,7 +410,7 @@ JNIEXPORT jint JNICALL JAVA_EXPORT_NAME(AudioThread_nativeAudioInitJavaCallbacks
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{ {
jniVM = vm; jniVM = vm;
return JNI_VERSION_1_2; return JNI_VERSION_1_6;
}; };
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)

View File

@@ -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) 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; return NULL;
} }

View File

@@ -66,7 +66,6 @@ SDL_Rect SDL_ANDROID_ForceClearScreenRect[4] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 },
int SDL_ANDROID_ForceClearScreenRectAmount = 0; int SDL_ANDROID_ForceClearScreenRectAmount = 0;
// Extremely wicked JNI environment to call Java functions from C code // Extremely wicked JNI environment to call Java functions from C code
static JNIEnv* JavaEnv = NULL;
static jclass JavaRendererClass = NULL; static jclass JavaRendererClass = NULL;
static jobject JavaRenderer = NULL; static jobject JavaRenderer = NULL;
static jmethodID JavaSwapBuffers = NULL; static jmethodID JavaSwapBuffers = NULL;
@@ -114,14 +113,23 @@ static void appRestoredCallbackDefault(void)
SDL_ANDROID_ResumeAudioPlayback(); SDL_ANDROID_ResumeAudioPlayback();
} }
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackgroundCallback = appPutToBackgroundCallbackDefault; static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackgroundCallback = appPutToBackgroundCallbackDefault;
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestoredCallback = appRestoredCallbackDefault; static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestoredCallback = appRestoredCallbackDefault;
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALPutToBackgroundCallback = NULL; static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALPutToBackgroundCallback = NULL;
static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALRestoredCallback = 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() int SDL_ANDROID_CallJavaSwapBuffers()
{ {
JNIEnv *JavaEnv = GetJavaEnv();
if( !glContextLost ) if( !glContextLost )
{ {
// Clear part of screen not used by SDL - on Android the screen contains garbage after each frame // 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) int SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput(void)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleScreenKeyboardWithoutTextInput ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleScreenKeyboardWithoutTextInput );
return 1; return 1;
} }
int SDL_ANDROID_ToggleInternalScreenKeyboard(SDL_InternalKeyboard_t keyboard) int SDL_ANDROID_ToggleInternalScreenKeyboard(SDL_InternalKeyboard_t keyboard)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleInternalScreenKeyboard, (jint)keyboard ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleInternalScreenKeyboard, (jint)keyboard );
return 1; return 1;
} }
@@ -254,6 +264,8 @@ extern SDL_Surface *SDL_GetVideoSurface(void);
void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf, int outBufLen) 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 // 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_LEFT );
SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT ); 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() void SDL_ANDROID_CallJavaHideScreenKeyboard()
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaHideScreenKeyboard ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaHideScreenKeyboard );
} }
@@ -318,6 +331,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeScreenKeyboardShown) ( JNIEnv* env, jo
void SDL_ANDROID_CallJavaSetScreenKeyboardHintMessage(const char *hint) void SDL_ANDROID_CallJavaSetScreenKeyboardHintMessage(const char *hint)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->PushLocalFrame(JavaEnv, 1); (*JavaEnv)->PushLocalFrame(JavaEnv, 1);
jstring s = hint ? (*JavaEnv)->NewStringUTF(JavaEnv, hint) : NULL; jstring s = hint ? (*JavaEnv)->NewStringUTF(JavaEnv, hint) : NULL;
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetScreenKeyboardHintMessage, s ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetScreenKeyboardHintMessage, s );
@@ -328,13 +342,14 @@ void SDL_ANDROID_CallJavaSetScreenKeyboardHintMessage(const char *hint)
void SDL_ANDROID_CallJavaStartAccelerometerGyroscope(int start) void SDL_ANDROID_CallJavaStartAccelerometerGyroscope(int start)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaStartAccelerometerGyroscope, (jint) start ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaStartAccelerometerGyroscope, (jint) start );
} }
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject thiz ) JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject thiz )
{ {
JavaEnv = env; JNIEnv *JavaEnv = env;
JavaRenderer = (*JavaEnv)->NewGlobalRef( JavaEnv, thiz ); JavaRenderer = (*JavaEnv)->NewGlobalRef( JavaEnv, thiz );
JavaRendererClass = (*JavaEnv)->GetObjectClass(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) int SDLCALL SDL_SetClipboardText(const char *text)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->PushLocalFrame(JavaEnv, 1); (*JavaEnv)->PushLocalFrame(JavaEnv, 1);
jstring s = (*JavaEnv)->NewStringUTF(JavaEnv, text); jstring s = (*JavaEnv)->NewStringUTF(JavaEnv, text);
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetClipboardText, s ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetClipboardText, s );
@@ -444,6 +460,7 @@ int SDLCALL SDL_SetClipboardText(const char *text)
char * SDLCALL SDL_GetClipboardText(void) char * SDLCALL SDL_GetClipboardText(void)
{ {
char *buf = NULL; char *buf = NULL;
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->PushLocalFrame( JavaEnv, 1 ); (*JavaEnv)->PushLocalFrame( JavaEnv, 1 );
jstring s = (jstring) (*JavaEnv)->CallObjectMethod( JavaEnv, JavaRenderer, JavaGetClipboardText ); jstring s = (jstring) (*JavaEnv)->CallObjectMethod( JavaEnv, JavaRenderer, JavaGetClipboardText );
if( s ) 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) int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position)
{ {
jint arr[5]; jint arr[5];
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->PushLocalFrame( JavaEnv, 1 ); (*JavaEnv)->PushLocalFrame( JavaEnv, 1 );
jintArray elemArr = (*JavaEnv)->NewIntArray(JavaEnv, 5); jintArray elemArr = (*JavaEnv)->NewIntArray(JavaEnv, 5);
if (elemArr == NULL) if (elemArr == NULL)
@@ -511,16 +529,19 @@ int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * positio
} }
int SDLCALL SDL_ANDROID_SetAdvertisementVisible(int visible) int SDLCALL SDL_ANDROID_SetAdvertisementVisible(int visible)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementVisible, (jint)visible ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementVisible, (jint)visible );
return 1; return 1;
} }
int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int left, int top) int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int left, int top)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementPosition, (jint)left, (jint)top ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementPosition, (jint)left, (jint)top );
return 1; return 1;
} }
int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void) int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestNewAdvertisement ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestNewAdvertisement );
return 1; 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, int SDLCALL SDL_ANDROID_CloudSave(const char *filename, const char *saveId, const char *dialogTitle,
const char *description, const char *screenshotFile, uint64_t playedTimeMs) 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); __android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_CloudSave: played time %llu", playedTimeMs);
if( !filename ) if( !filename )
return 0; 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) int SDLCALL SDL_ANDROID_CloudLoad(const char *filename, const char *saveId, const char *dialogTitle)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
if( !filename ) if( !filename )
return 0; return 0;
if( !saveId ) 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) void SDLCALL SDL_ANDROID_OpenExternalApp(const char *package, const char *activity, const char *data)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->PushLocalFrame(JavaEnv, 3); (*JavaEnv)->PushLocalFrame(JavaEnv, 3);
jstring s1 = package ? (*JavaEnv)->NewStringUTF(JavaEnv, package) : (*JavaEnv)->NewStringUTF(JavaEnv, ""); jstring s1 = package ? (*JavaEnv)->NewStringUTF(JavaEnv, package) : (*JavaEnv)->NewStringUTF(JavaEnv, "");
jstring s2 = activity ? (*JavaEnv)->NewStringUTF(JavaEnv, activity) : (*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) void SDLCALL SDL_ANDROID_RestartMyself(const char *restartParams)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->PushLocalFrame(JavaEnv, 1); (*JavaEnv)->PushLocalFrame(JavaEnv, 1);
jstring s1 = restartParams ? (*JavaEnv)->NewStringUTF(JavaEnv, restartParams) : (*JavaEnv)->NewStringUTF(JavaEnv, ""); jstring s1 = restartParams ? (*JavaEnv)->NewStringUTF(JavaEnv, restartParams) : (*JavaEnv)->NewStringUTF(JavaEnv, "");
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestRestartMyself, s1 ); (*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) void SDLCALL SDL_ANDROID_SetConfigOption(int option, int value)
{ {
JNIEnv *JavaEnv = GetJavaEnv();
(*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestSetConfigOption, (jint)option, (jint)value ); (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestSetConfigOption, (jint)option, (jint)value );
} }

View File

@@ -18,7 +18,7 @@ extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls);
// Library init // Library init
extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
{ {
return JNI_VERSION_1_4; return JNI_VERSION_1_6;
} }
// Start up the SDL app // Start up the SDL app

View File

@@ -44,26 +44,17 @@ jobject SDL_ANDROID_JniVideoObject()
return static_thiz; return static_thiz;
} }
void redirectStdout()
{
freopen( "stdout.log", "w", stdout );
dup2( fileno(stdout), fileno(stderr) );
}
#if SDL_VERSION_ATLEAST(1,3,0) #if SDL_VERSION_ATLEAST(1,3,0)
#else #else
extern void SDL_ANDROID_MultiThreadedVideoLoopInit(); extern void SDL_ANDROID_MultiThreadedVideoLoopInit();
extern void SDL_ANDROID_MultiThreadedVideoLoop(); 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 ) static JNIEnv *JavaEnv = NULL;
{ (*SDL_ANDROID_JavaVM())->AttachCurrentThread(SDL_ANDROID_JavaVM(), &JavaEnv, NULL);
//__android_log_print(ANDROID_LOG_INFO, "libSDL", "We are being debugged - waiting for debugger for 7 seconds");
//usleep(7000000);
}
SDL_main( argc, argv ); SDL_main( argc, argv );
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Application closed, calling exit(0)"); __android_log_print(ANDROID_LOG_INFO, "libSDL", "Application closed, calling exit(0)");
exit(0); exit(0);
@@ -71,7 +62,7 @@ int threadedMain(void * waitForDebugger)
#endif #endif
extern C_LINKAGE void 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; int i = 0;
char curdir[PATH_MAX] = ""; char curdir[PATH_MAX] = "";
@@ -93,9 +84,6 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz, jstring
setenv("HOME", curdir, 1); setenv("HOME", curdir, 1);
__android_log_print(ANDROID_LOG_INFO, "libSDL", "Changing curdir to \"%s\"", curdir); __android_log_print(ANDROID_LOG_INFO, "libSDL", "Changing curdir to \"%s\"", curdir);
if( waitForDebugger )
redirectStdout();
jstr = (*env)->GetStringUTFChars(env, cmdline, NULL); jstr = (*env)->GetStringUTFChars(env, cmdline, NULL);
if (jstr != NULL && strlen(jstr) > 0) if (jstr != NULL && strlen(jstr) > 0)
@@ -147,17 +135,12 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInit) ( JNIEnv* env, jobject thiz, jstring
#else #else
if( ! multiThreadedVideo ) 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 ); SDL_main( argc, argv );
} }
else else
{ {
SDL_ANDROID_MultiThreadedVideoLoopInit(); SDL_ANDROID_MultiThreadedVideoLoopInit();
SDL_CreateThread(threadedMain, (void *)waitForDebugger); SDL_CreateThread(threadedMain, NULL);
SDL_ANDROID_MultiThreadedVideoLoop(); SDL_ANDROID_MultiThreadedVideoLoop();
} }
#endif #endif