summaryrefslogtreecommitdiffstats
path: root/meta-agl-drm-lease/recipes-graphics/weston/weston/0001-backend-drm-Add-method-to-import-DRM-fd.patch
blob: da3a0c6f277d388ac304826467d0b8b3e85efb53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
From e7d843e3a2af9ed04569f4ec94d3f558ab2aeede Mon Sep 17 00:00:00 2001
From: Damian Hobson-Garcia <dhobsong@igel.co.jp>
Date: Wed, 20 Jan 2021 16:25:39 +0900
Subject: [PATCH 1/2] backend-drm: Add method to import DRM fd

Allow the compositor to provide a file descriptor for a
DRM device.

This allows the compositor to bypass the launcher backends
and to get a DRM file descriptor from an external
resource manager, such as one that can create DRM leases,
and pass it to the DRM backend for use.

Having the DRM device management in the compositor allows for
integrating a platform specific resource manager without having
to add extra dependencies to the generic libweston code.
---
 compositor/main.c               |  1 +
 include/libweston/backend-drm.h |  7 +++
 libweston/backend-drm/drm.c     | 76 ++++++++++++++++++++++++---------
 3 files changed, 65 insertions(+), 19 deletions(-)

diff --git a/compositor/main.c b/compositor/main.c
index 8eb8a470..7d5373f7 100644
--- a/compositor/main.c
+++ b/compositor/main.c
@@ -2510,6 +2510,7 @@ load_drm_backend(struct weston_compositor *c,
 	config.base.struct_version = WESTON_DRM_BACKEND_CONFIG_VERSION;
 	config.base.struct_size = sizeof(struct weston_drm_backend_config);
 	config.configure_device = configure_input_device;
+	config.device_fd = -1;
 
 	wet->heads_changed_listener.notify = drm_heads_changed;
 	weston_compositor_add_heads_changed_listener(c,
diff --git a/include/libweston/backend-drm.h b/include/libweston/backend-drm.h
index f6647e28..a62c8996 100644
--- a/include/libweston/backend-drm.h
+++ b/include/libweston/backend-drm.h
@@ -223,6 +223,13 @@ struct weston_drm_backend_config {
 
 	/** Use shadow buffer if using Pixman-renderer. */
 	bool use_pixman_shadow;
+
+	/** DRM device file descriptor to use
+         *
+         * An openeded DRM device file descriptor.  If <0, open a DRM
+         * device in the backend using `specific_device` or heuristics.
+         */
+	int device_fd;
 };
 
 #ifdef  __cplusplus
diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c
index e3169b6e..300c9ff6 100644
--- a/libweston/backend-drm/drm.c
+++ b/libweston/backend-drm/drm.c
@@ -40,6 +40,7 @@
 #include <linux/vt.h>
 #include <assert.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
 #include <time.h>
 
 #include <xf86drm.h>
@@ -2486,29 +2487,22 @@ drm_device_changed(struct weston_compositor *compositor,
 	wl_signal_emit(&compositor->session_signal, compositor);
 }
 
-/**
- * Determines whether or not a device is capable of modesetting. If successful,
- * sets b->drm.fd and b->drm.filename to the opened device.
- */
 static bool
-drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
+drm_backend_update_kms_device(struct drm_backend *b, struct udev_device *device,
+                const char *name, int drm_fd)
 {
-	const char *filename = udev_device_get_devnode(device);
 	const char *sysnum = udev_device_get_sysnum(device);
 	dev_t devnum = udev_device_get_devnum(device);
 	drmModeRes *res;
-	int id = -1, fd;
+	int id = -1;
 
-	if (!filename)
+	if (!name)
 		return false;
 
-	fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
-	if (fd < 0)
-		return false;
 
-	res = drmModeGetResources(fd);
+	res = drmModeGetResources(drm_fd);
 	if (!res)
-		goto out_fd;
+		return false;
 
 	if (res->count_crtcs <= 0 || res->count_connectors <= 0 ||
 	    res->count_encoders <= 0)
@@ -2517,7 +2511,7 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
 	if (sysnum)
 		id = atoi(sysnum);
 	if (!sysnum || id < 0) {
-		weston_log("couldn't get sysnum for device %s\n", filename);
+		weston_log("couldn't get sysnum for device %s\n", name);
 		goto out_res;
 	}
 
@@ -2527,9 +2521,9 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
 		weston_launcher_close(b->compositor->launcher, b->drm.fd);
 	free(b->drm.filename);
 
-	b->drm.fd = fd;
+	b->drm.fd = drm_fd;
 	b->drm.id = id;
-	b->drm.filename = strdup(filename);
+	b->drm.filename = strdup(name);
 	b->drm.devnum = devnum;
 
 	drmModeFreeResources(res);
@@ -2538,11 +2532,33 @@ drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
 
 out_res:
 	drmModeFreeResources(res);
-out_fd:
-	weston_launcher_close(b->compositor->launcher, fd);
 	return false;
 }
 
+/**
+ * Determines whether or not a device is capable of modesetting. If successful,
+ * sets b->drm.fd and b->drm.filename to the opened device.
+ */
+static bool
+drm_device_is_kms(struct drm_backend *b, struct udev_device *device)
+{
+	int fd;
+	const char *filename = udev_device_get_devnode(device);
+	if (!filename)
+		return false;
+
+	fd = weston_launcher_open(b->compositor->launcher, filename, O_RDWR);
+	if (fd < 0)
+		return false;
+
+	if (!drm_backend_update_kms_device(b, device, filename, fd)) {
+		weston_launcher_close(b->compositor->launcher, fd);
+		return false;
+	}
+
+	return true;
+}
+
 /*
  * Find primary GPU
  * Some systems may have multiple DRM devices attached to a single seat. This
@@ -2630,6 +2646,25 @@ find_primary_gpu(struct drm_backend *b, const char *seat)
 	return drm_device;
 }
 
+static struct udev_device *
+import_drm_device_fd(struct drm_backend *b, int fd)
+{
+	struct udev_device *device;
+	struct stat s;
+
+	if (fstat(fd, &s) < 0 || !S_ISCHR(s.st_mode))
+		return NULL;
+
+	device = udev_device_new_from_devnum(b->udev, 'c', s.st_rdev);
+	if (!device)
+		return NULL;
+
+	if (!drm_backend_update_kms_device(b, device, "imported DRM device fd", fd))
+		return NULL;
+
+	return device;
+}
+
 static struct udev_device *
 open_specific_drm_device(struct drm_backend *b, const char *name)
 {
@@ -2854,7 +2889,9 @@ drm_backend_create(struct weston_compositor *compositor,
 	b->session_listener.notify = session_notify;
 	wl_signal_add(&compositor->session_signal, &b->session_listener);
 
-	if (config->specific_device)
+	if (config->device_fd >= 0)
+		drm_device = import_drm_device_fd(b, config->device_fd);
+	else if (config->specific_device)
 		drm_device = open_specific_drm_device(b, config->specific_device);
 	else
 		drm_device = find_primary_gpu(b, seat_id);
@@ -3013,6 +3050,7 @@ static void
 config_init_to_defaults(struct weston_drm_backend_config *config)
 {
 	config->use_pixman_shadow = true;
+	config->device_fd = -1;
 }
 
 WL_EXPORT int
-- 
2.25.1