From d7cfcd3f9b170d0cbd06937cdf1d9bbf116b1619 Mon Sep 17 00:00:00 2001 From: Ryunam Date: Mon, 16 May 2022 17:50:11 +0200 Subject: [PATCH] Add option to toggle automatic refresh rate switching --- config.def.h | 4 ++++ configuration.c | 1 + configuration.h | 1 + driver.c | 33 ++++++++++++++++++----------- gfx/video_defines.h | 9 ++++++++ gfx/video_driver.c | 24 ++++++++++++++------- intl/msg_hash_lbl.h | 4 ++++ intl/msg_hash_us.h | 20 ++++++++++++++++++ menu/cbs/menu_cbs_sublabel.c | 4 ++++ menu/drivers/ozone.c | 1 + menu/drivers/xmb.c | 1 + menu/menu_displaylist.c | 7 ++++++ menu/menu_setting.c | 41 ++++++++++++++++++++++++++++++++++++ msg_hash.h | 6 ++++++ 14 files changed, 136 insertions(+), 20 deletions(-) diff --git a/config.def.h b/config.def.h index a41e24613f..4e4e4275e9 100644 --- a/config.def.h +++ b/config.def.h @@ -224,6 +224,10 @@ #define DEFAULT_WINDOWED_FULLSCREEN true #endif +/* Enable automatic switching of the screen refresh rate when using the specified screen mode(s), + * based on running core/content */ +#define DEFAULT_AUTOSWITCH_REFRESH_RATE AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN + /* Which monitor to prefer. 0 is any monitor, 1 and up selects * specific monitors, 1 being the first monitor. */ #define DEFAULT_MONITOR_INDEX 0 diff --git a/configuration.c b/configuration.c index 4769176fe7..a37e25c6de 100644 --- a/configuration.c +++ b/configuration.c @@ -2125,6 +2125,7 @@ static struct config_uint_setting *populate_settings_uint( #endif SETTING_UINT("screen_brightness", &settings->uints.screen_brightness, true, DEFAULT_SCREEN_BRIGHTNESS, false); SETTING_UINT("crt_switch_resolution", &settings->uints.crt_switch_resolution, true, DEFAULT_CRT_SWITCH_RESOLUTION, false); + SETTING_UINT("video_autoswitch_refresh_rate", &settings->uints.video_autoswitch_refresh_rate, true, DEFAULT_AUTOSWITCH_REFRESH_RATE, false); SETTING_UINT("input_bind_timeout", &settings->uints.input_bind_timeout, true, input_bind_timeout, false); SETTING_UINT("input_bind_hold", &settings->uints.input_bind_hold, true, input_bind_hold, false); SETTING_UINT("input_turbo_period", &settings->uints.input_turbo_period, true, turbo_period, false); diff --git a/configuration.h b/configuration.h index 2dafacabff..d9687cf0f5 100644 --- a/configuration.h +++ b/configuration.h @@ -332,6 +332,7 @@ typedef struct settings unsigned core_updater_auto_backup_history_size; unsigned video_black_frame_insertion; + unsigned video_autoswitch_refresh_rate; unsigned quit_on_close_content; #ifdef HAVE_LAKKA diff --git a/driver.c b/driver.c index 83eeaee500..2c82f2bea8 100644 --- a/driver.c +++ b/driver.c @@ -520,24 +520,33 @@ void drivers_init( { struct retro_system_av_info *av_info = &video_st->av_info; float refresh_rate = av_info->timing.fps; - + unsigned autoswitch_refresh_rate = settings->uints.video_autoswitch_refresh_rate; + bool exclusive_fullscreen = settings->bools.video_fullscreen && !settings->bools.video_windowed_fullscreen; + bool windowed_fullscreen = settings->bools.video_fullscreen && settings->bools.video_windowed_fullscreen; + bool all_fullscreen = settings->bools.video_fullscreen || settings->bools.video_windowed_fullscreen; + if ( refresh_rate > 0.0 && !settings->uints.crt_switch_resolution && !settings->bools.vrr_runloop_enable && - !settings->bools.video_windowed_fullscreen && - settings->bools.video_fullscreen && + video_display_server_has_resolution_list() && + (autoswitch_refresh_rate != AUTOSWITCH_REFRESH_RATE_OFF) && fabs(settings->floats.video_refresh_rate - refresh_rate) > 1) { - bool video_switch_refresh_rate = false; - - video_switch_refresh_rate_maybe(&refresh_rate, &video_switch_refresh_rate); - - if (video_switch_refresh_rate && video_display_server_set_refresh_rate(refresh_rate)) + if (((autoswitch_refresh_rate == AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN) && exclusive_fullscreen) || + ((autoswitch_refresh_rate == AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN) && windowed_fullscreen) || + ((autoswitch_refresh_rate == AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN) && all_fullscreen)) { - int reinit_flags = DRIVER_AUDIO_MASK; - video_monitor_set_refresh_rate(refresh_rate); - /* Audio must reinit after successful rate switch */ - command_event(CMD_EVENT_REINIT, &reinit_flags); + bool video_switch_refresh_rate = false; + + video_switch_refresh_rate_maybe(&refresh_rate, &video_switch_refresh_rate); + + if (video_switch_refresh_rate && video_display_server_set_refresh_rate(refresh_rate)) + { + int reinit_flags = DRIVER_AUDIO_MASK; + video_monitor_set_refresh_rate(refresh_rate); + /* Audio must reinit after successful rate switch */ + command_event(CMD_EVENT_REINIT, &reinit_flags); + } } } } diff --git a/gfx/video_defines.h b/gfx/video_defines.h index d11f0143ed..f1ce8e187c 100644 --- a/gfx/video_defines.h +++ b/gfx/video_defines.h @@ -75,6 +75,15 @@ enum rotation ORIENTATION_END }; +enum autoswitch_refresh_rate +{ + AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN = 0, + AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN, + AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN, + AUTOSWITCH_REFRESH_RATE_OFF, + AUTOSWITCH_REFRESH_RATE_LAST +}; + enum rarch_display_type { /* Non-bindable types like consoles, KMS, VideoCore, etc. */ diff --git a/gfx/video_driver.c b/gfx/video_driver.c index 25f5cc5106..38c97e190c 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -1170,12 +1170,14 @@ void video_switch_refresh_rate_maybe( float refresh_rate = *refresh_rate_suggest; float video_refresh_rate = settings->floats.video_refresh_rate; unsigned crt_switch_resolution = settings->uints.crt_switch_resolution; + unsigned autoswitch_refresh_rate = settings->uints.video_autoswitch_refresh_rate; unsigned video_swap_interval = runloop_get_video_swap_interval( settings->uints.video_swap_interval); unsigned video_bfi = settings->uints.video_black_frame_insertion; - bool video_fullscreen = settings->bools.video_fullscreen; - bool video_windowed_full = settings->bools.video_windowed_fullscreen; bool vrr_runloop_enable = settings->bools.vrr_runloop_enable; + bool exclusive_fullscreen = settings->bools.video_fullscreen && !settings->bools.video_windowed_fullscreen; + bool windowed_fullscreen = settings->bools.video_fullscreen && settings->bools.video_windowed_fullscreen; + bool all_fullscreen = settings->bools.video_fullscreen || settings->bools.video_windowed_fullscreen; /* Roundings to PAL & NTSC standards */ refresh_rate = (refresh_rate > 54 && refresh_rate < 60) ? 59.94f : refresh_rate; @@ -1196,15 +1198,21 @@ void video_switch_refresh_rate_maybe( if (!video_st->video_refresh_rate_original) video_st->video_refresh_rate_original = video_refresh_rate; - /* Try to switch display rate when: + /* Try to switch display rate for the desired screen mode(s) when: * - Not already at correct rate - * - In exclusive fullscreen * - 'CRT SwitchRes' OFF & 'Sync to Exact Content Framerate' OFF + * - Automatic refresh rate switching not OFF */ - *video_switch_refresh_rate = ( - refresh_rate != video_refresh_rate && - !crt_switch_resolution && !vrr_runloop_enable && - video_fullscreen && !video_windowed_full); + if (refresh_rate != video_refresh_rate && + !crt_switch_resolution && + !vrr_runloop_enable && + (autoswitch_refresh_rate != AUTOSWITCH_REFRESH_RATE_OFF)) + { + *video_switch_refresh_rate = ( + ((autoswitch_refresh_rate == AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN) && exclusive_fullscreen) || + ((autoswitch_refresh_rate == AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN) && windowed_fullscreen) || + ((autoswitch_refresh_rate == AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN) && all_fullscreen)); + } } bool video_display_server_set_refresh_rate(float hz) diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 51ab8f2aaa..f725efa511 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -3628,6 +3628,10 @@ MSG_HASH( MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, "video_refresh_rate_polled" ) +MSG_HASH( + MENU_ENUM_LABEL_VIDEO_AUTOSWITCH_REFRESH_RATE, + "video_autoswitch_refresh_rate" + ) MSG_HASH( MENU_ENUM_LABEL_VIDEO_ROTATION, "video_rotation" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 144af28959..d6d0beaa57 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1701,6 +1701,26 @@ MSG_HASH( MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED, "The refresh rate as reported by the display driver." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE, + "Switch Refresh Rate Automatically" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_VIDEO_AUTOSWITCH_REFRESH_RATE, + "Switch the refresh rate of the screen automatically when using the specified screen mode, based on the core and/or content being run." + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN, + "Only in Exclusive Fullscreen Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN, + "Only in Windowed Fullscreen Mode" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN, + "All Fullscreen Modes" + ) #if defined(DINGUX) && defined(DINGUX_BETA) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DINGUX_REFRESH_RATE, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index fd1246c281..c7c4640a28 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -610,6 +610,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_screen_orientation, MENU_ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_force_srgb_enable, MENU_ENUM_SUBLABEL_VIDEO_FORCE_SRGB_DISABLE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_fullscreen, MENU_ENUM_SUBLABEL_VIDEO_FULLSCREEN) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_windowed_fullscreen, MENU_ENUM_SUBLABEL_VIDEO_WINDOWED_FULLSCREEN) +DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_autoswitch_refresh_rate, MENU_ENUM_SUBLABEL_VIDEO_AUTOSWITCH_REFRESH_RATE) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_gpu_record, MENU_ENUM_SUBLABEL_VIDEO_GPU_RECORD) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_auto_index, MENU_ENUM_SUBLABEL_SAVESTATE_AUTO_INDEX) DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_block_sram_overwrite, MENU_ENUM_SUBLABEL_BLOCK_SRAM_OVERWRITE) @@ -3670,6 +3671,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_VIDEO_WINDOWED_FULLSCREEN: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_windowed_fullscreen); break; + case MENU_ENUM_LABEL_VIDEO_AUTOSWITCH_REFRESH_RATE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_autoswitch_refresh_rate); + break; case MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_force_srgb_enable); break; diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index 6b08f6a028..eafc4a13ab 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -2006,6 +2006,7 @@ static uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone, case MENU_ENUM_LABEL_RESET_TO_DEFAULT_CONFIG: case MENU_ENUM_LABEL_CHEAT_RELOAD_CHEATS: case MENU_ENUM_LABEL_RESTART_RETROARCH: + case MENU_ENUM_LABEL_VIDEO_AUTOSWITCH_REFRESH_RATE: case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE: case MENU_ENUM_LABEL_AUTOSAVE_INTERVAL: case MENU_ENUM_LABEL_FRAME_TIME_COUNTER_SETTINGS: diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 926f5fd4a3..59d2c9a0f4 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2638,6 +2638,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, case MENU_ENUM_LABEL_RESET_TO_DEFAULT_CONFIG: case MENU_ENUM_LABEL_CHEAT_RELOAD_CHEATS: case MENU_ENUM_LABEL_RESTART_RETROARCH: + case MENU_ENUM_LABEL_VIDEO_AUTOSWITCH_REFRESH_RATE: case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE: case MENU_ENUM_LABEL_AUTOSAVE_INTERVAL: case MENU_ENUM_LABEL_FRAME_TIME_COUNTER_SETTINGS: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 0f568fa9ad..4e9cf3ccfb 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -8552,6 +8552,13 @@ unsigned menu_displaylist_build_list( PARSE_ONLY_FLOAT, false) == 0) count++; } + if (video_display_server_has_resolution_list()) + { + if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, + MENU_ENUM_LABEL_VIDEO_AUTOSWITCH_REFRESH_RATE, + PARSE_ONLY_UINT, false) == 0) + count++; + } if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list, MENU_ENUM_LABEL_VIDEO_FORCE_SRGB_DISABLE, PARSE_ONLY_BOOL, false) == 0) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 73d083fe58..91c15d211d 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -4951,6 +4951,30 @@ static void setting_get_string_representation_uint_notification_show_screenshot_ #endif #endif +static void setting_get_string_representation_uint_video_autoswitch_refresh_rate( + rarch_setting_t *setting, + char *s, size_t len) +{ + if (!setting) + return; + + switch (*setting->value.target.unsigned_integer) + { + case AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN), len); + break; + case AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN), len); + break; + case AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN), len); + break; + case AUTOSWITCH_REFRESH_RATE_OFF: + strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF), len); + break; + } +} + static void setting_get_string_representation_uint_video_monitor_index(rarch_setting_t *setting, char *s, size_t len) { @@ -11635,6 +11659,23 @@ static bool setting_append_list( } } + CONFIG_UINT( + list, list_info, + &settings->uints.video_autoswitch_refresh_rate, + MENU_ENUM_LABEL_VIDEO_AUTOSWITCH_REFRESH_RATE, + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE, + DEFAULT_AUTOSWITCH_REFRESH_RATE, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; + (*list)[list_info->index - 1].get_string_representation = + &setting_get_string_representation_uint_video_autoswitch_refresh_rate; + menu_settings_list_current_add_range(list, list_info, 0, AUTOSWITCH_REFRESH_RATE_LAST - 1, 1, true, true); + (*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX; + if (string_is_equal(settings->arrays.video_driver, "gl")) { CONFIG_BOOL( diff --git a/msg_hash.h b/msg_hash.h index a98a810b5f..bdb01c1d43 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1107,6 +1107,12 @@ enum msg_hash_enums MENU_LABEL(VIDEO_HARD_SYNC), MENU_LABEL(VIDEO_HARD_SYNC_FRAMES), MENU_LABEL(VIDEO_WINDOWED_FULLSCREEN), + MENU_LABEL(VIDEO_AUTOSWITCH_REFRESH_RATE), + + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN, + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN, + MENU_ENUM_LABEL_VALUE_VIDEO_AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN, + MENU_LABEL(VIDEO_WINDOW_WIDTH), MENU_LABEL(VIDEO_WINDOW_HEIGHT), MENU_LABEL(VIDEO_WINDOW_AUTO_WIDTH_MAX),