[PATCH v14 14/41] compositor-drm: Discover atomic properties

Daniel Stone daniels at collabora.com
Wed Dec 20 12:26:31 UTC 2017


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

Set the atomic client cap, where it exists, and use this to discover the
plane/CRTC/connector properties we require for atomic modesetting.

Signed-off-by: Daniel Stone <daniels at collabora.com>
Co-authored-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Reviewed-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
---
 configure.ac               |  3 +++
 libweston/compositor-drm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index 285c2efdf..72b5d6f23 100644
--- a/configure.ac
+++ b/configure.ac
@@ -206,6 +206,9 @@ AM_CONDITIONAL(ENABLE_DRM_COMPOSITOR, test x$enable_drm_compositor = xyes)
 if test x$enable_drm_compositor = xyes; then
   AC_DEFINE([BUILD_DRM_COMPOSITOR], [1], [Build the DRM compositor])
   PKG_CHECK_MODULES(DRM_COMPOSITOR, [libudev >= 136 libdrm >= 2.4.30 gbm])
+  PKG_CHECK_MODULES(DRM_COMPOSITOR_ATOMIC, [libdrm >= 2.4.62],
+		    [AC_DEFINE([HAVE_DRM_ATOMIC], 1, [libdrm supports atomic API])],
+		    [AC_MSG_WARN([libdrm does not support atomic modesetting, will omit that capability])])
   PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 10.2],
 		    [AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports dmabuf import])],
 		    [AC_MSG_WARN([gbm does not support dmabuf import, will omit that capability])])
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index 71e93c1c2..694e307bf 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -88,6 +88,16 @@
  */
 enum wdrm_plane_property {
 	WDRM_PLANE_TYPE = 0,
+	WDRM_PLANE_SRC_X,
+	WDRM_PLANE_SRC_Y,
+	WDRM_PLANE_SRC_W,
+	WDRM_PLANE_SRC_H,
+	WDRM_PLANE_CRTC_X,
+	WDRM_PLANE_CRTC_Y,
+	WDRM_PLANE_CRTC_W,
+	WDRM_PLANE_CRTC_H,
+	WDRM_PLANE_FB_ID,
+	WDRM_PLANE_CRTC_ID,
 	WDRM_PLANE__COUNT
 };
 
@@ -107,6 +117,7 @@ enum wdrm_plane_type {
 enum wdrm_connector_property {
 	WDRM_CONNECTOR_EDID = 0,
 	WDRM_CONNECTOR_DPMS,
+	WDRM_CONNECTOR_CRTC_ID,
 	WDRM_CONNECTOR__COUNT
 };
 
@@ -139,6 +150,15 @@ struct drm_property_info {
 	struct drm_property_enum_info *enum_values; /**< array of enum values */
 };
 
+/**
+ * List of properties attached to DRM CRTCs
+ */
+enum wdrm_crtc_property {
+	WDRM_CRTC_MODE_ID = 0,
+	WDRM_CRTC_ACTIVE,
+	WDRM_CRTC__COUNT
+};
+
 /**
  * Mode for drm_output_state_duplicate.
  */
@@ -195,6 +215,7 @@ struct drm_backend {
 	int cursors_are_broken;
 
 	bool universal_planes;
+	bool atomic_modeset;
 
 	int use_pixman;
 
@@ -347,6 +368,8 @@ struct drm_output {
 
 	/* Holds the properties for the connector */
 	struct drm_property_info props_conn[WDRM_CONNECTOR__COUNT];
+	/* Holds the properties for the CRTC */
+	struct drm_property_info props_crtc[WDRM_CRTC__COUNT];
 
 	struct backlight *backlight;
 
@@ -2889,6 +2912,15 @@ init_kms_caps(struct drm_backend *b)
 	weston_log("DRM: %s universal planes\n",
 		   b->universal_planes ? "supports" : "does not support");
 
+#ifdef HAVE_DRM_ATOMIC
+	if (b->universal_planes && !getenv("WESTON_DISABLE_ATOMIC")) {
+		ret = drmSetClientCap(b->drm.fd, DRM_CLIENT_CAP_ATOMIC, 1);
+		b->atomic_modeset = (ret == 0);
+	}
+#endif
+	weston_log("DRM: %s atomic modesetting\n",
+		   b->atomic_modeset ? "supports" : "does not support");
+
 	return 0;
 }
 
@@ -3032,6 +3064,16 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
 			.enum_values = plane_type_enums,
 			.num_enum_values = WDRM_PLANE_TYPE__COUNT,
 		},
+		[WDRM_PLANE_SRC_X] = { .name = "SRC_X", },
+		[WDRM_PLANE_SRC_Y] = { .name = "SRC_Y", },
+		[WDRM_PLANE_SRC_W] = { .name = "SRC_W", },
+		[WDRM_PLANE_SRC_H] = { .name = "SRC_H", },
+		[WDRM_PLANE_CRTC_X] = { .name = "CRTC_X", },
+		[WDRM_PLANE_CRTC_Y] = { .name = "CRTC_Y", },
+		[WDRM_PLANE_CRTC_W] = { .name = "CRTC_W", },
+		[WDRM_PLANE_CRTC_H] = { .name = "CRTC_H", },
+		[WDRM_PLANE_FB_ID] = { .name = "FB_ID", },
+		[WDRM_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
 	};
 
 	plane = zalloc(sizeof(*plane) +
@@ -3225,7 +3267,6 @@ create_sprites(struct drm_backend *b)
 	drmModePlane *kplane;
 	struct drm_plane *drm_plane;
 	uint32_t i;
-
 	kplane_res = drmModeGetPlaneResources(b->drm.fd);
 	if (!kplane_res) {
 		weston_log("failed to get plane resources: %s\n",
@@ -4284,6 +4325,7 @@ 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);
 
 	drmModeFreeConnector(output->connector);
 
@@ -4397,6 +4439,11 @@ create_output_for_connector(struct drm_backend *b,
 	static const struct drm_property_info connector_props[] = {
 		[WDRM_CONNECTOR_EDID] = { .name = "EDID" },
 		[WDRM_CONNECTOR_DPMS] = { .name = "DPMS" },
+		[WDRM_CONNECTOR_CRTC_ID] = { .name = "CRTC_ID", },
+	};
+	static const struct drm_property_info crtc_props[] = {
+		[WDRM_CRTC_MODE_ID] = { .name = "MODE_ID", },
+		[WDRM_CRTC_ACTIVE] = { .name = "ACTIVE", },
 	};
 
 	i = find_crtc_for_connector(b, resources, connector);
@@ -4435,6 +4482,16 @@ 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");
+		goto err;
+	}
+	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);
 	if (!props) {
-- 
2.14.3



More information about the wayland-devel mailing list