diff options
author | Simon Ser <contact@emersion.fr> | 2023-02-27 17:06:51 +0100 |
---|---|---|
committer | Olivier Fourdan <ofourdan@redhat.com> | 2023-03-03 19:19:18 +0100 |
commit | 97233c9858bb19af11753454a4d394b0e1bca89c (patch) | |
tree | 6304c920496d380830a62cb12dc8719b576fa6f4 | |
parent | bdb023b34af5ef519fd8dc621b6e29f0c25d3612 (diff) | |
download | xserver-97233c9858bb19af11753454a4d394b0e1bca89c.tar.gz |
xwayland: use drmDevice to compare DRM devices
The linux_dmabuf_v1 protocol doesn't guarantee any DRM node type:
the compositor may send a primary node or a render node. Use
drmDevice so that device comparisons are node-type-insensitive.
Signed-off-by: Simon Ser <contact@emersion.fr>
Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1447
(cherry picked from commit 6f0b9deed66882aa18983eb35abca45207e37316)
-rw-r--r-- | hw/xwayland/xwayland-glamor-gbm.c | 13 | ||||
-rw-r--r-- | hw/xwayland/xwayland-glamor.c | 34 | ||||
-rw-r--r-- | hw/xwayland/xwayland-glamor.h | 5 | ||||
-rw-r--r-- | hw/xwayland/xwayland-window.c | 1 | ||||
-rw-r--r-- | hw/xwayland/xwayland-window.h | 5 |
5 files changed, 37 insertions, 21 deletions
diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c index dcad1df04..8e46f30f7 100644 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ b/hw/xwayland/xwayland-glamor-gbm.c @@ -53,7 +53,7 @@ #include "linux-dmabuf-unstable-v1-client-protocol.h" struct xwl_gbm_private { - dev_t device; + drmDevice *device; char *device_name; struct gbm_device *gbm; struct wl_drm *drm; @@ -460,6 +460,7 @@ xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen) if (xwl_gbm->device_name) free(xwl_gbm->device_name); + drmFreeDevice(&xwl_gbm->device); if (xwl_gbm->drm_fd) close(xwl_gbm->drm_fd); if (xwl_gbm->drm) @@ -784,7 +785,6 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device) struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); drm_magic_t magic; char *render_node_path = NULL; - struct stat stat; if (!is_device_path_render_node(device)) render_node_path = get_render_node_path(device); @@ -807,12 +807,11 @@ xwl_drm_handle_device(void *data, struct wl_drm *drm, const char *device) return; } - if (fstat(xwl_gbm->drm_fd, &stat)) { - ErrorF("wayland-egl: Could not stat file %s (%s)\n", - xwl_gbm->device_name, strerror(errno)); + if (drmGetDevice2(xwl_gbm->drm_fd, 0, &xwl_gbm->device) != 0) { + ErrorF("wayland-egl: Could not fetch DRM device %s\n", + xwl_gbm->device_name); return; } - xwl_gbm->device = stat.st_rdev; if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) { xwl_gbm->fd_render_node = 1; @@ -1111,7 +1110,7 @@ error: return FALSE; } -static dev_t xwl_gbm_get_main_device(struct xwl_screen *xwl_screen) +static drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen) { struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen); diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index e7cc7eaf0..edb028978 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -187,7 +187,7 @@ wl_drm_format_for_depth(int depth) } } -static dev_t +static drmDevice * xwl_screen_get_main_dev(struct xwl_screen *xwl_screen) { /* @@ -222,7 +222,7 @@ xwl_get_formats(struct xwl_format *format_array, int format_array_len, } static Bool -xwl_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, dev_t device, +xwl_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, drmDevice *device, uint32_t *num_formats, uint32_t **formats) { uint32_t *ret = NULL; @@ -230,7 +230,7 @@ xwl_get_formats_for_device(struct xwl_dmabuf_feedback *xwl_feedback, dev_t devic /* go through all matching sets of tranches for the window's device */ for (int i = 0; i < xwl_feedback->dev_formats_len; i++) { - if (xwl_feedback->dev_formats[i].drm_dev == device) { + if (drmDevicesEqual(xwl_feedback->dev_formats[i].drm_dev, device)) { struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i]; /* Append the formats from this tranche to the list */ @@ -273,7 +273,7 @@ xwl_glamor_get_formats(ScreenPtr screen, return FALSE; if (xwl_screen->dmabuf_protocol_version >= 4) { - dev_t main_dev = xwl_screen_get_main_dev(xwl_screen); + drmDevice *main_dev = xwl_screen_get_main_dev(xwl_screen); return xwl_get_formats_for_device(&xwl_screen->default_feedback, main_dev, num_formats, formats); @@ -320,7 +320,7 @@ xwl_get_modifiers_for_format(struct xwl_format *format_array, int num_formats, } static Bool -xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, dev_t device, +xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, drmDevice *device, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers) { @@ -328,7 +328,7 @@ xwl_get_modifiers_for_device(struct xwl_dmabuf_feedback *feedback, dev_t device, for (int i = 0; i < feedback->dev_formats_len; i++) { struct xwl_device_formats *dev_formats = &feedback->dev_formats[i]; - if (dev_formats->drm_dev == device && + if (drmDevicesEqual(dev_formats->drm_dev, device) && xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats, format, num_modifiers, modifiers)) return TRUE; @@ -342,7 +342,7 @@ xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format, uint32_t *num_modifiers, uint64_t **modifiers) { struct xwl_screen *xwl_screen = xwl_screen_get(screen); - dev_t main_dev; + drmDevice *main_dev; /* Explicitly zero the count as the caller may ignore the return value */ *num_modifiers = 0; @@ -368,7 +368,7 @@ xwl_glamor_get_drawable_modifiers(DrawablePtr drawable, uint32_t format, { struct xwl_screen *xwl_screen = xwl_screen_get(drawable->pScreen); struct xwl_window *xwl_window; - dev_t main_dev; + drmDevice *main_dev; *num_modifiers = 0; *modifiers = NULL; @@ -475,11 +475,15 @@ xwl_dmabuf_feedback_main_device(void *data, struct wl_array *dev) { struct xwl_dmabuf_feedback *xwl_feedback = data; + dev_t devid; xwl_check_reset_tranche_info(xwl_feedback); assert(dev->size == sizeof(dev_t)); - memcpy(&xwl_feedback->main_dev, dev->data, sizeof(dev_t)); + memcpy(&devid, dev->data, sizeof(dev_t)); + + if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->main_dev) != 0) + ErrorF("linux_dmabuf_feedback.main_device: Failed to fetch DRM device\n"); } static void @@ -488,11 +492,15 @@ xwl_dmabuf_feedback_tranche_target_device(void *data, struct wl_array *dev) { struct xwl_dmabuf_feedback *xwl_feedback = data; + dev_t devid; xwl_check_reset_tranche_info(xwl_feedback); assert(dev->size == sizeof(dev_t)); - memcpy(&xwl_feedback->tmp_tranche.drm_dev, dev->data, sizeof(dev_t)); + memcpy(&devid, dev->data, sizeof(dev_t)); + + if (drmGetDeviceFromDevId(devid, 0, &xwl_feedback->tmp_tranche.drm_dev) != 0) + ErrorF("linux_dmabuf_feedback.tranche_target_device: Failed to fetch DRM device\n"); } static void @@ -564,6 +572,11 @@ xwl_dmabuf_feedback_tranche_done(void *data, * triggered first */ + if (xwl_feedback->tmp_tranche.drm_dev == NULL) { + xwl_device_formats_destroy(&xwl_feedback->tmp_tranche); + goto out; + } + /* * First check if there is an existing tranche for this device+flags combo. We * will combine it with this tranche, since we can only send one modifier list @@ -598,6 +611,7 @@ xwl_dmabuf_feedback_tranche_done(void *data, sizeof(struct xwl_device_formats)); } +out: /* reset the tranche */ memset(&xwl_feedback->tmp_tranche, 0, sizeof(struct xwl_device_formats)); } diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h index aed65b50f..0ecd25b38 100644 --- a/hw/xwayland/xwayland-glamor.h +++ b/hw/xwayland/xwayland-glamor.h @@ -31,6 +31,7 @@ #include <sys/types.h> #include <wayland-client.h> +#include <xf86drm.h> #include "xwayland-types.h" @@ -99,10 +100,10 @@ struct xwl_egl_backend { */ Bool (*check_flip)(PixmapPtr pixmap); - /* Called to get the dev_t of the primary GPU that this backend + /* Called to get the DRM device of the primary GPU that this backend * is set up on. */ - dev_t (*get_main_device)(struct xwl_screen *xwl_screen); + drmDevice *(*get_main_device)(struct xwl_screen *xwl_screen); }; #ifdef XWL_HAS_GLAMOR diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index eba81b8cb..e159743a0 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -1014,6 +1014,7 @@ xwl_device_formats_destroy(struct xwl_device_formats *dev_formats) for (int j = 0; j < dev_formats->num_formats; j++) free(dev_formats->formats[j].modifiers); free(dev_formats->formats); + drmFreeDevice(&dev_formats->drm_dev); } void diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h index c5c42f097..65dfb69ff 100644 --- a/hw/xwayland/xwayland-window.h +++ b/hw/xwayland/xwayland-window.h @@ -38,6 +38,7 @@ #include <propertyst.h> #include <validate.h> #include <wayland-util.h> +#include <xf86drm.h> #include "xwayland-types.h" @@ -54,7 +55,7 @@ struct xwl_format_table_entry { }; struct xwl_device_formats { - dev_t drm_dev; + drmDevice *drm_dev; int supports_scanout; uint32_t num_formats; struct xwl_format *formats; @@ -74,7 +75,7 @@ struct xwl_format_table { struct xwl_dmabuf_feedback { struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback; struct xwl_format_table format_table; - dev_t main_dev; + drmDevice *main_dev; /* * This will be filled in during wl events and copied to * dev_formats on dmabuf_feedback.tranche_done |