Add optional frame skipping when fast-forwarding (#13550)

This commit is contained in:
Tony 2022-01-26 19:30:33 +02:00 committed by GitHub
parent fa213a724f
commit 84f558db0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 73 additions and 8 deletions

View File

@ -1253,6 +1253,9 @@ static const bool savestate_thumbnail_enable = false;
/* Maximum fast forward ratio. */
#define DEFAULT_FASTFORWARD_RATIO 0.0
/* Skip frames when fast forwarding. */
#define DEFAULT_FASTFORWARD_FRAMESKIP true
/* Enable runloop for variable refresh rate screens. Force x1 speed while handling fast forward too. */
#define DEFAULT_VRR_RUNLOOP_ENABLE false

View File

@ -1654,6 +1654,7 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("ui_menubar_enable", &settings->bools.ui_menubar_enable, true, DEFAULT_UI_MENUBAR_ENABLE, false);
SETTING_BOOL("suspend_screensaver_enable", &settings->bools.ui_suspend_screensaver_enable, true, true, false);
SETTING_BOOL("rewind_enable", &settings->bools.rewind_enable, true, DEFAULT_REWIND_ENABLE, false);
SETTING_BOOL("fastforward_frameskip", &settings->bools.fastforward_frameskip, true, DEFAULT_FASTFORWARD_FRAMESKIP, false);
SETTING_BOOL("vrr_runloop_enable", &settings->bools.vrr_runloop_enable, true, DEFAULT_VRR_RUNLOOP_ENABLE, false);
SETTING_BOOL("apply_cheats_after_toggle", &settings->bools.apply_cheats_after_toggle, true, DEFAULT_APPLY_CHEATS_AFTER_TOGGLE, false);
SETTING_BOOL("apply_cheats_after_load", &settings->bools.apply_cheats_after_load, true, DEFAULT_APPLY_CHEATS_AFTER_LOAD, false);

View File

@ -834,6 +834,7 @@ typedef struct settings
bool history_list_enable;
bool playlist_entry_rename;
bool rewind_enable;
bool fastforward_frameskip;
bool vrr_runloop_enable;
bool apply_cheats_after_toggle;
bool apply_cheats_after_load;

View File

@ -3579,6 +3579,7 @@ void video_driver_frame(const void *data, unsigned width,
const enum retro_pixel_format
video_driver_pix_fmt = video_st->pix_fmt;
bool runloop_idle = runloop_st->idle;
bool render_frame = !runloop_st->fastforward_frameskip_frames_current;
bool video_driver_active = video_st->active;
#if defined(HAVE_GFX_WIDGETS)
bool widgets_active = dispwidget_get_ptr()->active;
@ -3617,6 +3618,11 @@ void video_driver_frame(const void *data, unsigned width,
video_driver_build_info(&video_info);
render_frame |= video_info.menu_is_alive;
if (!render_frame)
runloop_st->fastforward_frameskip_frames_current--;
/* Get the amount of frames per seconds. */
if (video_st->frame_count)
{
@ -3772,7 +3778,7 @@ void video_driver_frame(const void *data, unsigned width,
pitch, runloop_idle);
#ifdef HAVE_VIDEO_FILTER
if (data && video_st->state_filter)
if (render_frame && data && video_st->state_filter)
{
unsigned output_width = 0;
unsigned output_height = 0;
@ -3834,11 +3840,7 @@ void video_driver_frame(const void *data, unsigned width,
msg_entry.category,
msg_entry.prio,
false,
#ifdef HAVE_MENU
menu_state_get_ptr()->alive
#else
false
#endif
video_info.menu_is_alive
);
}
/* ...otherwise, just output message via
@ -3858,7 +3860,7 @@ void video_driver_frame(const void *data, unsigned width,
}
}
if (video_info.statistics_show)
if (render_frame && video_info.statistics_show)
{
audio_statistics_t audio_stats;
double stddev = 0.0;
@ -3920,13 +3922,17 @@ void video_driver_frame(const void *data, unsigned width,
/* TODO/FIXME - add OSD chat text here */
}
if (video_st->current_video && video_st->current_video->frame)
if (render_frame && video_st->current_video && video_st->current_video->frame)
{
video_st->active = video_st->current_video->frame(
video_st->data, data, width, height,
video_st->frame_count, (unsigned)pitch,
video_info.menu_screensaver_active || video_info.notifications_hidden ? "" : video_driver_msg,
&video_info);
runloop_st->fastforward_frameskip_frames_current = runloop_st->fastforward_frameskip_frames;
}
video_st->frame_count++;
/* Display the status text, with a higher priority. */

View File

@ -1234,6 +1234,10 @@ MSG_HASH(
MENU_ENUM_LABEL_FASTFORWARD_RATIO,
"fastforward_ratio"
)
MSG_HASH(
MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP,
"fastforward_frameskip"
)
MSG_HASH(
MENU_ENUM_LABEL_FILE_BROWSER_CORE,
"file_browser_core"

View File

@ -3460,6 +3460,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_FASTFORWARD_RATIO,
"The maximum rate at which content will be run when using fast-forward (e.g., 5.0x for 60 fps content = 300 fps cap). If set to 0.0x, fast-forward ratio is unlimited (no FPS cap)."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_FASTFORWARD_FRAMESKIP,
"Fast-Forward Frameskip"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_FASTFORWARD_FRAMESKIP,
"Skip frames according to fast-forward rate. This conserves power and allows the use of 3rd party frame limiting."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_SLOWMOTION_RATIO,
"Slow-Motion Rate"

View File

@ -494,6 +494,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_fastforward_frameskip, MENU_ENUM_SUBLABEL_FASTFORWARD_FRAMESKIP)
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)
@ -3409,6 +3410,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_FASTFORWARD_FRAMESKIP:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_fastforward_frameskip);
break;
case MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_vrr_runloop_enable);
break;

