summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPekka Paalanen <pekka.paalanen@collabora.co.uk>2016-11-15 22:07:49 +0000
committerDaniel Stone <daniels@collabora.com>2017-02-07 19:16:32 +0000
commitf1676789e9bb10d0b663f2d90015090ff3e3d733 (patch)
treeed1caab8ad258ebce142706ff3d538fd8d1b527f
parenta8c15b17989f0b663eff3f214fc19ccef268688d (diff)
compositor-drm: Discover atomic properties
Set the atomic client cap, where it exists, and use this to discover the plane/CRTC/connector properties we require for atomic modesetting. Differential Revision: https://phabricator.freedesktop.org/D1503 Signed-off-by: Daniel Stone <daniels@collabora.com> Co-authored-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
-rw-r--r--configure.ac3
-rw-r--r--libweston/compositor-drm.c143
2 files changed, 146 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 7a6bb271..be3d7dbe 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 mtdev >= 1.1.0])
+ 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 89848bb6..bff4ca50 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -100,6 +100,16 @@ struct property_item {
*/
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
};
@@ -123,6 +133,37 @@ struct plane_properties {
};
/**
+ * List of properties attached to DRM CRTCs
+ */
+enum wdrm_crtc_property {
+ WDRM_CRTC_MODE_ID = 0,
+ WDRM_CRTC_ACTIVE,
+ WDRM_CRTC__COUNT
+};
+
+/**
+ * List of properties attached to DRM connectors
+ */
+enum wdrm_connector_property {
+ WDRM_CONNECTOR_CRTC_ID = 0,
+ WDRM_CONNECTOR__COUNT
+};
+
+/**
+ * Holding structure for CRTC properties.
+ */
+struct crtc_properties {
+ struct property_item item[WDRM_CRTC__COUNT];
+};
+
+/**
+ * Holding structure for CRTC properties.
+ */
+struct connector_properties {
+ struct property_item item[WDRM_CONNECTOR__COUNT];
+};
+
+/**
* Mode for drm_output_state_duplicate.
*/
enum drm_output_state_duplicate_mode {
@@ -171,6 +212,7 @@ struct drm_backend {
int cursors_are_broken;
bool universal_planes;
+ bool atomic_modeset;
int use_pixman;
@@ -300,6 +342,9 @@ struct drm_output {
drmModePropertyPtr dpms_prop;
uint32_t gbm_format;
+ struct crtc_properties props_crtc;
+ struct connector_properties props_conn;
+
int vblank_pending;
int page_flip_pending;
int destroy_pending;
@@ -590,6 +635,16 @@ plane_properties_init(struct drm_plane *plane)
{
static const char * const plane_property_names[] = {
[WDRM_PLANE_TYPE] = "type",
+ [WDRM_PLANE_SRC_X] = "SRC_X",
+ [WDRM_PLANE_SRC_Y] = "SRC_Y",
+ [WDRM_PLANE_SRC_W] = "SRC_W",
+ [WDRM_PLANE_SRC_H] = "SRC_H",
+ [WDRM_PLANE_CRTC_X] = "CRTC_X",
+ [WDRM_PLANE_CRTC_Y] = "CRTC_Y",
+ [WDRM_PLANE_CRTC_W] = "CRTC_W",
+ [WDRM_PLANE_CRTC_H] = "CRTC_H",
+ [WDRM_PLANE_FB_ID] = "FB_ID",
+ [WDRM_PLANE_CRTC_ID] = "CRTC_ID",
};
static const char * const plane_type_names[] = {
[WDRM_PLANE_TYPE_PRIMARY] = "Primary",
@@ -682,6 +737,84 @@ drm_plane_get_type(struct drm_plane *plane)
return WDRM_PLANE_TYPE_OVERLAY;
}
+/**
+ * Initialise DRM properties for CRTC and connector
+ *
+ * Set up the holding structures to track DRM object properties set on the CRTC
+ * and connector associated with an output.
+ * Free the memory allocated here with output_properties_release.
+ *
+ * @param b DRM backend
+ * @param output Output to configure
+ */
+static bool output_properties_init(struct drm_backend *b,
+ struct drm_output *output)
+{
+ static const char * const crtc_property_names[] = {
+ [WDRM_CRTC_MODE_ID] = "MODE_ID",
+ [WDRM_CRTC_ACTIVE] = "ACTIVE",
+ };
+ static const char * const connector_property_names[] = {
+ [WDRM_CONNECTOR_CRTC_ID] = "CRTC_ID",
+ };
+ uint32_t valid_mask, required_mask;
+
+ static_assert(ARRAY_LENGTH(crtc_property_names) == WDRM_CRTC__COUNT,
+ "crtc_property_names mismatch with the enum");
+ static_assert(WDRM_CRTC__COUNT <= 32,
+ "need more bits for crtc item_valid_mask");
+
+ static_assert(ARRAY_LENGTH(connector_property_names) == WDRM_CONNECTOR__COUNT,
+ "connector_property_names mismatch with the enum");
+ static_assert(WDRM_CONNECTOR__COUNT <= 32,
+ "need more bits for connector item_valid_mask");
+
+ valid_mask = drm_properties_get_from_obj(b,
+ output->props_crtc.item,
+ crtc_property_names,
+ WDRM_CRTC__COUNT,
+ output->crtc_id,
+ DRM_MODE_OBJECT_CRTC);
+
+ required_mask = 0;
+ if ((valid_mask & required_mask) != required_mask) {
+ weston_log("DRM error: failed to look up all CRTC properties "
+ "(wanted 0x%x got 0x%x) on ID %d\n",
+ required_mask, valid_mask, output->crtc_id);
+ return false;
+ }
+
+ valid_mask = drm_properties_get_from_obj(b,
+ output->props_conn.item,
+ connector_property_names,
+ WDRM_CONNECTOR__COUNT,
+ output->connector_id,
+ DRM_MODE_OBJECT_CONNECTOR);
+ required_mask = 0;
+ if ((valid_mask & required_mask) != required_mask) {
+ weston_log("DRM error: failed to look up all connector properties "
+ "(wanted 0x%x got 0x%x) on ID %d\n",
+ required_mask, valid_mask, output->connector_id);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Free DRM CRTC and connector properties
+ *
+ * The counterpart to output_properties_init.
+ *
+ * @param output Output to release properties for
+ */
+static void output_properties_release(struct drm_output *output)
+{
+ property_item_array_release(output->props_crtc.item, WDRM_CRTC__COUNT);
+ property_item_array_release(output->props_conn.item,
+ WDRM_CONNECTOR__COUNT);
+}
+
static void
drm_output_set_cursor(struct drm_output_state *output_state);
@@ -2552,6 +2685,13 @@ 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
+ 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;
}
@@ -3816,6 +3956,7 @@ drm_output_destroy(struct weston_output *base)
assert(!output->state_last);
drm_output_state_free(output->state_cur);
+ output_properties_release(output);
assert(!output->state_pending);
free(output);
@@ -3899,6 +4040,8 @@ create_output_for_connector(struct drm_backend *b,
output->base.name = make_connector_name(connector);
output->base.gamma_size = origcrtc->gamma_size;
+ output_properties_init(b, output);
+
output->destroy_pending = 0;
output->disable_pending = 0;