From bd4d4621709df521e8f480db14c101b407143132 Mon Sep 17 00:00:00 2001 From: Tatsuya79 Date: Sun, 5 Aug 2018 00:34:10 +0200 Subject: [PATCH] VRR runloop Option. --- config.def.h | 3 +++ configuration.c | 1 + configuration.h | 1 + intl/msg_hash_lbl.h | 2 ++ intl/msg_hash_us.c | 9 ++++++++- intl/msg_hash_us.h | 4 ++++ menu/cbs/menu_cbs_sublabel.c | 10 +++++++--- menu/menu_displaylist.c | 3 +++ menu/menu_setting.c | 16 ++++++++++++++++ msg_hash.h | 1 + retroarch.c | 35 ++++++++++++++++++++++++++++++++++- 11 files changed, 80 insertions(+), 5 deletions(-) diff --git a/config.def.h b/config.def.h index b0502d3488..f086b5de98 100644 --- a/config.def.h +++ b/config.def.h @@ -610,6 +610,9 @@ static const float slowmotion_ratio = 3.0; /* Maximum fast forward ratio. */ static const float fastforward_ratio = 0.0; +/* Enable runloop for variable refresh rate screens. Force x1 speed while handling fast forward too. */ +static const bool vrr_runloop_enable = false; + /* Run core logic one or more frames ahead then load the state back to reduce perceived input lag. */ static const unsigned run_ahead_frames = 1; diff --git a/configuration.c b/configuration.c index 5ab7b22edd..853a8e8563 100644 --- a/configuration.c +++ b/configuration.c @@ -1280,6 +1280,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("ui_menubar_enable", &settings->bools.ui_menubar_enable, true, true, false); SETTING_BOOL("suspend_screensaver_enable", &settings->bools.ui_suspend_screensaver_enable, true, true, false); SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, rewind_enable, false); + SETTING_BOOL("vrr_runloop_enable", &settings->bools.vrr_runloop_enable, true, vrr_runloop_enable, false); SETTING_BOOL("apply_cheats_after_toggle", &settings->bools.apply_cheats_after_toggle, true, apply_cheats_after_toggle, false); SETTING_BOOL("run_ahead_enabled", &settings->bools.run_ahead_enabled, true, false, false); SETTING_BOOL("run_ahead_secondary_instance", &settings->bools.run_ahead_secondary_instance, true, false, false); diff --git a/configuration.h b/configuration.h index dd0d930470..3265299fa4 100644 --- a/configuration.h +++ b/configuration.h @@ -239,6 +239,7 @@ typedef struct settings bool playlist_entry_remove; bool playlist_entry_rename; bool rewind_enable; + bool vrr_runloop_enable; bool apply_cheats_after_toggle; bool run_ahead_enabled; bool run_ahead_secondary_instance; diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 6b763f6c47..79948590ad 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -947,6 +947,8 @@ MSG_HASH(MENU_ENUM_LABEL_REWIND_BUFFER_SIZE_STEP, "rewind_buffer_size_step") MSG_HASH(MENU_ENUM_LABEL_REWIND_SETTINGS, "rewind_settings") +MSG_HASH(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, + "vrr_runloop_enable") MSG_HASH(MENU_ENUM_LABEL_CHEAT_SETTINGS, "cheat_settings") MSG_HASH(MENU_ENUM_LABEL_RGUI_BROWSER_DIRECTORY, diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index 41529f2284..b682d9ae96 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1237,7 +1237,7 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_FASTFORWARD_RATIO: snprintf(s, len, - "Fastforward ratio." + "Fastforward ratio.\n" " \n" "The maximum rate at which content will\n" "be run when using fast forward.\n" @@ -1250,6 +1250,13 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) "Do not rely on this cap to be perfectly \n" "accurate."); break; + case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE: + snprintf(s, len, + "VRR Runloop Mode.\n" + " \n" + "This option will force x1 speed \n" + "to ensure smooth scrolling."); + break; case MENU_ENUM_LABEL_VIDEO_MONITOR_INDEX: snprintf(s, len, "Which monitor to prefer.\n" diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index fdf7e53f45..cc4b6cf119 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -689,6 +689,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_FPS_SHOW, "Display Framerate") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_ENABLE, "Limit Maximum Run Speed") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, + "VRR Runloop (G-Sync, FreeSync Mode)") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRAME_THROTTLE_SETTINGS, "Frame Throttle") MSG_HASH(MENU_ENUM_LABEL_VALUE_FRONTEND_COUNTERS, @@ -3286,6 +3288,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_DISK_IMAGE_APPEND, "Select a disk image to insert.") MSG_HASH(MENU_ENUM_SUBLABEL_MENU_ENUM_THROTTLE_FRAMERATE, "Makes sure the framerate is capped while inside the menu.") +MSG_HASH(MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE, + "Force core requested timing for variable refresh rate screens.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_LAYOUT, "Select a different layout for the XMB interface.") MSG_HASH(MENU_ENUM_SUBLABEL_XMB_THEME, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index edccb8b17e..f4b808b729 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -200,6 +200,7 @@ default_sublabel_macro(action_bind_sublabel_video_gpu_record, MENU_ 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) default_sublabel_macro(action_bind_sublabel_fastforward_ratio, MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO) +default_sublabel_macro(action_bind_sublabel_vrr_runloop_enable, MENU_ENUM_SUBLABEL_VRR_RUNLOOP_ENABLE) default_sublabel_macro(action_bind_sublabel_slowmotion_ratio, MENU_ENUM_SUBLABEL_SLOWMOTION_RATIO) default_sublabel_macro(action_bind_sublabel_run_ahead_enabled, MENU_ENUM_SUBLABEL_RUN_AHEAD_ENABLED) default_sublabel_macro(action_bind_sublabel_run_ahead_secondary_instance, MENU_ENUM_SUBLABEL_RUN_AHEAD_SECONDARY_INSTANCE) @@ -371,9 +372,9 @@ default_sublabel_macro(action_bind_sublabel_quick_menu_show_options, default_sublabel_macro(action_bind_sublabel_quick_menu_show_controls, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CONTROLS) default_sublabel_macro(action_bind_sublabel_quick_menu_show_cheats, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_CHEATS) default_sublabel_macro(action_bind_sublabel_quick_menu_show_shaders, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SHADERS) -default_sublabel_macro(action_bind_sublabel_content_show_overlays, MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS) -default_sublabel_macro(action_bind_sublabel_content_show_rewind, MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND) -default_sublabel_macro(action_bind_sublabel_content_show_latency, MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY) +default_sublabel_macro(action_bind_sublabel_content_show_overlays, MENU_ENUM_SUBLABEL_CONTENT_SHOW_OVERLAYS) +default_sublabel_macro(action_bind_sublabel_content_show_rewind, MENU_ENUM_SUBLABEL_CONTENT_SHOW_REWIND) +default_sublabel_macro(action_bind_sublabel_content_show_latency, MENU_ENUM_SUBLABEL_CONTENT_SHOW_LATENCY) default_sublabel_macro(action_bind_sublabel_quick_menu_show_save_core_overrides, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_CORE_OVERRIDES) default_sublabel_macro(action_bind_sublabel_quick_menu_show_save_game_overrides, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_SAVE_GAME_OVERRIDES) default_sublabel_macro(action_bind_sublabel_quick_menu_show_information, MENU_ENUM_SUBLABEL_QUICK_MENU_SHOW_INFORMATION) @@ -1489,6 +1490,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_FASTFORWARD_RATIO: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_fastforward_ratio); break; + case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_vrr_runloop_enable); + break; case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_block_sram_overwrite); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 1c5cb1d006..726b0fa29e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5134,6 +5134,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_SLOWMOTION_RATIO, PARSE_ONLY_FLOAT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, + PARSE_ONLY_BOOL, false); { settings_t *settings = config_get_ptr(); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index b2d84ee582..e81bc9215c 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5377,6 +5377,22 @@ static bool setting_append_list( menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_SET_FRAME_LIMIT); menu_settings_list_current_add_range(list, list_info, 0, 10, 1.0, true, true); + CONFIG_BOOL( + list, list_info, + &settings->bools.vrr_runloop_enable, + MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, + MENU_ENUM_LABEL_VALUE_VRR_RUNLOOP_ENABLE, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + CONFIG_FLOAT( list, list_info, &settings->floats.slowmotion_ratio, diff --git a/msg_hash.h b/msg_hash.h index f5adeca60b..b4e3d047fb 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1311,6 +1311,7 @@ enum msg_hash_enums MENU_LABEL(OVERLAY_OPACITY), MENU_LABEL(FASTFORWARD_RATIO), + MENU_LABEL(VRR_RUNLOOP_ENABLE), MENU_LABEL(REWIND_ENABLE), MENU_LABEL(CHEAT_APPLY_AFTER_TOGGLE), diff --git a/retroarch.c b/retroarch.c index 6ec4ddf508..b6b52ee357 100644 --- a/retroarch.c +++ b/retroarch.c @@ -262,6 +262,7 @@ static msg_queue_t *runloop_msg_queue = NULL; static unsigned runloop_pending_windowed_scale = 0; static unsigned runloop_max_frames = 0; +static unsigned fastforward_after_frames = 0; static retro_usec_t runloop_frame_time_last = 0; static retro_time_t frame_limit_minimum_time = 0.0; @@ -2971,6 +2972,7 @@ static enum runloop_state runloop_check_state( { input_driver_unset_nonblock_state(); runloop_fastmotion = false; + fastforward_after_frames = 1; } else { @@ -2990,6 +2992,7 @@ static enum runloop_state runloop_check_state( { input_driver_unset_nonblock_state(); runloop_fastmotion = false; + fastforward_after_frames = 1; } driver_set_nonblock_state(); } @@ -3438,9 +3441,39 @@ int runloop_iterate(unsigned *sleep_ms) if (runloop_autosave) autosave_unlock(); - if (settings->floats.fastforward_ratio) + /* Condition for max speed x0.0 when vrr_runloop is off to skip that part */ + if (settings->floats.fastforward_ratio || settings->bools.vrr_runloop_enable) end: { + if (settings->bools.vrr_runloop_enable) + { + struct retro_system_av_info *av_info = + video_viewport_get_system_av_info(); + + /* Sync on video only, block audio later. */ + if (fastforward_after_frames && settings->bools.audio_sync) + { + if (fastforward_after_frames == 1) + command_event(CMD_EVENT_AUDIO_SET_NONBLOCKING_STATE, NULL); + + fastforward_after_frames++; + + if (fastforward_after_frames == 6) + { + command_event(CMD_EVENT_AUDIO_SET_BLOCKING_STATE, NULL); + fastforward_after_frames = 0; + } + } + + /* Fast Forward for max speed x0.0 */ + if (!settings->floats.fastforward_ratio && runloop_fastmotion) + return 0; + + frame_limit_minimum_time = + (retro_time_t)roundf(1000000.0f / (av_info->timing.fps * + (runloop_fastmotion ? settings->floats.fastforward_ratio : 1.0f))); + } + retro_time_t to_sleep_ms = ( (frame_limit_last_time + frame_limit_minimum_time) - cpu_features_get_time_usec()) / 1000;