Skip to content

Commit

Permalink
Fullscreen refresh rate improvements
Browse files Browse the repository at this point in the history
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 stil not be selected), and allow close matches such as 49.5 Hz
for PAL 50 Hz.
  • Loading branch information
zoltanvb committed Jun 16, 2024
1 parent 1f1ff0a commit e58a90b
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 10 deletions.
11 changes: 10 additions & 1 deletion gfx/display_servers/dispserv_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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++;
Expand Down
6 changes: 6 additions & 0 deletions gfx/display_servers/dispserv_win32.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ static void *win32_display_server_get_resolution_list(
#if _WIN32_WINNT >= 0x0500
unsigned curr_orientation = 0;
#endif
bool curr_interlaced = 0;
struct video_display_config *conf = NULL;

if (win32_get_video_output(&dm, -1, sizeof(dm)))
Expand All @@ -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++)
Expand Down Expand Up @@ -403,13 +405,17 @@ static void *win32_display_server_get_resolution_list(
conf[j].height = dm.dmPelsHeight;
conf[j].bpp = dm.dmBitsPerPel;
conf[j].refreshrate = dm.dmDisplayFrequency;
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;

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;

Expand Down
3 changes: 3 additions & 0 deletions gfx/video_display_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 5 additions & 3 deletions gfx/video_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1214,9 +1214,11 @@ 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 recognize 49.95Hz modelines for PAL */
if ( (video_list[i].width == video_driver_width)
&& (video_list[i].height == video_driver_height)
&& ((video_list[i].refreshrate == floor(hz)) ||
(abs(video_list[i].refreshrate_float - hz) < 0.06f)))
rate_exists = true;
}

Expand Down
9 changes: 5 additions & 4 deletions menu/cbs/menu_cbs_ok.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -6960,7 +6961,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");
Expand All @@ -6971,10 +6972,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
Expand All @@ -6984,7 +6985,7 @@ int action_cb_push_dropdown_item_resolution(const char *path,
unsigned refresh_mod = (unsigned)lroundf((float)(refreshrate / 60.0f));
#endif
float refresh_exact = refreshrate;

/* TODO: what is going on here */
/* 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,
* the exact float needs to be calculated for 'video_refresh_rate' */
Expand Down
13 changes: 11 additions & 2 deletions menu/menu_displaylist.c
Original file line number Diff line number Diff line change
Expand Up @@ -8350,10 +8350,19 @@ 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 (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,
Expand Down

0 comments on commit e58a90b

Please sign in to comment.