drm: sort modes
This allows the best mode to be selected even if a constraint is specified (such as the width or height).
This commit is contained in:
parent
a3144601c3
commit
127b1b510e
2 changed files with 19 additions and 21 deletions
34
src/drm.cpp
34
src/drm.cpp
|
@ -23,6 +23,7 @@ extern "C" {
|
||||||
|
|
||||||
#include "gpuvis_trace_utils.h"
|
#include "gpuvis_trace_utils.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
struct drm_t g_DRM = {};
|
struct drm_t g_DRM = {};
|
||||||
|
@ -365,26 +366,19 @@ static const drmModeModeInfo *get_matching_mode( const drmModeConnector *connect
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const drmModeModeInfo *get_preferred_mode( const drmModeConnector *connector )
|
static bool compare_modes( drmModeModeInfo mode1, drmModeModeInfo mode2 )
|
||||||
{
|
{
|
||||||
/* find preferred mode or the highest resolution mode */
|
if (mode1.type & DRM_MODE_TYPE_PREFERRED)
|
||||||
int highest_area = 0;
|
return true;
|
||||||
const drmModeModeInfo *highest_mode = NULL;
|
if (mode2.type & DRM_MODE_TYPE_PREFERRED)
|
||||||
for (int i = 0; i < connector->count_modes; i++) {
|
return false;
|
||||||
const drmModeModeInfo *mode = &connector->modes[i];
|
|
||||||
|
|
||||||
if (mode->type & DRM_MODE_TYPE_PREFERRED) {
|
int area1 = mode1.hdisplay * mode1.vdisplay;
|
||||||
return mode;
|
int area2 = mode2.hdisplay * mode2.vdisplay;
|
||||||
}
|
if (area1 != area2)
|
||||||
|
return area1 > area2;
|
||||||
|
|
||||||
int area = mode->hdisplay * mode->vdisplay;
|
return mode1.vrefresh > mode2.vrefresh;
|
||||||
if (area > highest_area) {
|
|
||||||
highest_mode = mode;
|
|
||||||
highest_area = area;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return highest_mode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_drm(struct drm_t *drm, const char *device)
|
int init_drm(struct drm_t *drm, const char *device)
|
||||||
|
@ -432,13 +426,17 @@ int init_drm(struct drm_t *drm, const char *device)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sort modes by preference: preferred flag, then highest area, then
|
||||||
|
* highest refresh rate */
|
||||||
|
std::stable_sort(connector->modes, connector->modes + connector->count_modes, compare_modes);
|
||||||
|
|
||||||
if ( g_nOutputWidth != 0 || g_nOutputHeight != 0 || g_nNestedRefresh != 0 )
|
if ( g_nOutputWidth != 0 || g_nOutputHeight != 0 || g_nNestedRefresh != 0 )
|
||||||
{
|
{
|
||||||
drm->mode = get_matching_mode(connector, g_nOutputWidth, g_nOutputHeight, g_nNestedRefresh);
|
drm->mode = get_matching_mode(connector, g_nOutputWidth, g_nOutputHeight, g_nNestedRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drm->mode) {
|
if (!drm->mode) {
|
||||||
drm->mode = get_preferred_mode(connector);
|
drm->mode = get_matching_mode(connector, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drm->mode) {
|
if (!drm->mode) {
|
||||||
|
|
|
@ -12,12 +12,12 @@ void wayland_commit(struct wlr_surface *surf, struct wlr_buffer *buf);
|
||||||
|
|
||||||
extern int g_nNestedWidth;
|
extern int g_nNestedWidth;
|
||||||
extern int g_nNestedHeight;
|
extern int g_nNestedHeight;
|
||||||
extern int g_nNestedRefresh;
|
extern int g_nNestedRefresh; // Hz
|
||||||
extern int g_nNestedUnfocusedRefresh;
|
extern int g_nNestedUnfocusedRefresh; // Hz
|
||||||
|
|
||||||
extern uint32_t g_nOutputWidth;
|
extern uint32_t g_nOutputWidth;
|
||||||
extern uint32_t g_nOutputHeight;
|
extern uint32_t g_nOutputHeight;
|
||||||
extern int g_nOutputRefresh;
|
extern int g_nOutputRefresh; // Hz
|
||||||
|
|
||||||
extern bool g_bFullscreen;
|
extern bool g_bFullscreen;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue