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)
dev
Wang Quanxian 12 years ago committed by Kristian Høgsberg
parent 572c2ff59a
commit acb805a356
  1. 30
      src/compositor-drm.c

@ -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;
if (crtc->mode_valid)
crtc_mode = crtc->mode; crtc_mode = crtc->mode;
drmModeFreeCrtc(crtc); 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,

Loading…
Cancel
Save