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
This commit is contained in:
parent
5a742ab876
commit
6f0b9deed6
|
@ -53,7 +53,7 @@
|
||||||
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
#include "linux-dmabuf-unstable-v1-client-protocol.h"
|
||||||
|
|
||||||
struct xwl_gbm_private {
|
struct xwl_gbm_private {
|
||||||
dev_t device;
|
drmDevice *device;
|
||||||
char *device_name;
|
char *device_name;
|
||||||
struct gbm_device *gbm;
|
struct gbm_device *gbm;
|
||||||
struct wl_drm *drm;
|
struct wl_drm *drm;
|
||||||
|
@ -460,6 +460,7 @@ xwl_glamor_gbm_cleanup(struct xwl_screen *xwl_screen)
|
||||||
|
|
||||||
if (xwl_gbm->device_name)
|
if (xwl_gbm->device_name)
|
||||||
free(xwl_gbm->device_name);
|
free(xwl_gbm->device_name);
|
||||||
|
drmFreeDevice(&xwl_gbm->device);
|
||||||
if (xwl_gbm->drm_fd)
|
if (xwl_gbm->drm_fd)
|
||||||
close(xwl_gbm->drm_fd);
|
close(xwl_gbm->drm_fd);
|
||||||
if (xwl_gbm->drm)
|
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);
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
drm_magic_t magic;
|
drm_magic_t magic;
|
||||||
char *render_node_path = NULL;
|
char *render_node_path = NULL;
|
||||||
struct stat stat;
|
|
||||||
|
|
||||||
if (!is_device_path_render_node(device))
|
if (!is_device_path_render_node(device))
|
||||||
render_node_path = get_render_node_path(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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(xwl_gbm->drm_fd, &stat)) {
|
if (drmGetDevice2(xwl_gbm->drm_fd, 0, &xwl_gbm->device) != 0) {
|
||||||
ErrorF("wayland-egl: Could not stat file %s (%s)\n",
|
ErrorF("wayland-egl: Could not fetch DRM device %s\n",
|
||||||
xwl_gbm->device_name, strerror(errno));
|
xwl_gbm->device_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xwl_gbm->device = stat.st_rdev;
|
|
||||||
|
|
||||||
if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) {
|
if (drmGetNodeTypeFromFd(xwl_gbm->drm_fd) == DRM_NODE_RENDER) {
|
||||||
xwl_gbm->fd_render_node = 1;
|
xwl_gbm->fd_render_node = 1;
|
||||||
|
@ -1111,7 +1110,7 @@ error:
|
||||||
return FALSE;
|
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);
|
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
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
|
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 *num_formats, uint32_t **formats)
|
||||||
{
|
{
|
||||||
uint32_t *ret = NULL;
|
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 */
|
/* go through all matching sets of tranches for the window's device */
|
||||||
for (int i = 0; i < xwl_feedback->dev_formats_len; i++) {
|
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];
|
struct xwl_device_formats *dev_formats = &xwl_feedback->dev_formats[i];
|
||||||
|
|
||||||
/* Append the formats from this tranche to the list */
|
/* Append the formats from this tranche to the list */
|
||||||
|
@ -273,7 +273,7 @@ xwl_glamor_get_formats(ScreenPtr screen,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (xwl_screen->dmabuf_protocol_version >= 4) {
|
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,
|
return xwl_get_formats_for_device(&xwl_screen->default_feedback, main_dev,
|
||||||
num_formats, formats);
|
num_formats, formats);
|
||||||
|
@ -320,7 +320,7 @@ xwl_get_modifiers_for_format(struct xwl_format *format_array, int num_formats,
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bool
|
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,
|
uint32_t format, uint32_t *num_modifiers,
|
||||||
uint64_t **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++) {
|
for (int i = 0; i < feedback->dev_formats_len; i++) {
|
||||||
struct xwl_device_formats *dev_formats = &feedback->dev_formats[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,
|
xwl_get_modifiers_for_format(dev_formats->formats, dev_formats->num_formats,
|
||||||
format, num_modifiers, modifiers))
|
format, num_modifiers, modifiers))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -342,7 +342,7 @@ xwl_glamor_get_modifiers(ScreenPtr screen, uint32_t format,
|
||||||
uint32_t *num_modifiers, uint64_t **modifiers)
|
uint32_t *num_modifiers, uint64_t **modifiers)
|
||||||
{
|
{
|
||||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
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 */
|
/* Explicitly zero the count as the caller may ignore the return value */
|
||||||
*num_modifiers = 0;
|
*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_screen *xwl_screen = xwl_screen_get(drawable->pScreen);
|
||||||
struct xwl_window *xwl_window;
|
struct xwl_window *xwl_window;
|
||||||
dev_t main_dev;
|
drmDevice *main_dev;
|
||||||
|
|
||||||
*num_modifiers = 0;
|
*num_modifiers = 0;
|
||||||
*modifiers = NULL;
|
*modifiers = NULL;
|
||||||
|
@ -475,11 +475,15 @@ xwl_dmabuf_feedback_main_device(void *data,
|
||||||
struct wl_array *dev)
|
struct wl_array *dev)
|
||||||
{
|
{
|
||||||
struct xwl_dmabuf_feedback *xwl_feedback = data;
|
struct xwl_dmabuf_feedback *xwl_feedback = data;
|
||||||
|
dev_t devid;
|
||||||
|
|
||||||
xwl_check_reset_tranche_info(xwl_feedback);
|
xwl_check_reset_tranche_info(xwl_feedback);
|
||||||
|
|
||||||
assert(dev->size == sizeof(dev_t));
|
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
|
static void
|
||||||
|
@ -488,11 +492,15 @@ xwl_dmabuf_feedback_tranche_target_device(void *data,
|
||||||
struct wl_array *dev)
|
struct wl_array *dev)
|
||||||
{
|
{
|
||||||
struct xwl_dmabuf_feedback *xwl_feedback = data;
|
struct xwl_dmabuf_feedback *xwl_feedback = data;
|
||||||
|
dev_t devid;
|
||||||
|
|
||||||
xwl_check_reset_tranche_info(xwl_feedback);
|
xwl_check_reset_tranche_info(xwl_feedback);
|
||||||
|
|
||||||
assert(dev->size == sizeof(dev_t));
|
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
|
static void
|
||||||
|
@ -564,6 +572,11 @@ xwl_dmabuf_feedback_tranche_done(void *data,
|
||||||
* triggered first
|
* 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
|
* 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
|
* 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));
|
sizeof(struct xwl_device_formats));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
/* reset the tranche */
|
/* reset the tranche */
|
||||||
memset(&xwl_feedback->tmp_tranche, 0, sizeof(struct xwl_device_formats));
|
memset(&xwl_feedback->tmp_tranche, 0, sizeof(struct xwl_device_formats));
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
|
||||||
#include "xwayland-types.h"
|
#include "xwayland-types.h"
|
||||||
|
|
||||||
|
@ -99,10 +100,10 @@ struct xwl_egl_backend {
|
||||||
*/
|
*/
|
||||||
Bool (*check_flip)(PixmapPtr pixmap);
|
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.
|
* 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
|
#ifdef XWL_HAS_GLAMOR
|
||||||
|
|
|
@ -1014,6 +1014,7 @@ xwl_device_formats_destroy(struct xwl_device_formats *dev_formats)
|
||||||
for (int j = 0; j < dev_formats->num_formats; j++)
|
for (int j = 0; j < dev_formats->num_formats; j++)
|
||||||
free(dev_formats->formats[j].modifiers);
|
free(dev_formats->formats[j].modifiers);
|
||||||
free(dev_formats->formats);
|
free(dev_formats->formats);
|
||||||
|
drmFreeDevice(&dev_formats->drm_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <propertyst.h>
|
#include <propertyst.h>
|
||||||
#include <validate.h>
|
#include <validate.h>
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
|
#include <xf86drm.h>
|
||||||
|
|
||||||
#include "xwayland-types.h"
|
#include "xwayland-types.h"
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ struct xwl_format_table_entry {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xwl_device_formats {
|
struct xwl_device_formats {
|
||||||
dev_t drm_dev;
|
drmDevice *drm_dev;
|
||||||
int supports_scanout;
|
int supports_scanout;
|
||||||
uint32_t num_formats;
|
uint32_t num_formats;
|
||||||
struct xwl_format *formats;
|
struct xwl_format *formats;
|
||||||
|
@ -74,7 +75,7 @@ struct xwl_format_table {
|
||||||
struct xwl_dmabuf_feedback {
|
struct xwl_dmabuf_feedback {
|
||||||
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback;
|
struct zwp_linux_dmabuf_feedback_v1 *dmabuf_feedback;
|
||||||
struct xwl_format_table format_table;
|
struct xwl_format_table format_table;
|
||||||
dev_t main_dev;
|
drmDevice *main_dev;
|
||||||
/*
|
/*
|
||||||
* This will be filled in during wl events and copied to
|
* This will be filled in during wl events and copied to
|
||||||
* dev_formats on dmabuf_feedback.tranche_done
|
* dev_formats on dmabuf_feedback.tranche_done
|
||||||
|
|
Loading…
Reference in New Issue