diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 08e8478f3b6..3e8d53dab25 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -2463,15 +2463,15 @@ static void rcheevos_client_load_game_callback(int result, } #ifdef HAVE_THREADS - if (!task_is_on_main_thread()) + if (!video_driver_is_threaded() && !task_is_on_main_thread()) { /* have to "schedule" this. game image should not be loaded on background thread */ rcheevos_locals.queued_command = CMD_CHEEVOS_NON_COMMAND; rcheevos_locals.game_placard_requested = true; } else - rcheevos_show_game_placard(); #endif + rcheevos_show_game_placard(); rcheevos_finalize_game_load(client); diff --git a/cheevos/cheevos_menu.c b/cheevos/cheevos_menu.c index 4ff901ef4ce..42a8d8e7a14 100644 --- a/cheevos/cheevos_menu.c +++ b/cheevos/cheevos_menu.c @@ -475,12 +475,15 @@ uintptr_t rcheevos_get_badge_texture(const char* badge, bool locked, bool downlo if (!badge || !badge[0]) return 0; - /* OpenGL driver crashes if gfx_display_reset_textures_list is called on a background thread */ - if (!task_is_on_main_thread()) - { - CHEEVOS_ERR(RCHEEVOS_TAG "attempt to load badge %s from background thread", badge); - retro_assert(task_is_on_main_thread()); - } +#ifdef HAVE_THREADS + /* The OpenGL driver crashes if gfx_display_reset_textures_list is not called on the video thread. + * If threaded video is enabled, it'll automatically dispatch the request to the video thread. + * If threaded video is not enabled, just return null. The video thread should assume the image + * wasn't downloaded and check again in a few frames. + */ + if (!video_driver_is_threaded() && !task_is_on_main_thread()) + return 0; +#endif snprintf(badge_file, sizeof(badge_file), "%s%s%s", badge, locked ? "_lock" : "", FILE_PATH_PNG_EXTENSION); diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index 6b81fbee07e..ad369cd2e1b 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -1432,6 +1432,11 @@ unsigned video_thread_texture_load(void *data, custom_command_method_t func) if (!thr) return 0; + /* if we're already on the video thread, just call the function, otherwise + * we may deadlock with ourself waiting for the packet to be processed. */ + if (sthread_get_thread_id(thr->thread) == sthread_get_current_thread_id()) + return func(data); + pkt.type = CMD_CUSTOM_COMMAND; pkt.data.custom_command.method = func; pkt.data.custom_command.data = data;