mirror of
https://github.com/libretro/RetroArch
synced 2025-03-20 10:20:51 +00:00
Fullscreen refresh rate improvements
Handle refresh rate as float in general, and add also extra attributes (interlaced, doublescan) for video modes. Make it possible to select exact mode (interlaced / doublescan modes will not be selected), and allow close matches such as 49.5 Hz for PAL 50 Hz.
This commit is contained in:
parent
622736e195
commit
2ca973770f
@ -123,6 +123,8 @@ static void *kms_display_server_get_resolution_list(
|
||||
unsigned curr_width = 0;
|
||||
unsigned curr_height = 0;
|
||||
unsigned curr_bpp = 0;
|
||||
bool curr_interlaced = false;
|
||||
bool curr_dblscan = false;
|
||||
float curr_refreshrate = 0;
|
||||
unsigned curr_orientation = 0;
|
||||
struct video_display_config *conf = NULL;
|
||||
@ -134,6 +136,8 @@ static void *kms_display_server_get_resolution_list(
|
||||
curr_width = g_drm_mode->hdisplay;
|
||||
curr_height = g_drm_mode->vdisplay;
|
||||
curr_bpp = 32;
|
||||
curr_interlaced = (g_drm_mode->flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
|
||||
curr_dblscan = (g_drm_mode->flags & DRM_MODE_FLAG_DBLSCAN) ? true : false;
|
||||
}
|
||||
|
||||
*len = g_drm_connector->count_modes;
|
||||
@ -147,13 +151,18 @@ static void *kms_display_server_get_resolution_list(
|
||||
conf[j].height = g_drm_connector->modes[i].vdisplay;
|
||||
conf[j].bpp = 32;
|
||||
conf[j].refreshrate = floor(drm_calc_refresh_rate(&g_drm_connector->modes[i]));
|
||||
conf[j].refreshrate_float = drm_calc_refresh_rate(&g_drm_connector->modes[i]);
|
||||
conf[j].interlaced = (g_drm_connector->modes[i].flags & DRM_MODE_FLAG_INTERLACE) ? true : false;
|
||||
conf[j].dblscan = (g_drm_connector->modes[i].flags & DRM_MODE_FLAG_DBLSCAN) ? true : false;
|
||||
conf[j].idx = j;
|
||||
conf[j].current = false;
|
||||
|
||||
if ( (conf[j].width == curr_width)
|
||||
&& (conf[j].height == curr_height)
|
||||
&& (conf[j].bpp == curr_bpp)
|
||||
&& (drm_calc_refresh_rate(&g_drm_connector->modes[i]) == curr_refreshrate)
|
||||
&& (conf[j].refreshrate_float == curr_refreshrate)
|
||||
&& (conf[j].interlaced == curr_interlaced)
|
||||
&& (conf[j].dblscan == curr_dblscan)
|
||||
)
|
||||
conf[j].current = true;
|
||||
j++;
|
||||
|
@ -356,6 +356,7 @@ static void *win32_display_server_get_resolution_list(
|
||||
#if _WIN32_WINNT >= 0x0500
|
||||
unsigned curr_orientation = 0;
|
||||
#endif
|
||||
bool curr_interlaced = false;
|
||||
struct video_display_config *conf = NULL;
|
||||
|
||||
if (win32_get_video_output(&dm, -1, sizeof(dm)))
|
||||
@ -367,6 +368,7 @@ static void *win32_display_server_get_resolution_list(
|
||||
#if _WIN32_WINNT >= 0x0500
|
||||
curr_orientation = dm.dmDisplayOrientation;
|
||||
#endif
|
||||
curr_interlaced = (dm.dmDisplayFlags & DM_INTERLACED) ? true : false;
|
||||
}
|
||||
|
||||
for (i = 0; win32_get_video_output(&dm, i, sizeof(dm)); i++)
|
||||
@ -403,13 +405,18 @@ static void *win32_display_server_get_resolution_list(
|
||||
conf[j].height = dm.dmPelsHeight;
|
||||
conf[j].bpp = dm.dmBitsPerPel;
|
||||
conf[j].refreshrate = dm.dmDisplayFrequency;
|
||||
/* It may be possible to get exact refresh rate via different API - for now, it is integer only */
|
||||
conf[j].refreshrate_float = 0.0f;
|
||||
conf[j].idx = j;
|
||||
conf[j].current = false;
|
||||
conf[j].interlaced = (dm.dmDisplayFlags & DM_INTERLACED) ? true : false;
|
||||
conf[j].dblscan = false; /* no flag for doublescan on this platform */
|
||||
|
||||
if ( (conf[j].width == curr_width)
|
||||
&& (conf[j].height == curr_height)
|
||||
&& (conf[j].bpp == curr_bpp)
|
||||
&& (conf[j].refreshrate == curr_refreshrate)
|
||||
&& (conf[j].interlaced == curr_interlaced)
|
||||
)
|
||||
conf[j].current = true;
|
||||
|
||||
|
@ -39,6 +39,9 @@ typedef struct video_display_config
|
||||
unsigned refreshrate;
|
||||
unsigned idx;
|
||||
bool current;
|
||||
bool interlaced;
|
||||
bool dblscan;
|
||||
float refreshrate_float;
|
||||
} video_display_config_t;
|
||||
|
||||
typedef struct video_display_server
|
||||
|
@ -1214,9 +1214,14 @@ bool video_display_server_has_refresh_rate(float hz)
|
||||
|
||||
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)))
|
||||
/* Float difference added to enable 49.95Hz modelines for PAL. *
|
||||
* Actual mode selection will be done in context driver, *
|
||||
* with some logic in video_switch_refresh_rate_maybe *
|
||||
* and in action_cb_push_dropdown_item_resolution */
|
||||
if ( (video_list[i].width == video_driver_width)
|
||||
&& (video_list[i].height == video_driver_height)
|
||||
&& ((video_list[i].refreshrate == floor(hz)) ||
|
||||
(fabsf(video_list[i].refreshrate_float - hz) < 0.06f)))
|
||||
rate_exists = true;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <compat/strl.h>
|
||||
#include <array/rbuf.h>
|
||||
#include <file/file_path.h>
|
||||
@ -6928,7 +6929,7 @@ int action_cb_push_dropdown_item_resolution(const char *path,
|
||||
char *pch = NULL;
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
unsigned refreshrate = 0;
|
||||
float refreshrate = 0.0f;
|
||||
|
||||
strlcpy(str, path, sizeof(str));
|
||||
pch = strtok(str, "x");
|
||||
@ -6939,10 +6940,10 @@ int action_cb_push_dropdown_item_resolution(const char *path,
|
||||
height = (unsigned)strtoul(pch, NULL, 0);
|
||||
pch = strtok(NULL, "(");
|
||||
if (pch)
|
||||
refreshrate = (unsigned)strtoul(pch, NULL, 0);
|
||||
refreshrate = (float)strtod(pch, NULL);
|
||||
|
||||
if (video_display_server_set_resolution(width, height,
|
||||
refreshrate, (float)refreshrate, 0, 0, 0, 0))
|
||||
floor(refreshrate), refreshrate, 0, 0, 0, 0))
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
#ifdef _MSC_VER
|
||||
@ -6954,7 +6955,7 @@ int action_cb_push_dropdown_item_resolution(const char *path,
|
||||
float refresh_exact = refreshrate;
|
||||
|
||||
/* 59 Hz is an inaccurate representation of the real value (59.94).
|
||||
* And since we at this point only have the integer to work with,
|
||||
* In case at this point we only have the integer to work with,
|
||||
* the exact float needs to be calculated for 'video_refresh_rate' */
|
||||
if (refreshrate == (60.0f * refresh_mod) - 1)
|
||||
refresh_exact = 59.94f * refresh_mod;
|
||||
|
@ -8350,10 +8350,20 @@ unsigned menu_displaylist_build_list(
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
char val_d[256], str[256];
|
||||
snprintf(str, sizeof(str), "%dx%d (%d Hz)",
|
||||
/* If there is exact refresh rate available, use it */
|
||||
if (video_list[i].refreshrate_float > 0.0f)
|
||||
snprintf(str, sizeof(str), "%dx%d (%.3f Hz)%s%s",
|
||||
video_list[i].width,
|
||||
video_list[i].height,
|
||||
video_list[i].refreshrate);
|
||||
video_list[i].refreshrate_float,
|
||||
video_list[i].interlaced ? "[i]":"",
|
||||
video_list[i].dblscan ? "[d]":"");
|
||||
else
|
||||
snprintf(str, sizeof(str), "%dx%d (%d Hz)%s",
|
||||
video_list[i].width,
|
||||
video_list[i].height,
|
||||
video_list[i].refreshrate,
|
||||
video_list[i].interlaced ? "[i]":"");
|
||||
snprintf(val_d, sizeof(val_d), "%d", i);
|
||||
if (menu_entries_append(list,
|
||||
str,
|
||||
|
Loading…
x
Reference in New Issue
Block a user