From 4be248550259a6794157e9bd46d17a1f66f37a72 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Mon, 11 Sep 2017 15:01:12 +0300 Subject: [PATCH] compositor-drm: move mode list to set_mode() Move the initialization of the drm_output mode list to drm_output_set_mode() time. Once we stop creating the drm_head with the drm_output, there will not be a head to get the mode list from at drm_output creation time. Furthermore, once DRM-backend starts supporting more than one head per output, the combined mode list to be exposed to clients (and the compositor?) must be constructed with all heads attached. Signed-off-by: Pekka Paalanen Reviewed-by: Daniel Stone Acked-by: Derek Foreman --- libweston/compositor-drm.c | 54 ++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c index f54257cd..df31f87e 100644 --- a/libweston/compositor-drm.c +++ b/libweston/compositor-drm.c @@ -4439,6 +4439,43 @@ parse_gbm_format(const char *s, uint32_t default_value, uint32_t *gbm_format) return ret; } +/** Rewrite the output's mode list + * + * @param output The output. + * @return 0 on success, -1 on failure. + * + * Destroy all existing modes in the list, and reconstruct a new list from + * scratch, based on the currently attached heads. + * + * On failure the output's mode list may contain some modes. + */ +static int +drm_output_update_modelist_from_heads(struct drm_output *output) +{ + struct drm_backend *backend = to_drm_backend(output->base.compositor); + struct weston_head *head_base; + struct drm_head *head; + struct drm_mode *mode; + int i; + + assert(!output->base.enabled); + + drm_mode_list_destroy(backend, &output->base.mode_list); + + /* XXX: needs a strategy for combining mode lists from multiple heads */ + head_base = weston_output_get_first_head(&output->base); + assert(head_base); + head = to_drm_head(head_base); + + for (i = 0; i < head->connector->count_modes; i++) { + mode = drm_output_add_mode(output, &head->connector->modes[i]); + if (!mode) + return -1; + } + + return 0; +} + /** * Choose suitable mode for an output * @@ -4563,6 +4600,9 @@ drm_output_set_mode(struct weston_output *base, struct drm_mode *current; + if (drm_output_update_modelist_from_heads(output) < 0) + return -1; + current = drm_output_choose_initial_mode(b, output, mode, modeline, &head->inherited_mode); if (!current) @@ -5140,8 +5180,6 @@ create_output_for_connector(struct drm_backend *b, { struct drm_output *output; struct drm_head *head; - struct drm_mode *drm_mode; - int i; output = zalloc(sizeof *output); if (output == NULL) @@ -5165,14 +5203,6 @@ create_output_for_connector(struct drm_backend *b, output->state_cur = drm_output_state_alloc(output, NULL); - for (i = 0; i < head->connector->count_modes; i++) { - drm_mode = drm_output_add_mode(output, &head->connector->modes[i]); - if (!drm_mode) { - weston_log("failed to add mode\n"); - goto err_output; - } - } - weston_compositor_add_pending_output(&output->base, b->compositor); /* drm_head_create() made its own connector */ @@ -5180,10 +5210,6 @@ create_output_for_connector(struct drm_backend *b, return 0; -err_output: - drm_head_destroy(head); - drm_output_destroy(&output->base); - err_init: drmModeFreeConnector(connector); return -1;