diff options
author | James Jones <jajones@nvidia.com> | 2021-03-26 12:50:08 -0700 |
---|---|---|
committer | Olivier Fourdan <ofourdan@redhat.com> | 2021-10-18 14:17:28 +0200 |
commit | ab1c873f9d2445d7ed46d71c3589b4c448a6cc12 (patch) | |
tree | bab1f3d92a7bdd6a5b88a27f21ec3ef18d5e5ad8 | |
parent | ce6d68d23daa76d03fac3cf878dc4adb32f9fd92 (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.c | 104 | ||||
-rw-r--r-- | include/dix-config.h.in | 3 | ||||
-rw-r--r-- | include/meson.build | 2 |
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')) |