[PATCH weston v6 50/73] compositor-drm: allocate CRTC on enable()

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


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

A drm_output needs a CRTC only when it is in use. Allocating a CRTC on
creation of drm_output will reserve the CRTC regardless of whether the
output is actually used or not. This may cause creating other
drm_outputs to fail if there are not enough CRTCs.

Instead, allocate the CRTC on drm_output enable() time. A drm_output
will have a valid CRTC only while it is enabled.

This allows us to create drm_output objects arbitrarily and without a
head assignment, which is required by the head-based output API for the
backends. The assigned heads will be known only at enable() time.

Now drm_output_enable() has to call drmModeGetResources() to be able to
find a suitable CRTC. We might want to cache the resources somewhere,
but that is it topic for another patch.

v4: Force resetting unused CRTCs on fini.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 libweston/compositor-drm.c | 43 ++++++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 63295d2a..dc4f5db5 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -4716,6 +4716,8 @@ drm_output_init_crtc(struct drm_output *output,
 		drm_output_find_special_plane(b, output,
 					      WDRM_PLANE_TYPE_CURSOR);
 
+	wl_array_remove_uint32(&b->unused_crtcs, output->crtc_id);
+
 	return 0;
 
 err_crtc:
@@ -4735,6 +4737,7 @@ static void
 drm_output_fini_crtc(struct drm_output *output)
 {
 	struct drm_backend *b = to_drm_backend(output->base.compositor);
+	uint32_t *unused;
 
 	if (!b->universal_planes && !b->shutting_down) {
 		/* With universal planes, the 'special' planes are allocated at
@@ -4756,6 +4759,15 @@ drm_output_fini_crtc(struct drm_output *output)
 	}
 
 	drm_property_info_free(output->props_crtc, WDRM_CRTC__COUNT);
+
+	assert(output->crtc_id != 0);
+
+	unused = wl_array_add(&b->unused_crtcs, sizeof(*unused));
+	*unused = output->crtc_id;
+
+	/* Force resetting unused CRTCs */
+	b->state_invalid = true;
+
 	output->crtc_id = 0;
 	output->cursor_plane = NULL;
 	output->scanout_plane = NULL;
@@ -4768,6 +4780,21 @@ drm_output_enable(struct weston_output *base)
 	struct drm_backend *b = to_drm_backend(base->compositor);
 	struct drm_head *head = to_drm_head(weston_output_get_first_head(base));
 	struct weston_mode *m;
+	drmModeRes *resources;
+	int ret;
+
+	resources = drmModeGetResources(b->drm.fd);
+	if (!resources) {
+		weston_log("drmModeGetResources failed\n");
+		return -1;
+	}
+	ret = drm_output_init_crtc(output, resources, head->connector);
+	drmModeFreeResources(resources);
+	if (ret < 0)
+		return -1;
+
+	if (drm_output_init_gamma_size(output) < 0)
+		goto err;
 
 	if (b->pageflip_timeout)
 		drm_output_pageflip_timer_create(output);
@@ -4810,7 +4837,6 @@ drm_output_enable(struct weston_output *base)
 				      &b->compositor->primary_plane);
 
 	wl_array_remove_uint32(&b->unused_connectors, head->connector_id);
-	wl_array_remove_uint32(&b->unused_crtcs, output->crtc_id);
 
 	weston_log("Output %s, (connector %d, crtc %d)\n",
 		   output->base.name, head->connector_id, output->crtc_id);
@@ -4827,6 +4853,8 @@ drm_output_enable(struct weston_output *base)
 	return 0;
 
 err:
+	drm_output_fini_crtc(output);
+
 	return -1;
 }
 
@@ -4861,11 +4889,8 @@ drm_output_deinit(struct weston_output *base)
 
 	unused = wl_array_add(&b->unused_connectors, sizeof(*unused));
 	*unused = head->connector_id;
-	unused = wl_array_add(&b->unused_crtcs, sizeof(*unused));
-	*unused = output->crtc_id;
 
-	/* Force programming unused connectors and crtcs. */
-	b->state_invalid = true;
+	drm_output_fini_crtc(output);
 }
 
 static void
@@ -4895,8 +4920,6 @@ drm_output_destroy(struct weston_output *base)
 
 	weston_output_release(&output->base);
 
-	drm_output_fini_crtc(output);
-
 	assert(!output->state_last);
 	drm_output_state_free(output->state_cur);
 
@@ -5166,12 +5189,6 @@ create_output_for_connector(struct drm_backend *b,
 	output->destroy_pending = 0;
 	output->disable_pending = 0;
 
-	if (drm_output_init_crtc(output, resources, connector) < 0)
-		goto err_output;
-
-	if (drm_output_init_gamma_size(output) < 0)
-		goto err_output;
-
 	output->state_cur = drm_output_state_alloc(output, NULL);
 
 	for (i = 0; i < head->connector->count_modes; i++) {
-- 
2.13.6



More information about the wayland-devel mailing list