compositor-drm: Improve initial mode picking
We now pick the driver preferred mode for our initial mode. If no preferred mode is available we default to the current mode. We also have a command line option now to keep the current mode if it differs from the preferred. This commit also drops the built-in mode and insteade uses the current mode if the connector doesn't report any modes.
This commit is contained in:
parent
18e928dfb8
commit
061c425331
@ -43,6 +43,8 @@
|
|||||||
#include "launcher-util.h"
|
#include "launcher-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
static int option_current_mode = 0;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
WESTON_PLANE_DRM_CURSOR = 0x100
|
WESTON_PLANE_DRM_CURSOR = 0x100
|
||||||
};
|
};
|
||||||
@ -1119,17 +1121,6 @@ init_egl(struct drm_compositor *ec, struct udev_device *device)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static drmModeModeInfo builtin_1024x768 = {
|
|
||||||
63500, /* clock */
|
|
||||||
1024, 1072, 1176, 1328, 0,
|
|
||||||
768, 771, 775, 798, 0,
|
|
||||||
59920,
|
|
||||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
|
|
||||||
0,
|
|
||||||
"1024x768"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
|
drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
|
||||||
{
|
{
|
||||||
@ -1157,6 +1148,10 @@ drm_output_add_mode(struct drm_output *output, drmModeModeInfo *info)
|
|||||||
|
|
||||||
mode->base.refresh = refresh;
|
mode->base.refresh = refresh;
|
||||||
mode->mode_info = *info;
|
mode->mode_info = *info;
|
||||||
|
|
||||||
|
if (info->type & DRM_MODE_TYPE_PREFERRED)
|
||||||
|
mode->base.flags |= WL_OUTPUT_MODE_PREFERRED;
|
||||||
|
|
||||||
wl_list_insert(output->base.mode_list.prev, &mode->base.link);
|
wl_list_insert(output->base.mode_list.prev, &mode->base.link);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1297,7 +1292,10 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
{
|
{
|
||||||
struct drm_output *output;
|
struct drm_output *output;
|
||||||
struct drm_mode *drm_mode, *next;
|
struct drm_mode *drm_mode, *next;
|
||||||
|
struct weston_mode *m, *preferred, *current;
|
||||||
drmModeEncoder *encoder;
|
drmModeEncoder *encoder;
|
||||||
|
drmModeModeInfo crtc_mode;
|
||||||
|
drmModeCrtc *crtc;
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[0]);
|
encoder = drmModeGetEncoder(ec->drm.fd, connector->encoders[0]);
|
||||||
@ -1337,23 +1335,54 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
|
output->original_crtc = drmModeGetCrtc(ec->drm.fd, output->crtc_id);
|
||||||
drmModeFreeEncoder(encoder);
|
drmModeFreeEncoder(encoder);
|
||||||
|
|
||||||
|
/* Get the current mode on the crtc that's currently driving
|
||||||
|
* this connector. */
|
||||||
|
encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
|
||||||
|
if (encoder == NULL)
|
||||||
|
goto err_free;
|
||||||
|
crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
if (crtc == NULL)
|
||||||
|
goto err_free;
|
||||||
|
crtc_mode = crtc->mode;
|
||||||
|
drmModeFreeCrtc(crtc);
|
||||||
|
|
||||||
for (i = 0; i < connector->count_modes; i++) {
|
for (i = 0; i < connector->count_modes; i++) {
|
||||||
ret = drm_output_add_mode(output, &connector->modes[i]);
|
ret = drm_output_add_mode(output, &connector->modes[i]);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connector->count_modes == 0) {
|
preferred = NULL;
|
||||||
ret = drm_output_add_mode(output, &builtin_1024x768);
|
current = NULL;
|
||||||
if (ret)
|
wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
|
||||||
goto err_free;
|
if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode)) {
|
||||||
|
drm_mode->base.flags |= WL_OUTPUT_MODE_CURRENT;
|
||||||
|
current = &drm_mode->base;
|
||||||
|
}
|
||||||
|
if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
|
||||||
|
preferred = &drm_mode->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_mode = container_of(output->base.mode_list.next,
|
if (current == NULL) {
|
||||||
struct drm_mode, base.link);
|
ret = drm_output_add_mode(output, &crtc_mode);
|
||||||
output->base.current = &drm_mode->base;
|
if (ret)
|
||||||
drm_mode->base.flags =
|
goto err_free;
|
||||||
WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
|
current = container_of(output->base.mode_list.prev,
|
||||||
|
struct weston_mode, link);
|
||||||
|
current->flags |= WL_OUTPUT_MODE_CURRENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (preferred == NULL)
|
||||||
|
preferred = current;
|
||||||
|
|
||||||
|
if (option_current_mode) {
|
||||||
|
output->base.current = current;
|
||||||
|
} else {
|
||||||
|
output->base.current = preferred;
|
||||||
|
current->flags &= ~WL_OUTPUT_MODE_CURRENT;
|
||||||
|
preferred->flags |= WL_OUTPUT_MODE_CURRENT;
|
||||||
|
}
|
||||||
|
|
||||||
output->surface = gbm_surface_create(ec->gbm,
|
output->surface = gbm_surface_create(ec->gbm,
|
||||||
output->base.current->width,
|
output->base.current->width,
|
||||||
@ -1403,11 +1432,17 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
output->base.set_dpms = drm_set_dpms;
|
output->base.set_dpms = drm_set_dpms;
|
||||||
output->base.switch_mode = drm_output_switch_mode;
|
output->base.switch_mode = drm_output_switch_mode;
|
||||||
|
|
||||||
weston_log("kms connector %d, crtc %d at mode %dx%d@%.1f\n",
|
weston_log("kms connector %d, crtc %d\n",
|
||||||
output->connector_id, output->crtc_id,
|
output->connector_id, output->crtc_id);
|
||||||
output->base.current->width,
|
wl_list_for_each(m, &output->base.mode_list, link)
|
||||||
output->base.current->height,
|
weston_log_continue(" mode %dx%d@%.1f%s%s%s\n",
|
||||||
output->base.current->refresh / 1000.0);
|
m->width, m->height, m->refresh / 1000.0,
|
||||||
|
m->flags & WL_OUTPUT_MODE_PREFERRED ?
|
||||||
|
", preferred" : "",
|
||||||
|
m->flags & WL_OUTPUT_MODE_CURRENT ?
|
||||||
|
", current" : "",
|
||||||
|
connector->count_modes == 0 ?
|
||||||
|
", built-in" : "");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1957,6 +1992,7 @@ backend_init(struct wl_display *display, int argc, char *argv[],
|
|||||||
{ WESTON_OPTION_INTEGER, "connector", 0, &connector },
|
{ WESTON_OPTION_INTEGER, "connector", 0, &connector },
|
||||||
{ WESTON_OPTION_STRING, "seat", 0, &seat },
|
{ WESTON_OPTION_STRING, "seat", 0, &seat },
|
||||||
{ WESTON_OPTION_INTEGER, "tty", 0, &tty },
|
{ WESTON_OPTION_INTEGER, "tty", 0, &tty },
|
||||||
|
{ WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
|
||||||
};
|
};
|
||||||
|
|
||||||
parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
|
parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
|
||||||
|
Loading…
Reference in New Issue
Block a user