View File

@ -9393,6 +9393,7 @@ unsigned menu_displaylist_build_list(
#endif
{MENU_ENUM_LABEL_FRAME_TIME_COUNTER_SETTINGS, PARSE_ACTION},
{MENU_ENUM_LABEL_FASTFORWARD_RATIO, PARSE_ONLY_FLOAT},
{MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP, PARSE_ONLY_BOOL },
{MENU_ENUM_LABEL_SLOWMOTION_RATIO, PARSE_ONLY_FLOAT},
{MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, PARSE_ONLY_BOOL },
{MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, PARSE_ONLY_BOOL },

View File

@ -13950,6 +13950,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.fastforward_frameskip,
MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP,
MENU_ENUM_LABEL_VALUE_FASTFORWARD_FRAMESKIP,
DEFAULT_FASTFORWARD_FRAMESKIP,
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_BOOL(
list, list_info,
&settings->bools.vrr_runloop_enable,

View File

@ -1993,6 +1993,7 @@ enum msg_hash_enums
MENU_LABEL(OVERLAY_CENTER_Y),
MENU_LABEL(FASTFORWARD_RATIO),
MENU_LABEL(FASTFORWARD_FRAMESKIP),
MENU_LABEL(VRR_RUNLOOP_ENABLE),
MENU_LABEL(REWIND_ENABLE),
MENU_LABEL(CHEAT_APPLY_AFTER_TOGGLE),

View File

@ -4910,6 +4910,22 @@ static bool core_unload_game(void)
return true;
}
static void runloop_apply_fastmotion_frameskip(runloop_state_t *runloop_st, settings_t *settings)
{
unsigned frames = 0;
if (runloop_st->fastmotion && settings->bools.fastforward_frameskip)
{
frames = (unsigned)settings->floats.fastforward_ratio;
/* Pick refresh rate as unlimited throttle rate */
frames = (!frames) ? (unsigned)roundf(settings->floats.video_refresh_rate) : frames;
/* Decrease one to represent skipped frames */
frames--;
}
runloop_st->fastforward_frameskip_frames_current = runloop_st->fastforward_frameskip_frames = frames;
}
static void runloop_apply_fastmotion_override(runloop_state_t *runloop_st, settings_t *settings)
{
video_driver_state_t *video_st = video_state_get_ptr();
@ -4947,6 +4963,7 @@ static void runloop_apply_fastmotion_override(runloop_state_t *runloop_st, setti
if (!runloop_st->fastmotion)
runloop_st->fastforward_after_frames = 1;
runloop_apply_fastmotion_frameskip(runloop_st, settings);
driver_set_nonblock_state();
/* Reset frame time counter when toggling
@ -7063,6 +7080,7 @@ static enum runloop_state_enum runloop_check_state(
runloop_st->fastmotion = true;
}
runloop_apply_fastmotion_frameskip(runloop_st, settings);
driver_set_nonblock_state();
/* Reset frame time counter when toggling

View File

@ -216,6 +216,8 @@ struct runloop
unsigned max_frames;
unsigned audio_latency;
unsigned fastforward_after_frames;
unsigned fastforward_frameskip_frames;
unsigned fastforward_frameskip_frames_current;
unsigned perf_ptr_libretro;
unsigned subsystem_current_count;
unsigned entry_state_slot;