summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Jones <jajones@nvidia.com>2021-03-26 12:50:08 -0700
committerOlivier Fourdan <ofourdan@redhat.com>2021-10-18 14:17:28 +0200
commitab1c873f9d2445d7ed46d71c3589b4c448a6cc12 (patch)
treebab1f3d92a7bdd6a5b88a27f21ec3ef18d5e5ad8
parentce6d68d23daa76d03fac3cf878dc4adb32f9fd92 (diff)
Use EGL_LINUX_DMA_BUF_EXT to create GBM bo EGLImages
Xwayland was passing GBM bos directly to eglCreateImageKHR using the EGL_NATIVE_PIXMAP_KHR target. Given the EGL GBM platform spec claims it is invalid to create a EGLSurface from a native pixmap on the GBM platform, implying there is no mapping between GBM objects and EGL's concept of native pixmaps, this seems a bit questionable. This change modifies the bo import function to extract all the required data from the bo and then imports it as a dma-buf instead when the dma-buf + modifiers path is available. Signed-off-by: James Jones <jajones@nvidia.com> Reviewed-by: Simon Ser <contact@emersion.fr> (cherry picked from commit f15729376d7c7ef183bd8f77156c281ff84c2bd9)
-rw-r--r--hw/xwayland/xwayland-glamor-gbm.c104
-rw-r--r--include/dix-config.h.in3
-rw-r--r--include/meson.build2
3 files changed, 105 insertions, 4 deletions
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c
index 12d820e44..386266a4e 100644
--- a/hw/xwayland/xwayland-glamor-gbm.c
+++ b/hw/xwayland/xwayland-glamor-gbm.c
@@ -120,6 +120,55 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
PixmapPtr pixmap;
struct xwl_pixmap *xwl_pixmap;
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+#ifdef GBM_BO_FD_FOR_PLANE
+ struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
+ uint64_t modifier = gbm_bo_get_modifier(bo);
+ const int num_planes = gbm_bo_get_plane_count(bo);
+ int fds[GBM_MAX_PLANES];
+ int plane;
+ int attr_num = 0;
+ EGLint img_attrs[64] = {0};
+ enum PlaneAttrs {
+ PLANE_FD,
+ PLANE_OFFSET,
+ PLANE_PITCH,
+ PLANE_MODIFIER_LO,
+ PLANE_MODIFIER_HI,
+ NUM_PLANE_ATTRS
+ };
+ static const EGLint planeAttrs[][NUM_PLANE_ATTRS] = {
+ {
+ EGL_DMA_BUF_PLANE0_FD_EXT,
+ EGL_DMA_BUF_PLANE0_OFFSET_EXT,
+ EGL_DMA_BUF_PLANE0_PITCH_EXT,
+ EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT,
+ EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT,
+ },
+ {
+ EGL_DMA_BUF_PLANE1_FD_EXT,
+ EGL_DMA_BUF_PLANE1_OFFSET_EXT,
+ EGL_DMA_BUF_PLANE1_PITCH_EXT,
+ EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT,
+ EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT,
+ },
+ {
+ EGL_DMA_BUF_PLANE2_FD_EXT,
+ EGL_DMA_BUF_PLANE2_OFFSET_EXT,
+ EGL_DMA_BUF_PLANE2_PITCH_EXT,
+ EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT,
+ EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT,
+ },
+ {
+ EGL_DMA_BUF_PLANE3_FD_EXT,
+ EGL_DMA_BUF_PLANE3_OFFSET_EXT,
+ EGL_DMA_BUF_PLANE3_PITCH_EXT,
+ EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT,
+ EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT,
+ },
+ };
+
+ for (plane = 0; plane < num_planes; plane++) fds[plane] = -1;
+#endif
xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
if (xwl_pixmap == NULL)
@@ -138,10 +187,57 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
xwl_glamor_egl_make_current(xwl_screen);
xwl_pixmap->bo = bo;
xwl_pixmap->buffer = NULL;
- xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
- xwl_screen->egl_context,
- EGL_NATIVE_PIXMAP_KHR,
- xwl_pixmap->bo, NULL);
+
+#ifdef GBM_BO_FD_FOR_PLANE
+ if (xwl_gbm->dmabuf_capable) {
+#define ADD_ATTR(attrs, num, attr) \
+ do { \
+ assert(((num) + 1) < (sizeof(attrs) / sizeof((attrs)[0]))); \
+ (attrs)[(num)++] = (attr); \
+ } while (0)
+ ADD_ATTR(img_attrs, attr_num, EGL_WIDTH);
+ ADD_ATTR(img_attrs, attr_num, gbm_bo_get_width(bo));
+ ADD_ATTR(img_attrs, attr_num, EGL_HEIGHT);
+ ADD_ATTR(img_attrs, attr_num, gbm_bo_get_height(bo));
+ ADD_ATTR(img_attrs, attr_num, EGL_LINUX_DRM_FOURCC_EXT);
+ ADD_ATTR(img_attrs, attr_num, gbm_bo_get_format(bo));
+
+ for (plane = 0; plane < num_planes; plane++) {
+ fds[plane] = gbm_bo_get_fd_for_plane(bo, plane);
+ ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_FD]);
+ ADD_ATTR(img_attrs, attr_num, fds[plane]);
+ ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_OFFSET]);
+ ADD_ATTR(img_attrs, attr_num, gbm_bo_get_offset(bo, plane));
+ ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_PITCH]);
+ ADD_ATTR(img_attrs, attr_num, gbm_bo_get_stride_for_plane(bo, plane));
+ ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_LO]);
+ ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier & 0xFFFFFFFFULL));
+ ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_MODIFIER_HI]);
+ ADD_ATTR(img_attrs, attr_num, (uint32_t)(modifier >> 32ULL));
+ }
+ ADD_ATTR(img_attrs, attr_num, EGL_NONE);
+#undef ADD_ATTR
+
+ xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
+ EGL_NO_CONTEXT,
+ EGL_LINUX_DMA_BUF_EXT,
+ NULL,
+ img_attrs);
+
+ for (plane = 0; plane < num_planes; plane++) {
+ close(fds[plane]);
+ fds[plane] = -1;
+ }
+ }
+ else
+#endif
+ {
+ xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
+ xwl_screen->egl_context,
+ EGL_NATIVE_PIXMAP_KHR,
+ xwl_pixmap->bo, NULL);
+ }
+
if (xwl_pixmap->image == EGL_NO_IMAGE_KHR)
goto error;
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index a7fead0d5..6fdfba903 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -443,6 +443,9 @@
/* GBM has modifiers support */
#undef GBM_BO_WITH_MODIFIERS
+/* GBM has gbm_bo_get_fd_for_plane function */
+#undef GBM_BO_FD_FOR_PLANE
+
/* Glamor can use eglQueryDmaBuf* functions */
#undef GLAMOR_HAS_EGL_QUERY_DMABUF
diff --git a/include/meson.build b/include/meson.build
index d3f2db840..885b3cef7 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -96,6 +96,8 @@ conf_data.set('GLAMOR_HAS_GBM_LINEAR',
build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 10.6'))
conf_data.set('GBM_BO_WITH_MODIFIERS',
build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 17.1'))
+conf_data.set('GBM_BO_FD_FOR_PLANE',
+ build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 21.1'))
conf_data.set_quoted('SERVER_MISC_CONFIG_PATH', serverconfigdir)
conf_data.set_quoted('PROJECTROOT', get_option('prefix'))