From 8f654c4f83c595a4de27902817b6b09028d88f38 Mon Sep 17 00:00:00 2001 From: Ryunam Date: Thu, 20 Aug 2026 23:30:26 +0200 Subject: [PATCH] Video: Add option to automatically set display-reported refresh rate --- config.def.h | 1 + configuration.h | 1 + menu/cbs/menu_cbs_sublabel.c | 1 + menu/menu_displaylist.c | 1 + msg_hash_lbl_str.h | 1 + retroarch.c | 27 ++++++++++++++-------- settings/settings_def_refresh_autoswitch.h | 5 ++++ tools/settings_table.reference | 3 +++ 8 files changed, 31 insertions(+), 9 deletions(-) diff --git a/config.def.h b/config.def.h index bb10cb185cf4..7136d958fe4a 100644 --- a/config.def.h +++ b/config.def.h @@ -1139,6 +1139,7 @@ #else #define DEFAULT_REFRESH_RATE (60) #endif +#define DEFAULT_VIDEO_REFRESH_RATE_POLLED_AUTO false #define DEFAULT_CRT_REFRESH_RATE (DEFAULT_REFRESH_RATE) /* Allow games to set rotation. If false, rotation requests are diff --git a/configuration.h b/configuration.h index c71d60991bdb..564a20d31757 100644 --- a/configuration.h +++ b/configuration.h @@ -540,6 +540,7 @@ typedef struct settings /* Video */ bool video_fullscreen; bool video_windowed_fullscreen; + bool video_refresh_rate_polled_auto; bool video_vsync; bool video_adaptive_vsync; bool video_gl_direct_spirv; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 14554655b7ca..ed3f75ec56df 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -2361,6 +2361,7 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, { MENU_ENUM_LABEL_VIDEO_HARD_SYNC_FRAMES, MENU_ENUM_SUBLABEL_VIDEO_HARD_SYNC_FRAMES }, { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_AUTO }, { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED }, + { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED_AUTO, MENU_ENUM_SUBLABEL_VIDEO_REFRESH_RATE_POLLED_AUTO }, { MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX, MENU_ENUM_SUBLABEL_VIDEO_MONITOR_INDEX }, { MENU_ENUM_LABEL_LOG_VERBOSITY, MENU_ENUM_SUBLABEL_LOG_VERBOSITY }, { MENU_ENUM_LABEL_LOG_TO_FILE, MENU_ENUM_SUBLABEL_LOG_TO_FILE }, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e489ed36b191..149fea163a96 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -10718,6 +10718,7 @@ unsigned menu_displaylist_build_list( static const menu_displaylist_settings_row_t dl_rows_10[] = { { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE, PARSE_ONLY_FLOAT, false }, { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED, PARSE_ONLY_FLOAT, false }, + { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED_AUTO, PARSE_ONLY_BOOL, false }, { MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO, PARSE_ONLY_FLOAT, false }, }; count += menu_displaylist_parse_settings_rows(list, settings, diff --git a/msg_hash_lbl_str.h b/msg_hash_lbl_str.h index 2560a2d07f9d..2e1fb031c67d 100644 --- a/msg_hash_lbl_str.h +++ b/msg_hash_lbl_str.h @@ -677,6 +677,7 @@ #define MENU_ENUM_LABEL_VIDEO_FRAME_TIME_SAMPLE_GATED_STR "video_frame_time_sample_gated" #define MENU_ENUM_LABEL_VIDEO_GAMMA_STR "video_gamma" #define MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED_STR "video_refresh_rate_polled" +#define MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_POLLED_AUTO_STR "video_refresh_rate_polled_auto" #define MENU_ENUM_LABEL_VIDEO_USE_METAL_ARG_BUFFERS_STR "video_use_metal_arg_buffers" #define MENU_ENUM_LABEL_SHADER_APPLY_CHANGES_STR "shader_apply_changes" #define MENU_ENUM_LABEL_SHADER_OPTIONS_STR "shader_options" diff --git a/retroarch.c b/retroarch.c index 5ed39280a41d..5ffed16c4ad6 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1598,6 +1598,15 @@ void drivers_init( location_driver_state_t *location_st = location_state_get_ptr(); bool video_is_threaded = VIDEO_DRIVER_IS_THREADED_INTERNAL(video_st); + unsigned refresh_rate_auto = settings->uints.video_autoswitch_refresh_rate; + bool refresh_rate_polled_auto = settings->bools.video_refresh_rate_polled_auto; + 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 any_fullscreen = settings->bools.video_fullscreen || settings->bools.video_windowed_fullscreen; + bool refresh_rate_autoswitch = + ((refresh_rate_auto == AUTOSWITCH_REFRESH_RATE_EXCLUSIVE_FULLSCREEN) && exclusive_fullscreen) + || ((refresh_rate_auto == AUTOSWITCH_REFRESH_RATE_WINDOWED_FULLSCREEN) && windowed_fullscreen) + || ((refresh_rate_auto == AUTOSWITCH_REFRESH_RATE_ALL_FULLSCREEN) && any_fullscreen); gfx_display_t *p_disp = disp_get_ptr(); #if defined(HAVE_GFX_WIDGETS) bool video_font_enable = settings->bools.video_font_enable; @@ -1623,6 +1632,13 @@ void drivers_init( struct retro_hw_render_callback *hwr = VIDEO_DRIVER_GET_HW_CONTEXT_INTERNAL(video_st); + if (refresh_rate_polled_auto && (!refresh_rate_autoswitch || !runloop_is_inited())) + { + float refresh_rate = video_driver_get_refresh_rate(); + if (refresh_rate > 0.0f) + video_monitor_set_refresh_rate(refresh_rate); + } + video_st->frame_time_count = 0; video_driver_lock_new(); @@ -1645,23 +1661,16 @@ void drivers_init( if ( flags & (DRIVER_VIDEO_MASK | DRIVER_AUDIO_MASK) && !runloop_is_inited()) { - float refresh_rate = video_st->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; + float refresh_rate = video_st->av_info.timing.fps; /* Making a switch from PC standard 60 Hz to NTSC 59.94 is excluded by the last condition. */ if ( (refresh_rate > 0.0f) && !settings->uints.crt_switch_resolution && !settings->bools.vrr_runloop_enable && video_display_server_has_resolution_list() - && (autoswitch_refresh_rate != AUTOSWITCH_REFRESH_RATE_OFF) && (fabs(settings->floats.video_refresh_rate - refresh_rate) > 1)) { - 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)) + if (refresh_rate_autoswitch) { bool video_switch_refresh_rate = false; diff --git a/settings/settings_def_refresh_autoswitch.h b/settings/settings_def_refresh_autoswitch.h index 1fa04c82d93e..1a09994aa3da 100644 --- a/settings/settings_def_refresh_autoswitch.h +++ b/settings/settings_def_refresh_autoswitch.h @@ -4,6 +4,11 @@ * matches SDESC__ROW; row order is menu display order; * h2json.py parses these rows for the Crowdin source upload. */ +S_BOOL(video_refresh_rate_polled_auto, VIDEO_REFRESH_RATE_POLLED_AUTO, + "video_refresh_rate_polled_auto", + DEFAULT_VIDEO_REFRESH_RATE_POLLED_AUTO, SD_FLAG_NONE, 0, CMD_EVENT_NONE, + "Automatically Set Display-Reported Refresh Rate", + "Automatically set the Vertical Refresh Rate to the display-reported value. If Automatic Refresh Rate Switch is enabled, it takes precedence when using compatible fullscreen modes.") S_UINT_EX(video_autoswitch_refresh_rate, VIDEO_AUTOSWITCH_REFRESH_RATE, "video_autoswitch_refresh_rate", DEFAULT_AUTOSWITCH_REFRESH_RATE, SD_FLAG_NONE, SDESC_RANGE_MINMAX, CMD_EVENT_NONE, 0, AUTOSWITCH_REFRESH_RATE_LAST - 1, 1, 0, setting_action_ok_uint, setting_get_string_representation_uint_video_autoswitch_refresh_rate, NULL, NULL, NULL, NULL, ST_UI_TYPE_UINT_COMBOBOX, diff --git a/tools/settings_table.reference b/tools/settings_table.reference index 06a56846638d..abc7a0126725 100644 --- a/tools/settings_table.reference +++ b/tools/settings_table.reference @@ -158,6 +158,7 @@ bool log_to_file 1 0 bool log_to_file_timestamp 1 0 bool fastforward_frameskip 1 1 bool vrr_runloop_enable 1 0 +bool video_refresh_rate_polled_auto 1 0 bool wifi_enabled 1 1 bool history_list_enable 1 1 bool ozone_truncate_playlist_name 1 1 @@ -802,6 +803,7 @@ bool log_to_file 1 0 bool log_to_file_timestamp 1 0 bool fastforward_frameskip 1 1 bool vrr_runloop_enable 1 0 +bool video_refresh_rate_polled_auto 1 0 bool wifi_enabled 1 1 bool history_list_enable 1 1 bool ozone_truncate_playlist_name 1 1 @@ -1445,6 +1447,7 @@ bool log_to_file 1 0 bool log_to_file_timestamp 1 0 bool fastforward_frameskip 1 1 bool vrr_runloop_enable 1 0 +bool video_refresh_rate_polled_auto 1 0 bool wifi_enabled 1 1 bool history_list_enable 1 1 bool ozone_truncate_playlist_name 1 1