mirror of
https://github.com/libretro/RetroArch
synced 2025-02-06 09:40:06 +00:00
Add 'Frame Rest' power saving option (#15834)
This commit is contained in:
parent
4f8e3fabad
commit
da59b8c9ac
@ -391,6 +391,9 @@
|
||||
#define MAXIMUM_FRAME_DELAY 19
|
||||
#define DEFAULT_FRAME_DELAY_AUTO false
|
||||
|
||||
/* Try to sleep the spare time after frame is presented in order to reduce vsync CPU usage. */
|
||||
#define DEFAULT_FRAME_REST false
|
||||
|
||||
/* Inserts black frame(s) inbetween frames.
|
||||
* Useful for Higher Hz monitors (set to multiples of 60 Hz) who want to play 60 Hz
|
||||
* material with eliminated ghosting. video_refresh_rate should still be configured
|
||||
|
@ -1810,6 +1810,7 @@ static struct config_bool_setting *populate_settings_bool(
|
||||
SETTING_BOOL("video_ctx_scaling", &settings->bools.video_ctx_scaling, true, DEFAULT_VIDEO_CTX_SCALING, false);
|
||||
SETTING_BOOL("video_force_aspect", &settings->bools.video_force_aspect, true, DEFAULT_FORCE_ASPECT, false);
|
||||
SETTING_BOOL("video_frame_delay_auto", &settings->bools.video_frame_delay_auto, true, DEFAULT_FRAME_DELAY_AUTO, false);
|
||||
SETTING_BOOL("video_frame_rest", &settings->bools.video_frame_rest, true, DEFAULT_FRAME_REST, false);
|
||||
#if defined(DINGUX)
|
||||
SETTING_BOOL("video_dingux_ipu_keep_aspect", &settings->bools.video_dingux_ipu_keep_aspect, true, DEFAULT_DINGUX_IPU_KEEP_ASPECT, false);
|
||||
#endif
|
||||
|
@ -578,6 +578,7 @@ typedef struct settings
|
||||
bool video_ctx_scaling;
|
||||
bool video_force_aspect;
|
||||
bool video_frame_delay_auto;
|
||||
bool video_frame_rest;
|
||||
bool video_crop_overscan;
|
||||
bool video_aspect_ratio_auto;
|
||||
bool video_dingux_ipu_keep_aspect;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <retro_inline.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <retro_math.h>
|
||||
#include <retro_timers.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -67,6 +68,7 @@
|
||||
#define TIME_TO_FPS(last_time, new_time, frames) ((1000000.0f * (frames)) / ((new_time) - (last_time)))
|
||||
|
||||
#define FRAME_DELAY_AUTO_DEBUG 0
|
||||
#define FRAME_REST_DEBUG 0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -527,27 +529,27 @@ video_driver_t *hw_render_context_driver(
|
||||
#endif
|
||||
case RETRO_HW_CONTEXT_D3D10:
|
||||
#if defined(HAVE_D3D10)
|
||||
return &video_d3d10;
|
||||
return &video_d3d10;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case RETRO_HW_CONTEXT_D3D11:
|
||||
#if defined(HAVE_D3D11)
|
||||
return &video_d3d11;
|
||||
return &video_d3d11;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case RETRO_HW_CONTEXT_D3D12:
|
||||
#if defined(HAVE_D3D12)
|
||||
return &video_d3d12;
|
||||
return &video_d3d12;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
case RETRO_HW_CONTEXT_D3D9:
|
||||
#if defined(HAVE_D3D9) && defined(HAVE_HLSL)
|
||||
return &video_d3d9_hlsl;
|
||||
return &video_d3d9_hlsl;
|
||||
#else
|
||||
break;
|
||||
break;
|
||||
#endif
|
||||
case RETRO_HW_CONTEXT_VULKAN:
|
||||
#if defined(HAVE_VULKAN)
|
||||
@ -2641,6 +2643,7 @@ void video_driver_build_info(video_frame_info_t *video_info)
|
||||
video_info->runloop_is_paused = (runloop_st->flags & RUNLOOP_FLAG_PAUSED) ? true : false;
|
||||
video_info->runloop_is_slowmotion = (runloop_st->flags & RUNLOOP_FLAG_SLOWMOTION) ? true : false;
|
||||
video_info->fastforward_frameskip = settings->bools.fastforward_frameskip;
|
||||
video_info->frame_rest = settings->bools.video_frame_rest;
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_VULKAN
|
||||
@ -3749,6 +3752,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
if (render_frame && video_info.statistics_show)
|
||||
{
|
||||
audio_statistics_t audio_stats;
|
||||
char throttle_stats[128];
|
||||
char latency_stats[128];
|
||||
char tmp[128];
|
||||
size_t len;
|
||||
@ -3796,9 +3800,27 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
|
||||
audio_compute_buffer_statistics(&audio_stats);
|
||||
|
||||
latency_stats[0] = '\0';
|
||||
tmp[0] = '\0';
|
||||
len = 0;
|
||||
throttle_stats[0] = '\0';
|
||||
latency_stats[0] = '\0';
|
||||
tmp[0] = '\0';
|
||||
len = 0;
|
||||
|
||||
if (video_info.frame_rest)
|
||||
len = snprintf(tmp + len, sizeof(throttle_stats),
|
||||
" Frame Rest: %2u.00 ms\n"
|
||||
" - Rested: %5.2f %%\n",
|
||||
video_st->frame_rest,
|
||||
(float)video_st->frame_rest_time_count / runloop_st->core_runtime_usec * 100);
|
||||
|
||||
if (len)
|
||||
{
|
||||
/* TODO/FIXME - localize */
|
||||
size_t _len = strlcpy(throttle_stats, "THROTTLE\n", sizeof(throttle_stats));
|
||||
strlcpy(throttle_stats + _len, tmp, sizeof(throttle_stats) - _len);
|
||||
}
|
||||
|
||||
tmp[0] = '\0';
|
||||
len = 0;
|
||||
|
||||
/* TODO/FIXME - localize */
|
||||
if (video_st->frame_delay_target > 0)
|
||||
@ -3826,9 +3848,9 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
|
||||
if (len)
|
||||
{
|
||||
/* TODO/FIXME - localize */
|
||||
size_t _len = strlcpy(latency_stats, "LATENCY\n", sizeof(latency_stats));
|
||||
strlcpy(latency_stats + _len, tmp, sizeof(latency_stats) - _len);
|
||||
/* TODO/FIXME - localize */
|
||||
size_t _len = strlcpy(latency_stats, "LATENCY\n", sizeof(latency_stats));
|
||||
strlcpy(latency_stats + _len, tmp, sizeof(latency_stats) - _len);
|
||||
}
|
||||
|
||||
/* TODO/FIXME - localize */
|
||||
@ -3853,6 +3875,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
" Underrun: %5.2f %%\n"
|
||||
" Blocking: %5.2f %%\n"
|
||||
" Samples: %5d\n"
|
||||
"%s"
|
||||
"%s",
|
||||
av_info->geometry.base_width,
|
||||
av_info->geometry.base_height,
|
||||
@ -3875,6 +3898,7 @@ void video_driver_frame(const void *data, unsigned width,
|
||||
audio_stats.close_to_underrun,
|
||||
audio_stats.close_to_blocking,
|
||||
audio_stats.samples,
|
||||
throttle_stats,
|
||||
latency_stats);
|
||||
|
||||
/* TODO/FIXME - add OSD chat text here */
|
||||
@ -4173,3 +4197,128 @@ void video_frame_delay_auto(video_driver_state_t *video_st, video_frame_delay_au
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_frame_rest(video_driver_state_t *video_st,
|
||||
settings_t *settings,
|
||||
retro_time_t current_time)
|
||||
{
|
||||
#ifdef HAVE_MENU
|
||||
bool menu_is_pausing = settings->bools.menu_pause_libretro && (menu_state_get_ptr()->flags & MENU_ST_FLAG_ALIVE);
|
||||
#else
|
||||
bool menu_is_pausing = false;
|
||||
#endif
|
||||
runloop_state_t *runloop_st = runloop_state_get_ptr();
|
||||
retro_time_t latest_time = cpu_features_get_time_usec();
|
||||
retro_time_t frame_time_delta = latest_time - current_time;
|
||||
retro_time_t frame_time_target = 1000000.0f / settings->floats.video_refresh_rate;
|
||||
retro_time_t frame_time = 0;
|
||||
static retro_time_t after_present = 0;
|
||||
int sleep_max = frame_time_target / 1000 / 2;
|
||||
int sleep = 0;
|
||||
int frame_time_near_req_count = ceil(settings->floats.video_refresh_rate / 2);
|
||||
static int frame_time_over_count = 0;
|
||||
static int frame_time_near_count = 0;
|
||||
static int frame_time_try_count = 0;
|
||||
double video_stddev = 0;
|
||||
audio_statistics_t audio_stats;
|
||||
|
||||
/* Must require video and audio deviation standards */
|
||||
video_monitor_fps_statistics(NULL, &video_stddev, NULL);
|
||||
audio_compute_buffer_statistics(&audio_stats);
|
||||
|
||||
/* Don't care about deviations when core is not running */
|
||||
if ( (runloop_st->flags & RUNLOOP_FLAG_PAUSED)
|
||||
|| !(runloop_st->flags & RUNLOOP_FLAG_CORE_RUNNING)
|
||||
|| menu_is_pausing)
|
||||
video_stddev = audio_stats.std_deviation_percentage = 0;
|
||||
|
||||
/* Compare to previous timestamp */
|
||||
frame_time = latest_time - after_present;
|
||||
|
||||
/* Count running timers */
|
||||
if (frame_time > frame_time_target)
|
||||
frame_time_over_count++;
|
||||
else if (frame_time < frame_time_target)
|
||||
frame_time_over_count--;
|
||||
|
||||
if (labs(frame_time - frame_time_target) < frame_time_target * 1.002f - frame_time_target)
|
||||
frame_time_near_count++;
|
||||
else
|
||||
frame_time_near_count--;
|
||||
|
||||
/* Take new timestamp */
|
||||
after_present = latest_time;
|
||||
|
||||
/* Ignore unreasonable frame times */
|
||||
if ( frame_time < frame_time_target / 2
|
||||
|| frame_time > frame_time_target * 2)
|
||||
return;
|
||||
|
||||
/* Carry the extra */
|
||||
frame_time_delta -= frame_time_target - frame_time;
|
||||
sleep = (frame_time_delta > 0) ? frame_time_delta : 0;
|
||||
|
||||
/* No rest with bogus values */
|
||||
if ( sleep < 0
|
||||
|| ( frame_time_target < frame_time_delta
|
||||
&& frame_time_target < frame_time))
|
||||
sleep = 0;
|
||||
|
||||
/* Reset over the target counter */
|
||||
if (!sleep)
|
||||
frame_time_over_count = 0;
|
||||
|
||||
frame_time_try_count++;
|
||||
if ( frame_time_try_count > frame_time_near_req_count * 2
|
||||
|| frame_time_try_count < frame_time_near_count)
|
||||
frame_time_over_count = frame_time_near_count = frame_time_try_count = 0;
|
||||
|
||||
/* Increase */
|
||||
if (sleep
|
||||
&& (frame_time_over_count < 2)
|
||||
&& (video_stddev * 100.0f < 25.00f)
|
||||
&& (audio_stats.std_deviation_percentage < 25.00f)
|
||||
&& (frame_time_near_count > frame_time_try_count / 2)
|
||||
&& (frame_time_near_count > frame_time_near_req_count)
|
||||
)
|
||||
{
|
||||
#if FRAME_REST_DEBUG
|
||||
RARCH_LOG("+ frame=%5d delta=%5d sleep=%2d over=%3d near=%3d try=%3d\n", frame_time, frame_time_delta, video_st->frame_rest, frame_time_over_count, frame_time_near_count, frame_time_try_count);
|
||||
#endif
|
||||
video_st->frame_rest++;
|
||||
frame_time_over_count = frame_time_near_count = frame_time_try_count = 0;
|
||||
}
|
||||
/* Decrease */
|
||||
else if ( sleep
|
||||
&& frame_time_over_count != 0
|
||||
&& frame_time_try_count > 10
|
||||
&& ( (frame_time_near_count < -2 && -frame_time_near_count > frame_time_try_count)
|
||||
|| (frame_time_over_count > frame_time_near_req_count / 2)
|
||||
|| (frame_time_over_count < -(frame_time_near_req_count / 2))
|
||||
)
|
||||
)
|
||||
{
|
||||
#if FRAME_REST_DEBUG
|
||||
RARCH_LOG("- frame=%5d delta=%5d sleep=%2d over=%3d near=%3d try=%3d\n", frame_time, frame_time_delta, video_st->frame_rest, frame_time_over_count, frame_time_near_count, frame_time_try_count);
|
||||
#endif
|
||||
if (video_st->frame_rest)
|
||||
video_st->frame_rest--;
|
||||
frame_time_over_count = frame_time_near_count = frame_time_try_count = 0;
|
||||
}
|
||||
|
||||
/* Limit to maximum sleep */
|
||||
if (video_st->frame_rest > sleep_max)
|
||||
video_st->frame_rest = sleep_max;
|
||||
|
||||
#if FRAME_REST_DEBUG
|
||||
RARCH_LOG(" frame=%5d delta=%5d sleep=%2d over=%3d near=%3d try=%3d %f %f\n", frame_time, frame_time_delta, video_st->frame_rest, frame_time_over_count, frame_time_near_count, frame_time_try_count, video_stddev, audio_stats.std_deviation_percentage);
|
||||
#endif
|
||||
|
||||
/* Do what is promised and add to statistics */
|
||||
if (video_st->frame_rest > 0)
|
||||
{
|
||||
if (!menu_is_pausing)
|
||||
video_st->frame_rest_time_count += video_st->frame_rest * 1000;
|
||||
retro_sleep(video_st->frame_rest);
|
||||
}
|
||||
}
|
||||
|
@ -482,6 +482,7 @@ typedef struct video_frame_info
|
||||
bool runloop_is_slowmotion;
|
||||
bool runloop_is_paused;
|
||||
bool fastforward_frameskip;
|
||||
bool frame_rest;
|
||||
bool msg_bgcolor_enable;
|
||||
bool crt_switch_hires_menu;
|
||||
bool hdr_enable;
|
||||
@ -774,6 +775,7 @@ typedef struct
|
||||
retro_time_t frame_time_samples[MEASURE_FRAME_TIME_SAMPLES_COUNT];
|
||||
uint64_t frame_time_count;
|
||||
uint64_t frame_count;
|
||||
uint64_t frame_rest_time_count;
|
||||
uint8_t *record_gpu_buffer;
|
||||
#ifdef HAVE_VIDEO_FILTER
|
||||
rarch_softfilter_t *state_filter;
|
||||
@ -859,6 +861,7 @@ typedef struct
|
||||
char title_buf[64];
|
||||
char cached_driver_id[32];
|
||||
|
||||
uint8_t frame_rest;
|
||||
uint8_t frame_delay_target;
|
||||
uint8_t frame_delay_effective;
|
||||
bool frame_delay_pause;
|
||||
@ -1087,7 +1090,12 @@ bool *video_driver_get_threaded(void);
|
||||
|
||||
void video_driver_set_threaded(bool val);
|
||||
|
||||
void video_frame_delay_auto(video_driver_state_t *video_st, video_frame_delay_auto_t *vfda);
|
||||
void video_frame_delay_auto(video_driver_state_t *video_st,
|
||||
video_frame_delay_auto_t *vfda);
|
||||
|
||||
void video_frame_rest(video_driver_state_t *video_st,
|
||||
settings_t *settings,
|
||||
retro_time_t current_time);
|
||||
|
||||
/**
|
||||
* video_context_driver_init:
|
||||
|
@ -4216,6 +4216,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VIDEO_FRAME_DELAY_AUTO,
|
||||
"video_frame_delay_auto"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VIDEO_FRAME_REST,
|
||||
"video_frame_rest"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VIDEO_SHADER_DELAY,
|
||||
"video_shader_delay"
|
||||
|
@ -15430,6 +15430,14 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_HELP_GAMEMODE_ENABLE,
|
||||
"Enabling Linux GameMode can improve latency, fix audio crackling issues and maximize overall performance by automatically configuring your CPU and GPU for best performance.\nThe GameMode software needs to be installed for this to work. See https://github.com/FeralInteractive/gamemode for information on how to install GameMode."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_REST,
|
||||
"Frame Rest"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_VIDEO_FRAME_REST,
|
||||
"Try to reduce vsync CPU usage by sleeping as much as possible after frame presentation. Designed primarily for third party scanline sync."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_PAL60_ENABLE,
|
||||
"Use PAL60 Mode"
|
||||
|
@ -1232,6 +1232,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_gamemode_enable, MENU
|
||||
#endif
|
||||
#endif /*HAVE_LAKKA*/
|
||||
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_video_frame_rest, MENU_ENUM_SUBLABEL_VIDEO_FRAME_REST)
|
||||
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_brightness_control, MENU_ENUM_SUBLABEL_BRIGHTNESS_CONTROL)
|
||||
|
||||
#ifdef _3DS
|
||||
@ -5225,6 +5226,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_gamemode_enable);
|
||||
break;
|
||||
#endif /*HAVE_LAKKA*/
|
||||
case MENU_ENUM_LABEL_VIDEO_FRAME_REST:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_video_frame_rest);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_BRIGHTNESS_CONTROL:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_brightness_control);
|
||||
break;
|
||||
|
@ -1981,6 +1981,7 @@ static uintptr_t ozone_entries_icon_get_texture(
|
||||
case MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_LATENCY:
|
||||
case MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE:
|
||||
case MENU_ENUM_LABEL_VIDEO_FRAME_REST:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_LATENCY];
|
||||
case MENU_ENUM_LABEL_SAVING_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_SAVING:
|
||||
@ -2003,6 +2004,7 @@ static uintptr_t ozone_entries_icon_get_texture(
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_RATIO:
|
||||
case MENU_ENUM_LABEL_FRAME_THROTTLE_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_FRAME_THROTTLE:
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_FRAMESKIP];
|
||||
case MENU_ENUM_LABEL_QUICK_MENU_START_RECORDING:
|
||||
case MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING:
|
||||
@ -2059,7 +2061,6 @@ static uintptr_t ozone_entries_icon_get_texture(
|
||||
#endif
|
||||
case MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_POWER_MANAGEMENT:
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP:
|
||||
return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_POWER];
|
||||
case MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_ACHIEVEMENTS:
|
||||
|
@ -3183,6 +3183,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
case MENU_ENUM_LABEL_CONTENT_SHOW_LATENCY:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_LATENCY:
|
||||
case MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE:
|
||||
case MENU_ENUM_LABEL_VIDEO_FRAME_REST:
|
||||
return xmb->textures.list[XMB_TEXTURE_LATENCY];
|
||||
case MENU_ENUM_LABEL_SAVING_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_SAVING:
|
||||
@ -3205,6 +3206,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_RATIO:
|
||||
case MENU_ENUM_LABEL_FRAME_THROTTLE_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_FRAME_THROTTLE:
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP:
|
||||
return xmb->textures.list[XMB_TEXTURE_FRAMESKIP];
|
||||
case MENU_ENUM_LABEL_QUICK_MENU_START_RECORDING:
|
||||
case MENU_ENUM_LABEL_QUICK_MENU_SHOW_START_RECORDING:
|
||||
@ -3261,7 +3263,6 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb,
|
||||
#endif
|
||||
case MENU_ENUM_LABEL_POWER_MANAGEMENT_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_POWER_MANAGEMENT:
|
||||
case MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP:
|
||||
return xmb->textures.list[XMB_TEXTURE_POWER];
|
||||
case MENU_ENUM_LABEL_RETRO_ACHIEVEMENTS_SETTINGS:
|
||||
case MENU_ENUM_LABEL_SETTINGS_SHOW_ACHIEVEMENTS:
|
||||
|
@ -10434,6 +10434,8 @@ unsigned menu_displaylist_build_list(
|
||||
case DISPLAYLIST_POWER_MANAGEMENT_SETTINGS_LIST:
|
||||
{
|
||||
menu_displaylist_build_info_t build_list[] = {
|
||||
{MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_VIDEO_FRAME_REST, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_SUSTAINED_PERFORMANCE_MODE, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_CPU_PERFPOWER, PARSE_ACTION},
|
||||
#ifdef HAVE_LAKKA
|
||||
@ -10915,7 +10917,8 @@ unsigned menu_displaylist_build_list(
|
||||
{MENU_ENUM_LABEL_FASTFORWARD_FRAMESKIP, PARSE_ONLY_BOOL, true},
|
||||
{MENU_ENUM_LABEL_SLOWMOTION_RATIO, PARSE_ONLY_FLOAT, true},
|
||||
{MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE, PARSE_ONLY_BOOL, true},
|
||||
{MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, PARSE_ONLY_BOOL , true},
|
||||
{MENU_ENUM_LABEL_MENU_THROTTLE_FRAMERATE, PARSE_ONLY_BOOL, true},
|
||||
{MENU_ENUM_LABEL_VIDEO_FRAME_REST, PARSE_ONLY_BOOL, true},
|
||||
};
|
||||
|
||||
#ifdef HAVE_REWIND
|
||||
|
@ -19154,6 +19154,21 @@ static bool setting_append_list(
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.video_frame_rest,
|
||||
MENU_ENUM_LABEL_VIDEO_FRAME_REST,
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_FRAME_REST,
|
||||
DEFAULT_FRAME_REST,
|
||||
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);
|
||||
|
||||
END_SUB_GROUP(list, list_info, parent_group);
|
||||
END_GROUP(list, list_info, parent_group);
|
||||
break;
|
||||
|
@ -3818,6 +3818,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(CPU_MANAGED_MAX_FREQ),
|
||||
MENU_LBL_H(GAMEMODE_ENABLE),
|
||||
MENU_ENUM_SUBLABEL_GAMEMODE_ENABLE_LINUX,
|
||||
MENU_LABEL(VIDEO_FRAME_REST),
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_CPU_PERF_MODE_MANAGED_PERF,
|
||||
MENU_ENUM_LABEL_VALUE_CPU_PERF_MODE_MANAGED_PER_CONTEXT,
|
||||
|
10
runloop.c
10
runloop.c
@ -4083,10 +4083,15 @@ void runloop_event_deinit_core(void)
|
||||
av_info->timing.fps = video_st->video_refresh_rate_original;
|
||||
video_display_server_restore_refresh_rate();
|
||||
}
|
||||
|
||||
/* Recalibrate frame delay target */
|
||||
if (settings->bools.video_frame_delay_auto)
|
||||
video_st->frame_delay_target = 0;
|
||||
|
||||
/* Reset frame rest counter */
|
||||
if (settings->bools.video_frame_rest)
|
||||
video_st->frame_rest_time_count = video_st->frame_rest = 0;
|
||||
|
||||
driver_uninit(DRIVERS_CMD_ALL, 0);
|
||||
|
||||
#ifdef HAVE_CONFIGFILE
|
||||
@ -7289,6 +7294,11 @@ end:
|
||||
runloop_st->frame_limit_last_time = end_frame_time;
|
||||
}
|
||||
|
||||
/* Post-frame power saving sleep resting */
|
||||
if ( settings->bools.video_frame_rest
|
||||
&& !(input_st->flags & INP_FLAG_NONBLOCKING))
|
||||
video_frame_rest(video_st, settings, current_time);
|
||||
|
||||
/* Set paused state after x frames */
|
||||
if (runloop_st->run_frames_and_pause > 0)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user