1 From 46e5ec89cad434b1a1dd9ca49a35e1c6992c54c1 Mon Sep 17 00:00:00 2001
2 From: Marius Vlad <marius.vlad@collabora.com>
3 Date: Thu, 2 May 2024 19:11:06 +0300
4 Subject: [PATCH 1/2] backend-drm: Add method to import DRM fd
6 Allow the compositor to provide a file descriptor for a
9 This allows the compositor to bypass the launcher backends
10 and to get a DRM file descriptor from an external
11 resource manager, such as one that can create DRM leases,
12 and pass it to the DRM backend for use.
14 Having the DRM device management in the compositor allows for
15 integrating a platform specific resource manager without having
16 to add extra dependencies to the generic libweston code.
18 Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
19 Signed-off-by: Damian Hobson-Garcia <dhobsong@igel.co.jp>
21 include/libweston/backend-drm.h | 7 +++
22 libweston/backend-drm/drm.c | 78 ++++++++++++++++++++++++---------
23 2 files changed, 64 insertions(+), 21 deletions(-)
25 diff --git a/include/libweston/backend-drm.h b/include/libweston/backend-drm.h
26 index d47955c..889848a 100644
27 --- a/include/libweston/backend-drm.h
28 +++ b/include/libweston/backend-drm.h
29 @@ -258,6 +258,13 @@ struct weston_drm_backend_config {
32 char *additional_devices;
34 + /** DRM device file descriptor to use
36 + * An openeded DRM device file descriptor. If <0, open a DRM
37 + * device in the backend using `specific_device` or heuristics.
43 diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
44 index 8092789..4e78ad0 100644
45 --- a/libweston/backend-drm/drm.c
46 +++ b/libweston/backend-drm/drm.c
51 +#include <sys/stat.h>
55 @@ -3431,31 +3432,22 @@ drm_device_changed(struct weston_backend *backend,
56 wl_signal_emit(&compositor->session_signal, compositor);
60 - * Determines whether or not a device is capable of modesetting. If successful,
61 - * sets b->drm.fd and b->drm.filename to the opened device.
64 -drm_device_is_kms(struct drm_backend *b, struct drm_device *device,
65 - struct udev_device *udev_device)
66 +drm_backend_update_kms_device(struct drm_backend *b, struct drm_device *device,
67 + struct udev_device *udev_device, const char *name, int drm_fd)
69 struct weston_compositor *compositor = b->compositor;
70 - const char *filename = udev_device_get_devnode(udev_device);
71 const char *sysnum = udev_device_get_sysnum(udev_device);
72 dev_t devnum = udev_device_get_devnum(udev_device);
80 - fd = weston_launcher_open(compositor->launcher, filename, O_RDWR);
85 - res = drmModeGetResources(fd);
86 + res = drmModeGetResources(drm_fd);
91 if (res->count_crtcs <= 0 || res->count_connectors <= 0 ||
92 res->count_encoders <= 0)
93 @@ -3464,7 +3456,7 @@ drm_device_is_kms(struct drm_backend *b, struct drm_device *device,
96 if (!sysnum || id < 0) {
97 - weston_log("couldn't get sysnum for device %s\n", filename);
98 + weston_log("couldn't get sysnum for device %s\n", name);
102 @@ -3474,9 +3466,9 @@ drm_device_is_kms(struct drm_backend *b, struct drm_device *device,
103 weston_launcher_close(compositor->launcher, device->drm.fd);
104 free(device->drm.filename);
106 - device->drm.fd = fd;
107 + device->drm.fd = drm_fd;
109 - device->drm.filename = strdup(filename);
110 + device->drm.filename = strdup(name);
111 device->drm.devnum = devnum;
113 drmModeFreeResources(res);
114 @@ -3485,11 +3477,34 @@ drm_device_is_kms(struct drm_backend *b, struct drm_device *device,
117 drmModeFreeResources(res);
119 - weston_launcher_close(b->compositor->launcher, fd);
124 + * Determines whether or not a device is capable of modesetting. If successful,
125 + * sets b->drm.fd and b->drm.filename to the opened device.
128 +drm_device_is_kms(struct drm_backend *b, struct drm_device *device,
129 + struct udev_device *udev_device)
132 + const char *filename = udev_device_get_devnode(udev_device);
136 + fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
140 + if (!drm_backend_update_kms_device(b, b->drm, udev_device, filename, fd)) {
141 + weston_launcher_close(b->compositor->launcher, fd);
150 * Some systems may have multiple DRM devices attached to a single seat. This
151 @@ -3578,6 +3593,25 @@ find_primary_gpu(struct drm_backend *b, const char *seat)
155 +static struct udev_device *
156 +import_drm_device_fd(struct drm_backend *b, int fd)
158 + struct udev_device *udev_device;
161 + if (fstat(fd, &s) < 0 || !S_ISCHR(s.st_mode))
164 + udev_device = udev_device_new_from_devnum(b->udev, 'c', s.st_rdev);
168 + if (!drm_backend_update_kms_device(b, b->drm, udev_device, "imported DRM device fd", fd))
171 + return udev_device;
174 static struct udev_device *
175 open_specific_drm_device(struct drm_backend *b, struct drm_device *device,
177 @@ -3904,7 +3938,9 @@ drm_backend_create(struct weston_compositor *compositor,
178 b->session_listener.notify = session_notify;
179 wl_signal_add(&compositor->session_signal, &b->session_listener);
181 - if (config->specific_device)
182 + if (config->device_fd > 0)
183 + drm_device = import_drm_device_fd(b, config->device_fd);
184 + else if (config->specific_device)
185 drm_device = open_specific_drm_device(b, device,
186 config->specific_device);