mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-27 02:00:41 +00:00
Move and relocate 'Frame Delay' (#15898)
This commit is contained in:
parent
e71a83e5c4
commit
f091b5a9e9
@ -4026,6 +4026,94 @@ void video_driver_reinit(int flags)
|
||||
video_st->window_title_prev[0] = '\0';
|
||||
}
|
||||
|
||||
void video_frame_delay(video_driver_state_t *video_st,
|
||||
settings_t *settings,
|
||||
bool core_paused)
|
||||
{
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
unsigned video_frame_delay = settings->uints.video_frame_delay;
|
||||
unsigned video_frame_delay_effective = video_st->frame_delay_effective;
|
||||
bool skip_delay = core_paused
|
||||
|| (runloop_st->flags & RUNLOOP_FLAG_SLOWMOTION)
|
||||
|| (runloop_st->flags & RUNLOOP_FLAG_FASTMOTION);
|
||||
|
||||
if (settings->bools.video_frame_delay_auto)
|
||||
{
|
||||
float refresh_rate = settings->floats.video_refresh_rate;
|
||||
uint8_t video_swap_interval = runloop_get_video_swap_interval(
|
||||
settings->uints.video_swap_interval);
|
||||
uint8_t video_bfi = settings->uints.video_black_frame_insertion;
|
||||
uint8_t frame_time_interval = 8;
|
||||
static uint8_t skip_update = 0;
|
||||
static bool skip_delay_prev = false;
|
||||
bool frame_time_update =
|
||||
/* Skip some initial frames for stabilization */
|
||||
video_st->frame_count > frame_time_interval
|
||||
/* Only update when there are enough frames for averaging */
|
||||
&& video_st->frame_count % frame_time_interval == 0;
|
||||
|
||||
/* A few frames must be ignored after slow+fastmotion/pause
|
||||
* is disabled or geometry change is triggered */
|
||||
if ( (!skip_delay && skip_delay_prev)
|
||||
|| video_st->frame_delay_pause)
|
||||
{
|
||||
skip_update = frame_time_interval * 4;
|
||||
video_st->frame_delay_pause = false;
|
||||
}
|
||||
|
||||
if (skip_update)
|
||||
skip_update--;
|
||||
|
||||
skip_delay_prev = skip_delay;
|
||||
|
||||
/* Always skip when slow+fastmotion/pause is active */
|
||||
if (skip_delay_prev)
|
||||
skip_update = 1;
|
||||
|
||||
if (skip_update)
|
||||
frame_time_update = false;
|
||||
|
||||
/* Black frame insertion + swap interval multiplier */
|
||||
refresh_rate = (refresh_rate / (video_bfi + 1.0f) / video_swap_interval);
|
||||
|
||||
/* Set target moderately as half frame time with 0 (Auto) delay */
|
||||
if (video_frame_delay == 0)
|
||||
video_frame_delay = 1 / refresh_rate * 1000 / 2;
|
||||
|
||||
/* Reset new desired delay target */
|
||||
if (video_st->frame_delay_target != video_frame_delay)
|
||||
{
|
||||
frame_time_update = false;
|
||||
video_st->frame_delay_target = video_frame_delay_effective = video_frame_delay;
|
||||
RARCH_LOG("[Video]: Frame delay reset to %d ms.\n", video_frame_delay);
|
||||
}
|
||||
|
||||
/* Decide what should happen to effective delay */
|
||||
if (video_frame_delay_effective > 0 && frame_time_update)
|
||||
{
|
||||
video_frame_delay_auto_t vfda = {0};
|
||||
vfda.frame_time_interval = frame_time_interval;
|
||||
vfda.refresh_rate = refresh_rate;
|
||||
|
||||
video_frame_delay_auto(video_st, &vfda);
|
||||
if (vfda.delay_decrease > 0)
|
||||
{
|
||||
video_frame_delay_effective -= vfda.delay_decrease;
|
||||
RARCH_LOG("[Video]: Frame delay decrease by %d ms to %d ms due to frame time average: %d > %d.\n",
|
||||
vfda.delay_decrease, video_frame_delay_effective, vfda.frame_time_avg, vfda.frame_time_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
video_st->frame_delay_target = video_frame_delay_effective = video_frame_delay;
|
||||
|
||||
video_st->frame_delay_effective = video_frame_delay_effective;
|
||||
|
||||
/* Never apply frame delay when slow+fastmotion/pause is active */
|
||||
if (video_frame_delay_effective > 0 && !skip_delay)
|
||||
retro_sleep(video_frame_delay_effective);
|
||||
}
|
||||
|
||||
void video_frame_delay_auto(video_driver_state_t *video_st, video_frame_delay_auto_t *vfda)
|
||||
{
|
||||
int i;
|
||||
|
@ -1090,6 +1090,10 @@ bool *video_driver_get_threaded(void);
|
||||
|
||||
void video_driver_set_threaded(bool val);
|
||||
|
||||
void video_frame_delay(video_driver_state_t *video_st,
|
||||
settings_t *settings,
|
||||
bool core_paused);
|
||||
|
||||
void video_frame_delay_auto(video_driver_state_t *video_st,
|
||||
video_frame_delay_auto_t *vfda);
|
||||
|
||||
|
92
runloop.c
92
runloop.c
@ -6807,8 +6807,6 @@ int runloop_iterate(void)
|
||||
#endif
|
||||
settings_t *settings = config_get_ptr();
|
||||
runloop_state_t *runloop_st = &runloop_state;
|
||||
unsigned video_frame_delay = settings->uints.video_frame_delay;
|
||||
unsigned video_frame_delay_effective = video_st->frame_delay_effective;
|
||||
bool vrr_runloop_enable = settings->bools.vrr_runloop_enable;
|
||||
unsigned max_users = settings->uints.input_max_users;
|
||||
retro_time_t current_time = cpu_features_get_time_usec();
|
||||
@ -7057,91 +7055,6 @@ int runloop_iterate(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Frame delay */
|
||||
if ( !(input_st->flags & INP_FLAG_NONBLOCKING)
|
||||
|| (runloop_st->flags & RUNLOOP_FLAG_FASTMOTION))
|
||||
{
|
||||
bool skip_delay = core_paused
|
||||
|| (runloop_st->flags & RUNLOOP_FLAG_SLOWMOTION)
|
||||
|| (runloop_st->flags & RUNLOOP_FLAG_FASTMOTION);
|
||||
|
||||
if (settings->bools.video_frame_delay_auto)
|
||||
{
|
||||
float refresh_rate = settings->floats.video_refresh_rate;
|
||||
uint8_t video_swap_interval = runloop_get_video_swap_interval(
|
||||
settings->uints.video_swap_interval);
|
||||
uint8_t video_bfi = settings->uints.video_black_frame_insertion;
|
||||
uint8_t frame_time_interval = 8;
|
||||
static uint8_t skip_update = 0;
|
||||
static bool skip_delay_prev = false;
|
||||
bool frame_time_update =
|
||||
/* Skip some initial frames for stabilization */
|
||||
video_st->frame_count > frame_time_interval
|
||||
/* Only update when there are enough frames for averaging */
|
||||
&& video_st->frame_count % frame_time_interval == 0;
|
||||
|
||||
/* A few frames must be ignored after slow+fastmotion/pause
|
||||
* is disabled or geometry change is triggered */
|
||||
if ( (!skip_delay && skip_delay_prev)
|
||||
|| video_st->frame_delay_pause)
|
||||
{
|
||||
skip_update = frame_time_interval * 4;
|
||||
video_st->frame_delay_pause = false;
|
||||
}
|
||||
|
||||
if (skip_update)
|
||||
skip_update--;
|
||||
|
||||
skip_delay_prev = skip_delay;
|
||||
|
||||
/* Always skip when slow+fastmotion/pause is active */
|
||||
if (skip_delay_prev)
|
||||
skip_update = 1;
|
||||
|
||||
if (skip_update)
|
||||
frame_time_update = false;
|
||||
|
||||
/* Black frame insertion + swap interval multiplier */
|
||||
refresh_rate = (refresh_rate / (video_bfi + 1.0f) / video_swap_interval);
|
||||
|
||||
/* Set target moderately as half frame time with 0 (Auto) delay */
|
||||
if (video_frame_delay == 0)
|
||||
video_frame_delay = 1 / refresh_rate * 1000 / 2;
|
||||
|
||||
/* Reset new desired delay target */
|
||||
if (video_st->frame_delay_target != video_frame_delay)
|
||||
{
|
||||
frame_time_update = false;
|
||||
video_st->frame_delay_target = video_frame_delay_effective = video_frame_delay;
|
||||
RARCH_LOG("[Video]: Frame delay reset to %d ms.\n", video_frame_delay);
|
||||
}
|
||||
|
||||
/* Decide what should happen to effective delay */
|
||||
if (video_frame_delay_effective > 0 && frame_time_update)
|
||||
{
|
||||
video_frame_delay_auto_t vfda = {0};
|
||||
vfda.frame_time_interval = frame_time_interval;
|
||||
vfda.refresh_rate = refresh_rate;
|
||||
|
||||
video_frame_delay_auto(video_st, &vfda);
|
||||
if (vfda.delay_decrease > 0)
|
||||
{
|
||||
video_frame_delay_effective -= vfda.delay_decrease;
|
||||
RARCH_LOG("[Video]: Frame delay decrease by %d ms to %d ms due to frame time average: %d > %d.\n",
|
||||
vfda.delay_decrease, video_frame_delay_effective, vfda.frame_time_avg, vfda.frame_time_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
video_st->frame_delay_target = video_frame_delay_effective = video_frame_delay;
|
||||
|
||||
video_st->frame_delay_effective = video_frame_delay_effective;
|
||||
|
||||
/* Never apply frame delay when slow+fastmotion/pause is active */
|
||||
if (video_frame_delay_effective > 0 && !skip_delay)
|
||||
retro_sleep(video_frame_delay_effective);
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef HAVE_RUNAHEAD
|
||||
bool run_ahead_enabled = settings->bools.run_ahead_enabled;
|
||||
@ -7225,6 +7138,11 @@ int runloop_iterate(void)
|
||||
autosave_unlock();
|
||||
#endif
|
||||
|
||||
/* Frame delay */
|
||||
if ( !(input_st->flags & INP_FLAG_NONBLOCKING)
|
||||
|| (runloop_st->flags & RUNLOOP_FLAG_FASTMOTION))
|
||||
video_frame_delay(video_st, settings, core_paused);
|
||||
|
||||
end:
|
||||
if (vrr_runloop_enable)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user