From af440bf5459db58dc6b216873249683f5e4abec2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 30 May 2014 17:49:04 +0200 Subject: [PATCH] (Menu) Menu now gets inited from driver.c instead of frontend.c (Console) Better way to 'restart' instead of using the function 'restart' - call rarch_set_fullscreen instead. 'Restart' function in driver interface can go now (Menu) Menu now gets properly deinited/reinited when - say - rarch_set_fullscreen is toggled or some other state change like this. If init_assets function of menu_ctx_driver is implemented, this should ensure all GL/D3D assets get 'cleaned up' prior to teardown of the video driver, and properly reinited after the video driver is brought up again --- driver.c | 36 +++++++++++++++++++++ driver.h | 3 ++ frontend/frontend.c | 33 ++----------------- frontend/menu/backend/menu_common_backend.c | 25 ++++---------- frontend/menu/disp/lakka.c | 4 +++ frontend/menu/file_list.c | 31 +++++++++++++++++- frontend/menu/menu_common.c | 36 ++++++++++----------- frontend/menu/menu_common.h | 2 +- 8 files changed, 101 insertions(+), 69 deletions(-) diff --git a/driver.c b/driver.c index ec5903f29a..4e94c2acd6 100644 --- a/driver.c +++ b/driver.c @@ -34,6 +34,10 @@ #include "gfx/context/x11_common.h" #endif +#ifdef HAVE_MENU +#include "frontend/menu/menu_common.h" +#endif + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -501,6 +505,20 @@ bool driver_update_system_av_info(const struct retro_system_av_info *info) return true; } +#ifdef HAVE_MENU +static void init_menu(void) +{ + if (!driver.menu_ctx) + find_menu_driver(); + + if (!(driver.menu = (rgui_handle_t*)menu_init(driver.menu_ctx))) + { + RARCH_ERR("Cannot initialize menu.\n"); + rarch_fail(1, "init_menu()"); + } +} +#endif + void init_drivers(void) { driver.video_data_own = false; @@ -515,10 +533,14 @@ void init_drivers(void) #ifdef HAVE_OSK driver.osk_data_own = false; #endif +#ifdef HAVE_MENU + driver.menu_data_own = false; +#endif adjust_system_rates(); g_extern.frame_count = 0; + init_video_input(); if (!driver.video_cache_context_ack && g_extern.system.hw_render_callback.context_reset) @@ -543,6 +565,10 @@ void init_drivers(void) init_osk(); #endif +#ifdef HAVE_MENU + init_menu(); +#endif + // Keep non-throttled state as good as possible. if (driver.nonblock_state) driver_set_nonblock_state(driver.nonblock_state); @@ -605,6 +631,14 @@ void uninit_drivers(void) if (g_extern.system.hw_render_callback.context_destroy && !driver.video_cache_context) g_extern.system.hw_render_callback.context_destroy(); +#ifdef HAVE_MENU + if (!driver.menu_data_own) + { + menu_free(driver.menu); + driver.menu = NULL; + } +#endif + uninit_video_input(); if (!driver.video_data_own) @@ -1087,6 +1121,7 @@ void init_video_input(void) rarch_fail(1, "init_video_input()"); } + driver.video_poke = NULL; if (driver.video->poke_interface) driver.video->poke_interface(driver.video_data, &driver.video_poke); @@ -1163,6 +1198,7 @@ void uninit_video_input(void) if (!driver.input_data_own && driver.input_data != driver.video_data && driver.input && driver.input->free) input_free_func(); + if (!driver.video_data_own && driver.video_data && driver.video && driver.video->free) video_free_func(); diff --git a/driver.h b/driver.h index d52aa5ef20..89e1ff4b83 100644 --- a/driver.h +++ b/driver.h @@ -505,6 +505,9 @@ typedef struct driver #ifdef HAVE_OSK bool osk_data_own; #endif +#ifdef HAVE_MENU + bool menu_data_own; +#endif #ifdef HAVE_COMMAND rarch_cmd_t *command; diff --git a/frontend/frontend.c b/frontend/frontend.c index 72b44721b1..2963922812 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -175,6 +175,9 @@ static int main_entry_iterate_menu_preinit(args_type() args) int i; rgui_handle_t *rgui = (rgui_handle_t*)driver.menu; + if (!rgui) + return 1; + // Menu should always run with vsync on. video_set_nonblock_state_func(false); // Stop all rumbling when entering RGUI. @@ -193,12 +196,6 @@ static int main_entry_iterate_menu_preinit(args_type() args) if (driver.audio_data) audio_stop_func(); - if (!rgui) - { - driver.menu = (rgui_handle_t*)menu_init(); - rgui = (rgui_handle_t*)driver.menu; - } - rgui->need_refresh = true; rgui->old_input_state |= 1ULL << RARCH_MENU_TOGGLE; @@ -262,11 +259,8 @@ int main_entry_iterate(signature(), args_type() args) void main_exit(args_type() args) { -#ifdef HAVE_MENU g_extern.system.shutdown = false; - menu_free(driver.menu); - if (g_extern.config_save_on_exit && *g_extern.config_path) { // save last core-specific config to the default config location, needed on @@ -277,7 +271,6 @@ void main_exit(args_type() args) if (*g_extern.core_specific_config_path && g_settings.core_specific_config) config_save_file(g_extern.core_specific_config_path); } -#endif if (g_extern.main_is_init) rarch_main_deinit(); @@ -339,26 +332,6 @@ returntype main_entry(signature()) } #if defined(HAVE_MENU) - driver.menu = (rgui_handle_t*)menu_init(); - - if (!driver.menu) - { - RARCH_ERR("Couldn't initialize menu.\n"); - - if (!driver.menu_ctx) - { - RARCH_WARN("Trying to bring up menu context interface.\n"); - find_menu_driver(); - } - - if (!(driver.menu = (rgui_handle_t*)menu_init())) - { - RARCH_ERR("Couldn't initialize menu (2nd attempt).\n"); - rarch_fail(1, "main_entry()"); - returnfunc(); - } - } - if (driver.frontend_ctx && driver.frontend_ctx->process_args) driver.frontend_ctx->process_args(argc, argv, args); diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index a1d39df25b..fb979c7d9f 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -590,6 +590,10 @@ static unsigned menu_common_type_is(unsigned type) static int menu_settings_iterate(void *data, unsigned action) { rgui_handle_t *rgui = (rgui_handle_t*)data; + + if (!rgui) + return 0; + rgui->frame_buf_pitch = rgui->width * 2; unsigned type = 0; const char *label = NULL; @@ -3390,12 +3394,7 @@ static int menu_common_setting_set(void *data, unsigned setting, unsigned action g_extern.lifecycle_state &= ~(1ULL << MODE_VIDEO_PAL_TEMPORAL_ENABLE); } - if (driver.video && driver.video->restart) - driver.video->restart(); - if (driver.menu_ctx && driver.menu_ctx->free_assets) - driver.menu_ctx->free_assets(rgui); - if (driver.menu_ctx && driver.menu_ctx->init_assets) - driver.menu_ctx->init_assets(rgui); + rarch_set_fullscreen(g_settings.video.fullscreen); } break; case RGUI_SETTINGS_VIDEO_PAL60: @@ -3411,12 +3410,7 @@ static int menu_common_setting_set(void *data, unsigned setting, unsigned action else g_extern.lifecycle_state |= (1ULL << MODE_VIDEO_PAL_TEMPORAL_ENABLE); - if (driver.video && driver.video->restart) - driver.video->restart(); - if (driver.menu_ctx && driver.menu_ctx->free_assets) - driver.menu_ctx->free_assets(rgui); - if (driver.menu_ctx && driver.menu_ctx->init_assets) - driver.menu_ctx->init_assets(rgui); + rarch_set_fullscreen(g_settings.video.fullscreen); } break; case RGUI_ACTION_START: @@ -3424,12 +3418,7 @@ static int menu_common_setting_set(void *data, unsigned setting, unsigned action { g_extern.lifecycle_state &= ~(1ULL << MODE_VIDEO_PAL_TEMPORAL_ENABLE); - if (driver.video && driver.video->restart) - driver.video->restart(); - if (driver.menu_ctx && driver.menu_ctx->free_assets) - driver.menu_ctx->free_assets(rgui); - if (driver.menu_ctx && driver.menu_ctx->init_assets) - driver.menu_ctx->init_assets(rgui); + rarch_set_fullscreen(g_settings.video.fullscreen); } break; } diff --git a/frontend/menu/disp/lakka.c b/frontend/menu/disp/lakka.c index efe1968a16..041224bd94 100644 --- a/frontend/menu/disp/lakka.c +++ b/frontend/menu/disp/lakka.c @@ -1176,6 +1176,8 @@ static void lakka_init_items(int i, menu_category_t *category, core_info_t *info static void lakka_free_assets(void *data) { + (void)data; + if (tweens) free(tweens); } @@ -1184,6 +1186,8 @@ static void lakka_free(void *data) { rgui_handle_t *rgui = (rgui_handle_t*)data; + lakka_free_assets(rgui); + if (rgui->alloc_font) free((uint8_t*)rgui->font); } diff --git a/frontend/menu/file_list.c b/frontend/menu/file_list.c index 699f206780..11568ed073 100644 --- a/frontend/menu/file_list.c +++ b/frontend/menu/file_list.c @@ -55,6 +55,9 @@ void file_list_push(file_list_t *list, void file_list_pop(file_list_t *list, size_t *directory_ptr) { + if (!list) + return; + if (!(list->size == 0)) { if (driver.menu_ctx && driver.menu_ctx->list_delete) @@ -74,6 +77,10 @@ void file_list_pop(file_list_t *list, size_t *directory_ptr) void file_list_free(file_list_t *list) { size_t i; + + if (!list) + return; + for (i = 0; i < list->size; i++) free(list->list[i].path); free(list->list); @@ -83,6 +90,10 @@ void file_list_free(file_list_t *list) void file_list_clear(file_list_t *list) { size_t i; + + if (!list) + return; + for (i = 0; i < list->size; i++) { free(list->list[i].path); @@ -97,6 +108,9 @@ void file_list_clear(file_list_t *list) void file_list_set_alt_at_offset(file_list_t *list, size_t index, const char *alt) { + if (!list) + return; + free(list->list[index].alt); list->list[index].alt = strdup(alt); } @@ -104,6 +118,9 @@ void file_list_set_alt_at_offset(file_list_t *list, size_t index, void file_list_get_alt_at_offset(const file_list_t *list, size_t index, const char **alt) { + if (!list) + return; + if (alt) *alt = list->list[index].alt ? list->list[index].alt : list->list[index].path; } @@ -119,12 +136,18 @@ static int file_list_alt_cmp(const void *a_, const void *b_) void file_list_sort_on_alt(file_list_t *list) { + if (!list) + return; + qsort(list->list, list->size, sizeof(list->list[0]), file_list_alt_cmp); } void file_list_get_at_offset(const file_list_t *list, size_t index, const char **path, unsigned *file_type) { + if (!list) + return; + if (path) *path = list->list[index].path; if (file_type) @@ -134,6 +157,9 @@ void file_list_get_at_offset(const file_list_t *list, size_t index, void file_list_get_last(const file_list_t *list, const char **path, unsigned *file_type) { + if (!list) + return; + if (list->size) file_list_get_at_offset(list, list->size - 1, path, file_type); } @@ -143,6 +169,10 @@ bool file_list_search(const file_list_t *list, const char *needle, size_t *index size_t i; const char *alt; bool ret = false; + + if (!list) + return false; + for (i = 0; i < list->size; i++) { file_list_get_alt_at_offset(list, i, &alt); @@ -165,4 +195,3 @@ bool file_list_search(const file_list_t *list, const char *needle, size_t *index return ret; } - diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c index 2667b2f4bb..f3a8b136ea 100644 --- a/frontend/menu/menu_common.c +++ b/frontend/menu/menu_common.c @@ -271,6 +271,11 @@ bool load_menu_game(void *data) struct rarch_main_wrap args = {0}; rgui_handle_t *rgui = (rgui_handle_t*)data; + if (!rgui) + return false; + + args.no_rom = rgui->load_no_rom; + if (g_extern.main_is_init) rarch_main_deinit(); @@ -280,14 +285,11 @@ bool load_menu_game(void *data) args.state_path = *g_extern.savestate_dir ? g_extern.savestate_dir : NULL; args.rom_path = *g_extern.fullpath ? g_extern.fullpath : NULL; args.libretro_path = *g_settings.libretro ? g_settings.libretro : NULL; - args.no_rom = rgui->load_no_rom; - - if (rgui) - rgui->load_no_rom = false; if (rarch_main_init_wrap(&args) != 0) { char name[PATH_MAX], msg[PATH_MAX]; + rgui = (rgui_handle_t*)driver.menu; fill_pathname_base(name, g_extern.fullpath, sizeof(name)); snprintf(msg, sizeof(msg), "Failed to load %s.\n", name); @@ -300,11 +302,12 @@ bool load_menu_game(void *data) RARCH_LOG("rarch_main_init_wrap() succeeded.\n"); - if (rgui) + if ((rgui = (rgui_handle_t*)driver.menu)) { // Update menu state which depends on config. menu_update_libretro_info(rgui); menu_init_history(rgui); + if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->shader_manager_init) driver.menu_ctx->backend->shader_manager_init(rgui); } @@ -312,25 +315,20 @@ bool load_menu_game(void *data) return true; } -void *menu_init(void) +void *menu_init(const void *data) { rgui_handle_t *rgui; + menu_ctx_driver_t *menu_ctx = (menu_ctx_driver_t*)data; - rgui = NULL; - - if (!driver.menu_ctx) - { - RARCH_ERR("menu_init() - menu context interface not initialized.\n"); + if (!menu_ctx) return NULL; - } - if (driver.menu_ctx->init) - rgui = (rgui_handle_t*)driver.menu_ctx->init(); + rgui = (rgui_handle_t*)menu_ctx->init(); if (!rgui) return NULL; - strlcpy(g_settings.menu.driver, driver.menu_ctx->ident, sizeof(g_settings.menu.driver)); + strlcpy(g_settings.menu.driver, menu_ctx->ident, sizeof(g_settings.menu.driver)); rgui->menu_stack = (file_list_t*)calloc(1, sizeof(file_list_t)); rgui->selection_buf = (file_list_t*)calloc(1, sizeof(file_list_t)); @@ -339,8 +337,8 @@ void *menu_init(void) rgui->push_start_screen = g_settings.rgui_show_start_screen; g_settings.rgui_show_start_screen = false; - if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->entries_init) - driver.menu_ctx->backend->entries_init(rgui, RGUI_SETTINGS); + if (menu_ctx && menu_ctx->backend && menu_ctx->backend->entries_init) + menu_ctx->backend->entries_init(rgui, RGUI_SETTINGS); rgui->trigger_state = 0; rgui->old_input_state = 0; @@ -350,8 +348,8 @@ void *menu_init(void) menu_update_libretro_info(rgui); - if (driver.menu_ctx && driver.menu_ctx->backend && driver.menu_ctx->backend->shader_manager_init) - driver.menu_ctx->backend->shader_manager_init(rgui); + if (menu_ctx && menu_ctx->backend && menu_ctx->backend->shader_manager_init) + menu_ctx->backend->shader_manager_init(rgui); menu_init_history(rgui); rgui->last_time = rarch_get_time_usec(); diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h index d932c94ab8..747507b07b 100644 --- a/frontend/menu/menu_common.h +++ b/frontend/menu/menu_common.h @@ -186,7 +186,7 @@ typedef struct retro_time_t sleep_msec; } rgui_handle_t; -void *menu_init(void); +void *menu_init(const void *data); bool menu_iterate(void *data); void menu_free(void *data);