[PATCH v15 33/34] compositor-drm: Support modifiers with GBM

Daniel Stone daniels at collabora.com
Mon Feb 5 18:44:42 UTC 2018


Use the extended GBM allocator interface to support modifiers and
multi-planar BOs.

Signed-off-by: Daniel Stone <daniels at collabora.com>
---
 configure.ac               |  3 +++
 libweston/compositor-drm.c | 57 ++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 993ef8912..1fac26dde 100644
--- a/configure.ac
+++ b/configure.ac
@@ -215,6 +215,9 @@ if test x$enable_drm_compositor = xyes; then
   PKG_CHECK_MODULES(DRM_COMPOSITOR_FORMATS_BLOB, [libdrm >= 2.4.83],
 		    [AC_DEFINE([HAVE_DRM_FORMATS_BLOB], 1, [libdrm supports modifier advertisement])],
 		    [AC_MSG_WARN([libdrm does not support modifier advertisement])])
+  PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM_MODIFIERS, [gbm >= 17.1],
+		    [AC_DEFINE([HAVE_GBM_MODIFIERS], 1, [GBM supports modifiers])],
+		    [AC_MSG_WARN([GBM does not support modifiers])])
   PKG_CHECK_MODULES(DRM_COMPOSITOR_GBM, [gbm >= 17.2],
 		    [AC_DEFINE([HAVE_GBM_FD_IMPORT], 1, [gbm supports import with modifiers])],
 		    [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 b88ff97cd..48ce19c09 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -1116,6 +1116,9 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
 		   bool is_opaque, enum drm_fb_type type)
 {
 	struct drm_fb *fb = gbm_bo_get_user_data(bo);
+#ifdef HAVE_GBM_MODIFIERS
+	int i;
+#endif
 
 	if (fb) {
 		assert(fb->type == type);
@@ -1129,15 +1132,25 @@ drm_fb_get_from_bo(struct gbm_bo *bo, struct drm_backend *backend,
 	fb->type = type;
 	fb->refcnt = 1;
 	fb->bo = bo;
+	fb->fd = backend->drm.fd;
 
 	fb->width = gbm_bo_get_width(bo);
 	fb->height = gbm_bo_get_height(bo);
+	fb->format = pixel_format_get_info(gbm_bo_get_format(bo));
+	fb->size = 0;
+
+#ifdef HAVE_GBM_MODIFIERS
+	fb->modifier = gbm_bo_get_modifier(bo);
+	for (i = 0; i < gbm_bo_get_plane_count(bo); i++) {
+		fb->strides[i] = gbm_bo_get_stride_for_plane(bo, i);
+		fb->handles[i] = gbm_bo_get_handle_for_plane(bo, i).u32;
+		fb->offsets[i] = gbm_bo_get_offset(bo, i);
+	}
+#else
 	fb->strides[0] = gbm_bo_get_stride(bo);
 	fb->handles[0] = gbm_bo_get_handle(bo).u32;
-	fb->format = pixel_format_get_info(gbm_bo_get_format(bo));
 	fb->modifier = DRM_FORMAT_MOD_INVALID;
-	fb->size = fb->strides[0] * fb->height;
-	fb->fd = backend->drm.fd;
+#endif
 
 	if (!fb->format) {
 		weston_log("couldn't look up format 0x%lx\n",
@@ -4365,13 +4378,39 @@ drm_output_init_egl(struct drm_output *output, struct drm_backend *b)
 		fallback_format_for(output->gbm_format),
 	};
 	int n_formats = 1;
+	struct weston_mode *mode = output->base.current_mode;
+	struct drm_plane *plane = output->scanout_plane;
+	unsigned int i;
+
+	for (i = 0; i < plane->count_formats; i++) {
+		if (plane->formats[i].format == output->gbm_format)
+			break;
+	}
+
+	if (i == plane->count_formats) {
+		/* XXX: better error message */
+		weston_log("can't use format for output\n");
+		return -1;
+	}
+
+#ifdef HAVE_GBM_MODIFIERS
+	if (plane->formats[i].count_modifiers > 0) {
+		output->gbm_surface =
+			gbm_surface_create_with_modifiers(b->gbm,
+							  mode->width,
+							  mode->height,
+							  format[0],
+							  plane->formats[i].modifiers,
+							  plane->formats[i].count_modifiers);
+	} else
+#endif
+	{
+		output->gbm_surface =
+		    gbm_surface_create(b->gbm, mode->width, mode->height,
+				       format[0],
+				       GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+	}
 
-	output->gbm_surface = gbm_surface_create(b->gbm,
-					     output->base.current_mode->width,
-					     output->base.current_mode->height,
-					     format[0],
-					     GBM_BO_USE_SCANOUT |
-					     GBM_BO_USE_RENDERING);
 	if (!output->gbm_surface) {
 		weston_log("failed to create gbm surface\n");
 		return -1;
-- 
2.14.3



More information about the wayland-devel mailing list