1 From e7d843e3a2af9ed04569f4ec94d3f558ab2aeede Mon Sep 17 00:00:00 2001
2 From: Damian Hobson-Garcia <dhobsong@igel.co.jp>
3 Date: Wed, 20 Jan 2021 16:25:39 +0900
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 compositor/main.c | 1 +
19 include/libweston/backend-drm.h | 7 +++
20 libweston/backend-drm/drm.c | 76 ++++++++++++++++++++++++---------
21 3 files changed, 65 insertions(+), 19 deletions(-)
23 diff --git a/compositor/main.c b/compositor/main.c
24 index 8eb8a470..7d5373f7 100644
25 --- a/compositor/main.c
26 +++ b/compositor/main.c
27 @@ -2510,6 +2510,7 @@ load_drm_backend(struct weston_compositor *c,
28 config.base.struct_version = WESTON_DRM_BACKEND_CONFIG_VERSION;
29 config.base.struct_size = sizeof(struct weston_drm_backend_config);
30 config.configure_device = configure_input_device;
31 + config.device_fd = -1;
33 wet->heads_changed_listener.notify = drm_heads_changed;
34 weston_compositor_add_heads_changed_listener(c,
35 diff --git a/include/libweston/backend-drm.h b/include/libweston/backend-drm.h
36 index f6647e28..a62c8996 100644
37 --- a/include/libweston/backend-drm.h
38 +++ b/include/libweston/backend-drm.h
39 @@ -223,6 +223,13 @@ struct weston_drm_backend_config {
41 /** Use shadow buffer if using Pixman-renderer. */
42 bool use_pixman_shadow;
44 + /** DRM device file descriptor to use
46 + * An openeded DRM device file descriptor. If <0, open a DRM
47 + * device in the backend using `specific_device` or heuristics.
53 diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
54 index e3169b6e..300c9ff6 100644
55 --- a/libweston/backend-drm/drm.c
56 +++ b/libweston/backend-drm/drm.c
61 +#include <sys/stat.h>
65 @@ -2486,29 +2487,22 @@ drm_device_changed(struct weston_compositor *compositor,
66 wl_signal_emit(&compositor->session_signal, compositor);
70 - * Determines whether or not a device is capable of modesetting. If successful,
71 - * sets b->drm.fd and b->drm.filename to the opened device.
74 -drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
75 +drm_backend_update_kms_device(struct drm_backend *b, struct udev_device *device,
76 + const char *name, int drm_fd)
78 - const char *filename = udev_device_get_devnode(device);
79 const char *sysnum = udev_device_get_sysnum(device);
80 dev_t devnum = udev_device_get_devnum(device);
89 - fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
93 - res = drmModeGetResources(fd);
94 + res = drmModeGetResources(drm_fd);
99 if (res->count_crtcs <= 0 || res->count_connectors <= 0 ||
100 res->count_encoders <= 0)
101 @@ -2517,7 +2511,7 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
104 if (!sysnum || id < 0) {
105 - weston_log("couldn't get sysnum for device %s\n", filename);
106 + weston_log("couldn't get sysnum for device %s\n", name);
110 @@ -2527,9 +2521,9 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
111 weston_launcher_close(b->compositor->launcher, b->drm.fd);
112 free(b->drm.filename);
115 + b->drm.fd = drm_fd;
117 - b->drm.filename = strdup(filename);
118 + b->drm.filename = strdup(name);
119 b->drm.devnum = devnum;
121 drmModeFreeResources(res);
122 @@ -2538,11 +2532,33 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
125 drmModeFreeResources(res);
127 - weston_launcher_close(b->compositor->launcher, fd);
132 + * Determines whether or not a device is capable of modesetting. If successful,
133 + * sets b->drm.fd and b->drm.filename to the opened device.
136 +drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
139 + const char *filename = udev_device_get_devnode(device);
143 + fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
147 + if (!drm_backend_update_kms_device(b, device, filename, fd)) {
148 + weston_launcher_close(b->compositor->launcher, fd);
157 * Some systems may have multiple DRM devices attached to a single seat. This
158 @@ -2630,6 +2646,25 @@ find_primary_gpu(struct drm_backend *b, const char *seat)
162 +static struct udev_device *
163 +import_drm_device_fd(struct drm_backend *b, int fd)
165 + struct udev_device *device;
168 + if (fstat(fd, &s) < 0 || !S_ISCHR(s.st_mode))
171 + device = udev_device_new_from_devnum(b->udev, 'c', s.st_rdev);
175 + if (!drm_backend_update_kms_device(b, device, "imported DRM device fd", fd))
181 static struct udev_device *
182 open_specific_drm_device(struct drm_backend *b, const char *name)
184 @@ -2854,7 +2889,9 @@ drm_backend_create(struct weston_compositor *compositor,
185 b->session_listener.notify = session_notify;
186 wl_signal_add(&compositor->session_signal, &b->session_listener);
188 - if (config->specific_device)
189 + if (config->device_fd >= 0)
190 + drm_device = import_drm_device_fd(b, config->device_fd);
191 + else if (config->specific_device)
192 drm_device = open_specific_drm_device(b, config->specific_device);
194 drm_device = find_primary_gpu(b, seat_id);
195 @@ -3013,6 +3050,7 @@ static void
196 config_init_to_defaults(struct weston_drm_backend_config *config)
198 config->use_pixman_shadow = true;
199 + config->device_fd = -1;