compositor-drm: Handle unconnected connectors better
If a connector is not attached to a crtc, weston fails to bring it up. Typically kms fbdev drives all crtc and connectors, but if kms hasn't been initialzed and weston is the first to set a mode of if a monitor is hotplugged, we just fail to bring it up. (krh: reformatted and edited a bit from original patch)
This commit is contained in:
committed by
Kristian Høgsberg
parent
572c2ff59a
commit
acb805a356
+22
-20
@@ -1337,14 +1337,16 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
/* Get the current mode on the crtc that's currently driving
|
/* Get the current mode on the crtc that's currently driving
|
||||||
* this connector. */
|
* this connector. */
|
||||||
encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
|
encoder = drmModeGetEncoder(ec->drm.fd, connector->encoder_id);
|
||||||
if (encoder == NULL)
|
memset(&crtc_mode, 0, sizeof crtc_mode);
|
||||||
goto err_free;
|
if (encoder != NULL) {
|
||||||
crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
|
crtc = drmModeGetCrtc(ec->drm.fd, encoder->crtc_id);
|
||||||
drmModeFreeEncoder(encoder);
|
drmModeFreeEncoder(encoder);
|
||||||
if (crtc == NULL)
|
if (crtc == NULL)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
crtc_mode = crtc->mode;
|
if (crtc->mode_valid)
|
||||||
drmModeFreeCrtc(crtc);
|
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]);
|
||||||
@@ -1355,34 +1357,34 @@ create_output_for_connector(struct drm_compositor *ec,
|
|||||||
preferred = NULL;
|
preferred = NULL;
|
||||||
current = NULL;
|
current = NULL;
|
||||||
wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
|
wl_list_for_each(drm_mode, &output->base.mode_list, base.link) {
|
||||||
if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode)) {
|
if (!memcmp(&crtc_mode, &drm_mode->mode_info, sizeof crtc_mode))
|
||||||
drm_mode->base.flags |= WL_OUTPUT_MODE_CURRENT;
|
|
||||||
current = &drm_mode->base;
|
current = &drm_mode->base;
|
||||||
}
|
|
||||||
if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
|
if (drm_mode->base.flags & WL_OUTPUT_MODE_PREFERRED)
|
||||||
preferred = &drm_mode->base;
|
preferred = &drm_mode->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current == NULL) {
|
if (current == NULL && crtc_mode.clock != 0) {
|
||||||
ret = drm_output_add_mode(output, &crtc_mode);
|
ret = drm_output_add_mode(output, &crtc_mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
current = container_of(output->base.mode_list.prev,
|
current = container_of(output->base.mode_list.prev,
|
||||||
struct weston_mode, link);
|
struct weston_mode, link);
|
||||||
current->flags |= WL_OUTPUT_MODE_CURRENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preferred == NULL)
|
if (option_current_mode && current)
|
||||||
preferred = current;
|
|
||||||
|
|
||||||
if (option_current_mode) {
|
|
||||||
output->base.current = current;
|
output->base.current = current;
|
||||||
} else {
|
else if (preferred)
|
||||||
output->base.current = preferred;
|
output->base.current = preferred;
|
||||||
current->flags &= ~WL_OUTPUT_MODE_CURRENT;
|
else if (current)
|
||||||
preferred->flags |= WL_OUTPUT_MODE_CURRENT;
|
output->base.current = current;
|
||||||
|
|
||||||
|
if (output->base.current == NULL) {
|
||||||
|
weston_log("no available modes for %s\n", output->name);
|
||||||
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output->base.current->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,
|
||||||
output->base.current->height,
|
output->base.current->height,
|
||||||
|
|||||||
Reference in New Issue
Block a user