mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 13:14:04 +00:00
Merge pull request #12795 from sonninnos/video-rate-switch
Automatic PAL/NTSC refresh rate switch where available
This commit is contained in:
commit
cfcd0a7a0d
@ -1931,8 +1931,7 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use,
|
||||
* for black frame insertion using video_refresh_rate set to a portion
|
||||
* of the display refresh rate, as well as higher vsync swap intervals. */
|
||||
float refresh_mod = bfi + 1.0f;
|
||||
unsigned refresh = roundf(video_refresh * refresh_mod
|
||||
* swap_interval);
|
||||
float refresh_rate = (video_refresh * refresh_mod * swap_interval);
|
||||
|
||||
if (windowed_full)
|
||||
{
|
||||
@ -1945,7 +1944,7 @@ void win32_set_style(MONITORINFOEX *current_mon, HMONITOR *hm_to_use,
|
||||
*style = WS_POPUP | WS_VISIBLE;
|
||||
|
||||
if (!win32_monitor_set_fullscreen(*width, *height,
|
||||
refresh, current_mon->szDevice)) { }
|
||||
(int)refresh_rate, current_mon->szDevice)) { }
|
||||
|
||||
/* Display settings might have changed, get new coordinates. */
|
||||
GetMonitorInfo(*hm_to_use, (LPMONITORINFO)current_mon);
|
||||
|
@ -239,7 +239,7 @@ static bool win32_display_server_set_resolution(void *data,
|
||||
if (serv->orig_height == 0)
|
||||
serv->orig_height = GetSystemMetrics(SM_CYSCREEN);
|
||||
if (serv->orig_refresh == 0)
|
||||
serv->orig_refresh = dm.dmDisplayFrequency;
|
||||
serv->orig_refresh = video_driver_get_refresh_rate();
|
||||
|
||||
/* Used to stop super resolution bug */
|
||||
if (width == dm.dmPelsWidth)
|
||||
|
@ -87,6 +87,12 @@ bool video_display_server_can_set_screen_orientation(void);
|
||||
|
||||
bool video_display_server_has_resolution_list(void);
|
||||
|
||||
bool video_display_server_set_refresh_rate(float hz);
|
||||
|
||||
bool video_display_server_has_refresh_rate(float hz);
|
||||
|
||||
void video_display_server_restore_refresh_rate(void);
|
||||
|
||||
enum rotation video_display_server_get_screen_orientation(void);
|
||||
|
||||
extern const video_display_server_t dispserv_win32;
|
||||
|
121
retroarch.c
121
retroarch.c
@ -9424,6 +9424,11 @@ static void command_event_deinit_core(
|
||||
uninit_libretro_symbols(p_rarch, &p_rarch->current_core);
|
||||
p_rarch->current_core.symbols_inited = false;
|
||||
|
||||
/* Restore original refresh rate, if it has been changed
|
||||
* automatically in SET_SYSTEM_AV_INFO */
|
||||
if (p_rarch->video_refresh_rate_original)
|
||||
video_display_server_restore_refresh_rate();
|
||||
|
||||
if (reinit)
|
||||
driver_uninit(p_rarch, DRIVERS_CMD_ALL);
|
||||
|
||||
@ -14428,13 +14433,67 @@ static bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
if (data)
|
||||
{
|
||||
settings_t *settings = p_rarch->configuration_settings;
|
||||
float refresh_rate = (*info)->timing.fps;
|
||||
unsigned crt_switch_resolution = settings->uints.crt_switch_resolution;
|
||||
bool video_fullscreen = settings->bools.video_fullscreen;
|
||||
const bool no_video_reinit = (
|
||||
bool video_has_resolution_list = video_display_server_has_resolution_list();
|
||||
bool video_switch_refresh_rate = false;
|
||||
bool no_video_reinit = true;
|
||||
|
||||
/* Refresh rate switch for regular displays */
|
||||
if (video_has_resolution_list)
|
||||
{
|
||||
float refresh_mod = 0.0f;
|
||||
float video_refresh_rate = settings->floats.video_refresh_rate;
|
||||
unsigned video_swap_interval = settings->uints.video_swap_interval;
|
||||
unsigned video_bfi = settings->uints.video_black_frame_insertion;
|
||||
bool video_windowed_full = settings->bools.video_windowed_fullscreen;
|
||||
bool vrr_runloop_enable = settings->bools.vrr_runloop_enable;
|
||||
|
||||
/* Roundings to PAL & NTSC standards */
|
||||
refresh_rate = (refresh_rate > 54 && refresh_rate < 60) ? 59.94f : refresh_rate;
|
||||
refresh_rate = (refresh_rate > 49 && refresh_rate < 55) ? 50.00f : refresh_rate;
|
||||
|
||||
/* Black frame insertion + swap interval multiplier */
|
||||
refresh_mod = video_bfi + 1.0f;
|
||||
refresh_rate = (refresh_rate * refresh_mod * video_swap_interval);
|
||||
|
||||
/* Fallback when target refresh rate is not exposed */
|
||||
if (!video_display_server_has_refresh_rate(refresh_rate))
|
||||
refresh_rate = (60.0f * refresh_mod * video_swap_interval);
|
||||
|
||||
/* Store original refresh rate on automatic change, and
|
||||
* restore it in deinit_core and main_quit, because not all
|
||||
* cores announce refresh rate via SET_SYSTEM_AV_INFO */
|
||||
if (!p_rarch->video_refresh_rate_original)
|
||||
p_rarch->video_refresh_rate_original = video_refresh_rate;
|
||||
|
||||
/* Try to switch display rate when:
|
||||
* - Not already at correct rate
|
||||
* - In exclusive fullscreen
|
||||
* - 'CRT SwitchRes' OFF & 'Sync to Exact Content Framerate' OFF
|
||||
*/
|
||||
video_switch_refresh_rate = (
|
||||
refresh_rate != video_refresh_rate &&
|
||||
!crt_switch_resolution && !vrr_runloop_enable &&
|
||||
video_fullscreen && !video_windowed_full);
|
||||
}
|
||||
|
||||
no_video_reinit = (
|
||||
crt_switch_resolution == 0
|
||||
&& video_switch_refresh_rate == false
|
||||
&& data
|
||||
&& ((*info)->geometry.max_width == av_info->geometry.max_width)
|
||||
&& ((*info)->geometry.max_height == av_info->geometry.max_height));
|
||||
|
||||
/* First set new refresh rate and display rate, then after REINIT do
|
||||
* another display rate change to make sure the change stays */
|
||||
if (video_switch_refresh_rate)
|
||||
{
|
||||
video_monitor_set_refresh_rate(refresh_rate);
|
||||
video_display_server_set_refresh_rate(refresh_rate);
|
||||
}
|
||||
|
||||
/* When not doing video reinit, we also must not do input and menu
|
||||
* reinit, otherwise the input driver crashes and the menu gets
|
||||
* corrupted. */
|
||||
@ -14453,6 +14512,9 @@ static bool rarch_environment_cb(unsigned cmd, void *data)
|
||||
if (no_video_reinit)
|
||||
video_driver_set_aspect_ratio();
|
||||
|
||||
if (video_switch_refresh_rate)
|
||||
video_display_server_set_refresh_rate(refresh_rate);
|
||||
|
||||
/* Cannot continue recording with different parameters.
|
||||
* Take the easiest route out and just restart the recording. */
|
||||
if (p_rarch->recording_data)
|
||||
@ -23883,6 +23945,58 @@ void *video_display_server_get_resolution_list(unsigned *size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool video_display_server_has_refresh_rate(float hz)
|
||||
{
|
||||
unsigned i, size = 0;
|
||||
bool rate_exists = false;
|
||||
|
||||
struct video_display_config *video_list = (struct video_display_config*)
|
||||
video_display_server_get_resolution_list(&size);
|
||||
|
||||
if (video_list)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
unsigned video_driver_width = p_rarch->video_driver_width;
|
||||
unsigned video_driver_height = p_rarch->video_driver_height;
|
||||
|
||||
for (i = 0; i < size && !rate_exists; i++)
|
||||
{
|
||||
if (video_list[i].width == video_driver_width &&
|
||||
video_list[i].height == video_driver_height &&
|
||||
video_list[i].refreshrate == floor(hz))
|
||||
rate_exists = true;
|
||||
}
|
||||
|
||||
free(video_list);
|
||||
}
|
||||
|
||||
return rate_exists;
|
||||
}
|
||||
|
||||
bool video_display_server_set_refresh_rate(float hz)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
if (current_display_server && current_display_server->set_resolution)
|
||||
return current_display_server->set_resolution(
|
||||
p_rarch->current_display_server_data, 0, 0, (int)hz,
|
||||
hz, 0, 0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
void video_display_server_restore_refresh_rate(void)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
settings_t *settings = p_rarch->configuration_settings;
|
||||
float refresh_rate_original = p_rarch->video_refresh_rate_original;
|
||||
float refresh_rate_current = settings->floats.video_refresh_rate;
|
||||
|
||||
if (!refresh_rate_original || refresh_rate_current == refresh_rate_original)
|
||||
return;
|
||||
|
||||
video_monitor_set_refresh_rate(refresh_rate_original);
|
||||
video_display_server_set_refresh_rate(refresh_rate_original);
|
||||
}
|
||||
|
||||
const char *video_display_server_get_output_options(void)
|
||||
{
|
||||
struct rarch_state *p_rarch = &rarch_st;
|
||||
@ -31492,6 +31606,11 @@ bool retroarch_main_quit(void)
|
||||
discord_is_inited = false;
|
||||
#endif
|
||||
|
||||
/* Restore original refresh rate, if it has been changed
|
||||
* automatically in SET_SYSTEM_AV_INFO */
|
||||
if (p_rarch->video_refresh_rate_original)
|
||||
video_display_server_restore_refresh_rate();
|
||||
|
||||
if (!runloop_state.shutdown_initiated)
|
||||
{
|
||||
command_event_save_auto_state(
|
||||
|
@ -1542,6 +1542,7 @@ struct rarch_state
|
||||
float *audio_driver_input_data;
|
||||
float video_driver_core_hz;
|
||||
float video_driver_aspect_ratio;
|
||||
float video_refresh_rate_original;
|
||||
|
||||
#ifdef HAVE_AUDIOMIXER
|
||||
float audio_driver_mixer_volume_gain;
|
||||
|
Loading…
x
Reference in New Issue
Block a user