summaryrefslogtreecommitdiff
path: root/libweston
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2017-09-05 16:11:15 +0300
committerPekka Paalanen <pekka.paalanen@collabora.co.uk>2018-02-12 16:48:23 +0200
commitfc5f5d7126e8da9ff5416f15325b6ef30743ad88 (patch)
treeca51f84b673028c37ea0a00ea6c8864751581333 /libweston
parentc4db6f762922d76ca200fa4f392c736a3ad9c104 (diff)
downloadweston-fc5f5d7126e8da9ff5416f15325b6ef30743ad88.tar.gz
compositor-drm: factor out drm_output_init_crtc()
Factor out drm_output_init_crtc() and drm_output_fini_crtc(), so that the call sites can later be moved easily. On fini, reset scanout_plane and cursor_plane to NULL, so that in the future when the drm_output is not longer destroyed immediately after, we free the planes for other use. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Ian Ray <ian.ray@ge.com> [Pekka: set crtc_id/pipe at top, reset both on error] Reviewed-by: Daniel Stone <daniels@collabora.com>
Diffstat (limited to 'libweston')
-rw-r--r--libweston/compositor-drm.c158
1 files changed, 106 insertions, 52 deletions
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index ab473e4f..d192cf3b 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -4593,6 +4593,109 @@ drm_output_init_gamma_size(struct drm_output *output)
return 0;
}
+/** Allocate a CRTC for the output
+ *
+ * @param output The output with no allocated CRTC.
+ * @param resources DRM KMS resources.
+ * @param connector The DRM KMS connector data.
+ * @return 0 on success, -1 on failure.
+ *
+ * Finds a free CRTC that can drive the given connector, reserves the CRTC
+ * for the output, and loads the CRTC properties.
+ *
+ * Populates the cursor and scanout planes.
+ *
+ * On failure, the output remains without a CRTC.
+ */
+static int
+drm_output_init_crtc(struct drm_output *output,
+ drmModeRes *resources, drmModeConnector *connector)
+{
+ struct drm_backend *b = to_drm_backend(output->base.compositor);
+ drmModeObjectPropertiesPtr props;
+ int i;
+
+ assert(output->crtc_id == 0);
+
+ i = find_crtc_for_connector(b, resources, connector);
+ if (i < 0) {
+ weston_log("No usable crtc/encoder pair for connector.\n");
+ return -1;
+ }
+
+ output->crtc_id = resources->crtcs[i];
+ output->pipe = i;
+
+ props = drmModeObjectGetProperties(b->drm.fd, output->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+ if (!props) {
+ weston_log("failed to get CRTC properties\n");
+ goto err_crtc;
+ }
+ drm_property_info_populate(b, crtc_props, output->props_crtc,
+ WDRM_CRTC__COUNT, props);
+ drmModeFreeObjectProperties(props);
+
+ output->scanout_plane =
+ drm_output_find_special_plane(b, output,
+ WDRM_PLANE_TYPE_PRIMARY);
+ if (!output->scanout_plane) {
+ weston_log("Failed to find primary plane for output %s\n",
+ output->base.name);
+ goto err_crtc;
+ }
+
+ /* Failing to find a cursor plane is not fatal, as we'll fall back
+ * to software cursor. */
+ output->cursor_plane =
+ drm_output_find_special_plane(b, output,
+ WDRM_PLANE_TYPE_CURSOR);
+
+ return 0;
+
+err_crtc:
+ output->crtc_id = 0;
+ output->pipe = 0;
+
+ return -1;
+}
+
+/** Free the CRTC from the output
+ *
+ * @param output The output whose CRTC to deallocate.
+ *
+ * The CRTC reserved for the given output becomes free to use again.
+ */
+static void
+drm_output_fini_crtc(struct drm_output *output)
+{
+ struct drm_backend *b = to_drm_backend(output->base.compositor);
+
+ if (!b->universal_planes && !b->shutting_down) {
+ /* With universal planes, the 'special' planes are allocated at
+ * startup, freed at shutdown, and live on the plane list in
+ * between. We want the planes to continue to exist and be freed
+ * up for other outputs.
+ *
+ * Without universal planes, our special planes are
+ * pseudo-planes allocated at output creation, freed at output
+ * destruction, and not usable by other outputs.
+ *
+ * On the other hand, if the compositor is already shutting down,
+ * the plane has already been destroyed.
+ */
+ if (output->cursor_plane)
+ drm_plane_destroy(output->cursor_plane);
+ if (output->scanout_plane)
+ drm_plane_destroy(output->scanout_plane);
+ }
+
+ drm_property_info_free(output->props_crtc, WDRM_CRTC__COUNT);
+ output->crtc_id = 0;
+ output->cursor_plane = NULL;
+ output->scanout_plane = NULL;
+}
+
static int
drm_output_enable(struct weston_output *base)
{
@@ -4715,25 +4818,6 @@ drm_output_destroy(struct weston_output *base)
if (output->base.enabled)
drm_output_deinit(&output->base);
- if (!b->universal_planes && !b->shutting_down) {
- /* With universal planes, the 'special' planes are allocated at
- * startup, freed at shutdown, and live on the plane list in
- * between. We want the planes to continue to exist and be freed
- * up for other outputs.
- *
- * Without universal planes, our special planes are
- * pseudo-planes allocated at output creation, freed at output
- * destruction, and not usable by other outputs.
- *
- * On the other hand, if the compositor is already shutting down,
- * the plane has already been destroyed.
- */
- if (output->cursor_plane)
- drm_plane_destroy(output->cursor_plane);
- if (output->scanout_plane)
- drm_plane_destroy(output->scanout_plane);
- }
-
wl_list_for_each_safe(drm_mode, next, &output->base.mode_list,
base.link)
drm_output_destroy_mode(b, drm_mode);
@@ -4743,9 +4827,9 @@ drm_output_destroy(struct weston_output *base)
weston_output_release(&output->base);
- drm_property_info_free(output->props_conn, WDRM_CONNECTOR__COUNT);
- drm_property_info_free(output->props_crtc, WDRM_CRTC__COUNT);
+ drm_output_fini_crtc(output);
+ drm_property_info_free(output->props_conn, WDRM_CONNECTOR__COUNT);
drmModeFreeConnector(output->connector);
if (output->backlight)
@@ -4851,19 +4935,11 @@ create_output_for_connector(struct drm_backend *b,
const char *serial_number = "unknown";
int i;
- i = find_crtc_for_connector(b, resources, connector);
- if (i < 0) {
- weston_log("No usable crtc/encoder pair for connector.\n");
- goto err_init;
- }
-
output = zalloc(sizeof *output);
if (output == NULL)
goto err_init;
output->connector = connector;
- output->crtc_id = resources->crtcs[i];
- output->pipe = i;
output->connector_id = connector->connector_id;
output->backlight = backlight_init(drm_device,
@@ -4880,15 +4956,8 @@ create_output_for_connector(struct drm_backend *b,
output->destroy_pending = 0;
output->disable_pending = 0;
- props = drmModeObjectGetProperties(b->drm.fd, output->crtc_id,
- DRM_MODE_OBJECT_CRTC);
- if (!props) {
- weston_log("failed to get CRTC properties\n");
+ if (drm_output_init_crtc(output, resources, connector) < 0)
goto err_output;
- }
- drm_property_info_populate(b, crtc_props, output->props_crtc,
- WDRM_CRTC__COUNT, props);
- drmModeFreeObjectProperties(props);
props = drmModeObjectGetProperties(b->drm.fd, connector->connector_id,
DRM_MODE_OBJECT_CONNECTOR);
@@ -4927,21 +4996,6 @@ create_output_for_connector(struct drm_backend *b,
}
}
- output->scanout_plane =
- drm_output_find_special_plane(b, output,
- WDRM_PLANE_TYPE_PRIMARY);
- if (!output->scanout_plane) {
- weston_log("Failed to find primary plane for output %s\n",
- output->base.name);
- goto err_output;
- }
-
- /* Failing to find a cursor plane is not fatal, as we'll fall back
- * to software cursor. */
- output->cursor_plane =
- drm_output_find_special_plane(b, output,
- WDRM_PLANE_TYPE_CURSOR);
-
weston_compositor_add_pending_output(&output->base, b->compositor);
return 0;