[PATCH weston v6 54/73] compositor-drm: move mode list to set_mode()

Pekka Paalanen ppaalanen at gmail.com
Fri Feb 16 14:57:39 UTC 2018


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

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 <pekka.paalanen at collabora.co.uk>
---
 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 5e459380..c0687932 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -4457,6 +4457,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
  *
@@ -4581,6 +4618,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)
@@ -5158,8 +5198,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)
@@ -5183,14 +5221,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 */
@@ -5198,10 +5228,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;
-- 
2.13.6



More information about the wayland-devel mailing list