diff --git a/src/twn_audio.c b/src/twn_audio.c index 50a8b6d..6a4eb6c 100644 --- a/src/twn_audio.c +++ b/src/twn_audio.c @@ -250,6 +250,8 @@ void audio_play(const char *path, float panning) { if (!ctx.audio_initialized) { + SDL_InitSubSystem(SDL_INIT_AUDIO); + profile_start("audio initialization"); SDL_AudioSpec request, got; diff --git a/src/twn_loop.c b/src/twn_loop.c index 52ead87..4a89cc7 100644 --- a/src/twn_loop.c +++ b/src/twn_loop.c @@ -21,7 +21,7 @@ #define PACKAGE_EXTENSION "btw" -static SDL_Thread *opengl_load_thread; +static SDL_sem *opengl_load_semaphore; /* note: it drives most of IO implicitly, such as audio callbacks */ @@ -334,10 +334,11 @@ ERR_PACK_MANIFEST_PATH_ALLOC_FAIL: } -static int opengl_load_thread_fn(void *data) { - (void)data; +static int opengl_load_thread_fn(void *sem) { + SDL_assert_always(!SDL_GL_LoadLibrary(NULL)); - SDL_GL_LoadLibrary(NULL); + /* signal success */ + SDL_assert_always(!SDL_SemPost(sem)); return 0; } @@ -643,7 +644,8 @@ static bool initialize(void) { profile_end("game object load"); /* delayed as further as possible so that more work is done before we have to wait */ - SDL_WaitThread(opengl_load_thread, NULL); + SDL_SemWait(opengl_load_semaphore); + SDL_DestroySemaphore(opengl_load_semaphore); profile_end("opengl loading"); SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); @@ -694,6 +696,11 @@ static bool initialize(void) { /* might need this to have multiple windows */ ctx.window_id = SDL_GetWindowID(ctx.window); + /* post background color until we're doing other initialization */ + render(); + if (ctx.render_double_buffered) + render(); + profile_start("texture and text cache initialization"); textures_cache_init(&ctx.texture_cache, ctx.window); text_cache_init(&ctx.text_cache); @@ -760,19 +767,23 @@ int enter_loop(int argc, char **argv) { profile_start("startup"); profile_start("SDL initialization"); - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS) == -1) { + if (SDL_Init(SDL_INIT_VIDEO) == -1) { CRY_SDL("SDL initialization failed."); return EXIT_FAILURE; } profile_end("SDL initialization"); profile_start("opengl loading"); - opengl_load_thread = SDL_CreateThread(opengl_load_thread_fn, "opengl loader", NULL); + opengl_load_semaphore = SDL_CreateSemaphore(0); + SDL_Thread *opengl_load_thread = SDL_CreateThread(opengl_load_thread_fn, "opengl loader", opengl_load_semaphore); if (!opengl_load_thread) { CRY_SDL("Cannot create opengl loading thread: "); return EXIT_FAILURE; } + SDL_DetachThread(opengl_load_thread); + opengl_load_thread = NULL; + ctx.argc = argc; ctx.argv = argv; ctx.base_dir = SDL_GetBasePath(); @@ -849,6 +860,8 @@ int enter_loop(int argc, char **argv) { ctx.was_successful = true; ctx.game.initialization_needed = true; + SDL_InitSubSystem(SDL_INIT_EVENTS); + profile_end("startup"); while (ctx.is_running) {