[PATCH weston v9 61/62] [XXX] compositor-drm: Support drmModeGetPlane2
Daniel Stone
daniels at collabora.com
Fri Mar 3 23:06:12 UTC 2017
GetPlane2 adds information about format modifiers; we can use these to
both feed GBM with the set of modifiers we want to use for rendering,
and also as an early-out test when we're trying to see if a FB will go
on a particular plane.
XXX: Depends on krh/bwidawsk's unmerged kernel/libdrm patches.
Signed-off-by: Daniel Stone <daniels at collabora.com>
---
configure.ac | 4 +++
libweston/compositor-drm.c | 78 ++++++++++++++++++++++++++++++++++++++++++----
libweston/meson.build | 5 +++
3 files changed, 81 insertions(+), 6 deletions(-)
v9: New. Not proposing to merge.
In order to merge the GETPLANE2 ioctl in the kernel, we need to
demonstrate viable userspace, with some acks that it looks like a
sane ABI for us to use with no pitfalls. So I would like an eye
cast over it for that, but this must not be merged until it lands
in finalised form.
diff --git a/configure.ac b/configure.ac
index 2937870..773f5ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -213,6 +213,10 @@ if test x$enable_drm_compositor = xyes; then
PKG_CHECK_MODULES(DRM_COMPOSITOR_MODIFIERS, [libdrm >= 2.4.71],
[AC_DEFINE([HAVE_DRM_ADDFB2_MODIFIERS], 1, [libdrm supports modifiers])],
[AC_MSG_WARN([libdrm does not support AddFB2 with modifiers])])
+ # XXX: Will be 2.4.75 ... ?
+ PKG_CHECK_MODULES(DRM_COMPOSITOR_GETPLANE2, [libdrm >= 2.4.74],
+ [AC_DEFINE([HAVE_DRM_GETPLANE2], 1, [libdrm supports GetPlane2])],
+ [AC_MSG_WARN([libdrm does not support GetPlane2])])
fi
diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c
index bf9571c..755f4f8 100644
--- a/libweston/compositor-drm.c
+++ b/libweston/compositor-drm.c
@@ -368,7 +368,11 @@ struct drm_plane {
struct wl_list link;
- uint32_t formats[];
+ struct {
+ uint32_t format;
+ uint32_t count_modifiers;
+ uint64_t *modifiers;
+ } formats[];
};
struct drm_output {
@@ -2658,7 +2662,19 @@ drm_output_prepare_overlay_view(struct drm_output_state *output_state,
/* Check whether the format is supported */
for (i = 0; i < p->count_formats; i++) {
- if (p->formats[i] == fb->format->format)
+ unsigned int j;
+
+ if (p->formats[i].format != fb->format->format)
+ continue;
+
+ if (!fb->modifier)
+ break;
+
+ for (j = 0; j < p->formats[i].count_modifiers; j++) {
+ if (p->formats[i].modifiers[j] == fb->modifier)
+ break;
+ }
+ if (j != p->formats[i].count_modifiers)
break;
}
if (i == p->count_formats)
@@ -3402,6 +3418,43 @@ init_pixman(struct drm_backend *b)
}
/**
+ * Populates the formats array for a drm_plane.
+ */
+#ifdef HAVE_DRM_GETPLANE2
+static bool
+populate_modifiers(struct drm_plane *plane, const drmModePlane *kplane,
+ int fmt_idx)
+{
+ unsigned int j;
+ unsigned int k = 0;
+ uint64_t *modifiers = NULL;
+ unsigned int size_modifiers = 0;
+
+ for (j = 0; j < kplane->count_format_modifiers; j++) {
+ struct drm_format_modifier *mod;
+ mod = &kplane->format_modifiers[j];
+ if (!(mod->formats & (1 << fmt_idx)))
+ continue;
+
+ if (size_modifiers <= k) {
+ size_modifiers += 8;
+ modifiers = realloc(modifiers,
+ size_modifiers *
+ sizeof(modifiers[0]));
+ if (!modifiers)
+ return false;
+ }
+ modifiers[k++] = mod->modifier;
+ }
+
+ plane->formats[fmt_idx].modifiers = modifiers;
+ plane->formats[fmt_idx].count_modifiers = k;
+
+ return true;
+}
+#endif
+
+/**
* Create a drm_plane for a hardware plane
*
* Creates one drm_plane structure for a hardware plane, and initialises its
@@ -3441,7 +3494,7 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
(type == WDRM_PLANE_TYPE_OVERLAY || (output && format)));
plane = zalloc(sizeof(*plane) +
- (sizeof(uint32_t) * num_formats));
+ (sizeof(plane->formats[0]) * num_formats));
if (!plane) {
weston_log("%s: out of memory\n", __func__);
return NULL;
@@ -3452,17 +3505,26 @@ drm_plane_create(struct drm_backend *b, const drmModePlane *kplane,
plane->state_cur->complete = true;
if (kplane) {
+ uint32_t i;
+
plane->possible_crtcs = kplane->possible_crtcs;
plane->plane_id = kplane->plane_id;
plane->count_formats = kplane->count_formats;
- memcpy(plane->formats, kplane->formats,
- kplane->count_formats * sizeof(kplane->formats[0]));
+ for (i = 0; i < kplane->count_formats; i++) {
+ plane->formats[i].format = kplane->formats[i];
+#ifdef HAVE_DRM_GETPLANE2
+ if (!populate_modifiers(plane, kplane, i)) {
+ weston_log("%s: out of memory\n", __func__);
+ return NULL;
+ }
+#endif
+ }
}
else {
plane->possible_crtcs = (1 << output->pipe);
plane->plane_id = 0;
plane->count_formats = 1;
- plane->formats[0] = format;
+ plane->formats[0].format = format;
}
props = drmModeObjectGetProperties(b->drm.fd, kplane->plane_id,
@@ -3621,7 +3683,11 @@ create_sprites(struct drm_backend *b)
}
for (i = 0; i < kplane_res->count_planes; i++) {
+#ifdef HAVE_DRM_GETPLANE2
+ kplane = drmModeGetPlane2(b->drm.fd, kplane_res->planes[i]);
+#else
kplane = drmModeGetPlane(b->drm.fd, kplane_res->planes[i]);
+#endif
if (!kplane)
continue;
diff --git a/libweston/meson.build b/libweston/meson.build
index 8127602..f139356 100644
--- a/libweston/meson.build
+++ b/libweston/meson.build
@@ -174,6 +174,11 @@ if get_option('backend_drm')
config_h.set('HAVE_DRM_ADDFB2_MODIFIERS', '1')
endif
+ # XXX: Will be 2.4.75 ... ?
+ if dep_drm.version().version_compare('>= 2.4.74')
+ config_h.set('HAVE_DRM_GETPLANE2', '1')
+ endif
+
plugin_drm = shared_library('drm-backend',
files_drm,
include_directories: include_directories('..', '../shared'),
--
2.9.3
More information about the wayland-devel
mailing list