xwayland-Detect-gbm_bo_get_fd_for_plane-at-runtime.patch

Description: xwayland: Detect gbm_bo_get_fd_for_plane at runtime
 `gbm_bo_get_fd_for_plane` was introduced in Mesa 21 but some
 proprietary GBM implementations (Xilinx) still haven't been updated
 to support it:
 ```
 /usr/bin/Xwayland: symbol lookup error: /usr/bin/Xwayland: undefined symbol: gbm_bo_get_fd_for_plane
 ```
 .
 Since distros would like to build a single Xwayland binary for all
 OEMs of the same architecture, we now make the function always
 available.
 .
 If a real implementation of `gbm_bo_get_fd_for_plane` exists at runtime
 then it will be used, otherwise fall back to `gbm_bo_get_fd` or fail.
Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
This commit is contained in:
su-fang 2023-04-21 14:21:47 +08:00
parent 474d22870b
commit eb8a09be2b
2 changed files with 31 additions and 7 deletions

View File

@ -32,6 +32,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <dlfcn.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <xf86drm.h> #include <xf86drm.h>
#include <drm_fourcc.h> #include <drm_fourcc.h>
@ -113,6 +114,33 @@ is_device_path_render_node (const char *device_path)
return is_render_node; return is_render_node;
} }
static int (*real_gbm_bo_get_fd_for_plane)(struct gbm_bo *, int);
static void
init_gbm_abi(void)
{
if (!real_gbm_bo_get_fd_for_plane) {
real_gbm_bo_get_fd_for_plane = dlsym(RTLD_NEXT,
"gbm_bo_get_fd_for_plane");
if (!real_gbm_bo_get_fd_for_plane)
LogMessageVerb(X_WARNING, 0,
"gbm_bo_get_fd_for_plane is not supported natively.\n");
}
}
static int
xwl_gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane)
{
if (real_gbm_bo_get_fd_for_plane)
return real_gbm_bo_get_fd_for_plane(bo, plane);
if (plane == 0)
return gbm_bo_get_fd(bo);
errno = ENOSYS;
return -1;
}
static PixmapPtr static PixmapPtr
xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
int depth) int depth)
@ -120,7 +148,6 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
PixmapPtr pixmap; PixmapPtr pixmap;
struct xwl_pixmap *xwl_pixmap; struct xwl_pixmap *xwl_pixmap;
struct xwl_screen *xwl_screen = xwl_screen_get(screen); 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); struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
uint64_t modifier = gbm_bo_get_modifier(bo); uint64_t modifier = gbm_bo_get_modifier(bo);
const int num_planes = gbm_bo_get_plane_count(bo); const int num_planes = gbm_bo_get_plane_count(bo);
@ -168,7 +195,6 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
}; };
for (plane = 0; plane < num_planes; plane++) fds[plane] = -1; for (plane = 0; plane < num_planes; plane++) fds[plane] = -1;
#endif
xwl_pixmap = calloc(1, sizeof(*xwl_pixmap)); xwl_pixmap = calloc(1, sizeof(*xwl_pixmap));
if (xwl_pixmap == NULL) if (xwl_pixmap == NULL)
@ -188,7 +214,6 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
xwl_pixmap->bo = bo; xwl_pixmap->bo = bo;
xwl_pixmap->buffer = NULL; xwl_pixmap->buffer = NULL;
#ifdef GBM_BO_FD_FOR_PLANE
if (xwl_gbm->dmabuf_capable) { if (xwl_gbm->dmabuf_capable) {
#define ADD_ATTR(attrs, num, attr) \ #define ADD_ATTR(attrs, num, attr) \
do { \ do { \
@ -203,7 +228,7 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
ADD_ATTR(img_attrs, attr_num, gbm_bo_get_format(bo)); ADD_ATTR(img_attrs, attr_num, gbm_bo_get_format(bo));
for (plane = 0; plane < num_planes; plane++) { for (plane = 0; plane < num_planes; plane++) {
fds[plane] = gbm_bo_get_fd_for_plane(bo, plane); fds[plane] = xwl_gbm_bo_get_fd_for_plane(bo, plane);
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_FD]); ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_FD]);
ADD_ATTR(img_attrs, attr_num, fds[plane]); ADD_ATTR(img_attrs, attr_num, fds[plane]);
ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_OFFSET]); ADD_ATTR(img_attrs, attr_num, planeAttrs[plane][PLANE_OFFSET]);
@ -230,7 +255,6 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
} }
} }
else else
#endif
{ {
xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display, xwl_pixmap->image = eglCreateImageKHR(xwl_screen->egl_display,
xwl_screen->egl_context, xwl_screen->egl_context,
@ -1062,6 +1086,8 @@ xwl_glamor_init_gbm(struct xwl_screen *xwl_screen)
return; return;
} }
init_gbm_abi();
dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key, dixSetPrivate(&xwl_screen->screen->devPrivates, &xwl_gbm_private_key,
xwl_gbm); xwl_gbm);

View File

@ -103,8 +103,6 @@ conf_data.set('GLAMOR_HAS_GBM_LINEAR',
build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 10.6') ? '1' : false) build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 10.6') ? '1' : false)
conf_data.set('GBM_BO_WITH_MODIFIERS', conf_data.set('GBM_BO_WITH_MODIFIERS',
build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 17.1') ? '1' : false) build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 17.1') ? '1' : false)
conf_data.set('GBM_BO_FD_FOR_PLANE',
build_glamor and gbm_dep.found() and gbm_dep.version().version_compare('>= 21.1') ? '1' : false)
conf_data.set_quoted('SERVER_MISC_CONFIG_PATH', serverconfigdir) conf_data.set_quoted('SERVER_MISC_CONFIG_PATH', serverconfigdir)
conf_data.set_quoted('PROJECTROOT', get_option('prefix')) conf_data.set_quoted('PROJECTROOT', get_option('prefix'))