commit 06017f5
Michael Forney
·
2013-09-05 08:23:41 +0000 UTC
parent 64bdb1f
Separate non-wayland specific parts of wayland-drm Now, applications can use hardware independent DRM drawables without using wayland.
+5,
-0
1@@ -19,6 +19,11 @@ if WITH_WAYLAND
2 pkginclude_HEADERS += wayland.h
3 endif
4
5+if ENABLE_DRM
6+ libwld_la_SOURCES += drm.c
7+ pkginclude_HEADERS += drm.h
8+endif
9+
10 if ENABLE_WAYLAND_DRM
11 AM_CPPFLAGS = -I$(top_builddir)/protocol
12 libwld_la_SOURCES += wayland-drm.c protocol/wayland-drm-protocol.c
+19,
-11
1@@ -47,33 +47,41 @@ if test "x$with_wayland" = "xyes" ; then
2 fi
3 AM_CONDITIONAL([WITH_WAYLAND], test "x$with_wayland" = "xyes")
4
5-# Wayland DRM
6+# DRM
7 AC_ARG_ENABLE([drm],
8 AS_HELP_STRING([--disable-drm],
9- [disable Wayland DRM support]),
10+ [disable DRM support]),
11 enable_drm=$enableval,
12- enable_drm=$with_wayland)
13-if test "x$enable_drm" = "xyes" ; then
14+ enable_drm=yes)
15+AM_CONDITIONAL([ENABLE_DRM], [test "x$enable_drm" = "xyes"])
16+
17+# Wayland DRM
18+AC_ARG_ENABLE([wayland-drm],
19+ AS_HELP_STRING([--disable-wayland-drm],
20+ [disable Wayland DRM support]),
21+ enable_wayland_drm=$enableval,
22+ enable_wayland_drm=$with_wayland)
23+if test "x$enable_wayland_drm" = "xyes" ; then
24 if test "x$with_wayland" != "xyes" ; then
25- AC_MSG_ERROR([--enable-drm requires --with-wayland])
26+ AC_MSG_ERROR([--enable-wayland-drm requires --with-wayland])
27 fi
28 AC_DEFINE([ENABLE_WAYLAND_DRM], [1], [Enable Wayland DRM support])
29 fi
30-AM_CONDITIONAL([ENABLE_WAYLAND_DRM], test "x$enable_drm" = "xyes")
31+AM_CONDITIONAL([ENABLE_WAYLAND_DRM], test "x$enable_wayland_drm" = "xyes")
32
33 # Wayland SHM
34-AC_ARG_ENABLE([shm],
35- AS_HELP_STRING([--disable-shm],
36+AC_ARG_ENABLE([wayland-shm],
37+ AS_HELP_STRING([--disable-wayland-shm],
38 [disable Wayland SHM support]),
39 enable_shm=$enableval,
40 enable_shm=$with_wayland)
41-if test "x$enable_shm" = "xyes" ; then
42+if test "x$enable_wayland_shm" = "xyes" ; then
43 if test "x$with_wayland" != "xyes" ; then
44- AC_MSG_ERROR([--enable-shm requires --with-wayland])
45+ AC_MSG_ERROR([--enable-wayland-shm requires --with-wayland])
46 fi
47 AC_DEFINE([ENABLE_WAYLAND_SHM], [1], [Enable Wayland SHM support])
48 fi
49-AM_CONDITIONAL([ENABLE_WAYLAND_SHM], test "x$enable_shm" = "xyes")
50+AM_CONDITIONAL([ENABLE_WAYLAND_SHM], test "x$enable_wayland_shm" = "xyes")
51
52 # Intel
53 AC_ARG_ENABLE([intel],
+11,
-3
1@@ -30,7 +30,7 @@ typedef bool (* drm_device_supported_func_t)(uint32_t vendor_id,
2 uint32_t device_id);
3 typedef void * (* drm_create_context_func_t)(int drm_fd);
4 typedef void (* drm_destroy_context_func_t)(void * context);
5-typedef struct wld_drawable * (* drm_create_drawable_func_t)
6+typedef struct drm_drawable * (* drm_create_drawable_func_t)
7 (void * context, uint32_t width, uint32_t height, uint32_t format);
8
9 struct wld_drm_interface
10@@ -41,11 +41,16 @@ struct wld_drm_interface
11 drm_create_drawable_func_t create_drawable;
12 };
13
14+struct wld_drm_context
15+{
16+ const struct wld_drm_interface * interface;
17+ void * context;
18+};
19+
20 struct drm_drawable
21 {
22 struct wld_drawable base;
23-
24- unsigned long pitch;
25+ struct wld_drm_context * drm;
26 int fd;
27 };
28
29@@ -56,5 +61,8 @@ _Static_assert(offsetof(struct drm_drawable, base) == 0,
30 extern const struct wld_drm_interface intel_drm;
31 #endif
32
33+bool drm_initialize_context(struct wld_drm_context * context, int fd);
34+void drm_finalize_context(struct wld_drm_context * context);
35+
36 #endif
37
A
drm.c
+132,
-0
1@@ -0,0 +1,132 @@
2+/* wld: drm.c
3+ *
4+ * Copyright (c) 2013 Michael Forney
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#include "drm.h"
26+#include "drm-private.h"
27+
28+const static struct wld_drm_interface * drm_interfaces[] = {
29+#if ENABLE_INTEL
30+ &intel_drm
31+#endif
32+};
33+
34+static const struct wld_drm_interface * find_drm_interface(int fd)
35+{
36+ char path[64], id[32];
37+ uint32_t vendor_id, device_id;
38+ char * path_part;
39+ struct stat st;
40+ FILE * file;
41+ uint32_t index;
42+
43+ if (fstat(fd, &st) == -1)
44+ return NULL;
45+
46+ snprintf(path, sizeof path, "/sys/dev/char/%u:%u/",
47+ major(st.st_rdev), minor(st.st_rdev));
48+ path_part = path + strlen(path);
49+
50+ strcpy(path_part, "device/vendor");
51+ file = fopen(path, "r");
52+ fgets(id, sizeof id, file);
53+ fclose(file);
54+ vendor_id = strtoul(id, NULL, 0);
55+
56+ strcpy(path_part, "device/device");
57+ file = fopen(path, "r");
58+ fgets(id, sizeof id, file);
59+ fclose(file);
60+ device_id = strtoul(id, NULL, 0);
61+
62+ for (index = 0; index < ARRAY_LENGTH(drm_interfaces); ++index)
63+ {
64+ if (drm_interfaces[index]->device_supported(vendor_id, device_id))
65+ return drm_interfaces[index];
66+ }
67+
68+ return NULL;
69+}
70+
71+bool drm_initialize_context(struct wld_drm_context * drm, int fd)
72+{
73+ if (!(drm->interface = find_drm_interface(fd)))
74+ return false;
75+
76+ if (!(drm->context = drm->interface->create_context(fd)))
77+ return false;
78+
79+ return true;
80+}
81+
82+void drm_finalize_context(struct wld_drm_context * drm)
83+{
84+ drm->interface->destroy_context(drm->context);
85+}
86+
87+struct wld_drm_context * wld_drm_create_context(int fd)
88+{
89+ struct wld_drm_context * drm;
90+
91+ if (!(drm = malloc(sizeof *drm)))
92+ goto error0;
93+
94+ if (!drm_initialize_context(drm, fd))
95+ goto error1;
96+
97+ return drm;
98+
99+ error1:
100+ free(drm);
101+ error0:
102+ return NULL;
103+}
104+
105+void wld_drm_destroy_context(struct wld_drm_context * drm)
106+{
107+ drm_finalize_context(drm);
108+ free(drm);
109+}
110+
111+static struct wld_drawable * finish_drawable(struct wld_drm_context * drm,
112+ struct drm_drawable * drawable)
113+{
114+ if (!drawable)
115+ return NULL;
116+
117+ drawable->drm = drm;
118+
119+ return &drawable->base;
120+}
121+
122+struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
123+ uint32_t width, uint32_t height,
124+ uint32_t format)
125+{
126+ struct drm_drawable * drawable;
127+
128+ drawable = drm->interface->create_drawable(drm->context,
129+ width, height, format);
130+
131+ return finish_drawable(drm, drawable);
132+}
133+
A
drm.h
+50,
-0
1@@ -0,0 +1,50 @@
2+/* wld: drm.h
3+ *
4+ * Copyright (c) 2013 Michael Forney
5+ *
6+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7+ * of this software and associated documentation files (the "Software"), to deal
8+ * in the Software without restriction, including without limitation the rights
9+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+ * copies of the Software, and to permit persons to whom the Software is
11+ * furnished to do so, subject to the following conditions:
12+ *
13+ * The above copyright notice and this permission notice shall be included in
14+ * all copies or substantial portions of the Software.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+ * SOFTWARE.
23+ */
24+
25+#ifndef WLD_DRM_H
26+#define WLD_DRM_H 1
27+
28+#include <stdint.h>
29+
30+struct wld_drm_context;
31+struct wld_drawable;
32+
33+/**
34+ * Create a new DRM context from an opened DRM device file descriptor.
35+ */
36+struct wld_drm_context * wld_drm_create_context(int fd);
37+
38+/**
39+ * Destroy a DRM context.
40+ */
41+void wld_drm_destroy_context(struct wld_drm_context * drm);
42+
43+/**
44+ * Create a new DRM drawable.
45+ */
46+struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
47+ uint32_t width, uint32_t height,
48+ uint32_t format);
49+
50+#endif
51+
M
intel.c
+3,
-3
1@@ -69,7 +69,7 @@ static void intel_destroy(struct wld_drawable * drawable);
2 static struct wld_intel_context * intel_create_context(int drm_fd);
3 static void intel_destroy_context(struct wld_intel_context * context);
4 static bool intel_device_supported(uint32_t vendor_id, uint32_t device_id);
5-static struct wld_drawable * intel_create_drawable
6+static struct drm_drawable * intel_create_drawable
7 (struct wld_intel_context * context, uint32_t width, uint32_t height,
8 uint32_t format);
9
10@@ -116,7 +116,7 @@ void intel_destroy_context(struct wld_intel_context * context)
11 free(context);
12 }
13
14-struct wld_drawable * intel_create_drawable
15+struct drm_drawable * intel_create_drawable
16 (struct wld_intel_context * context, uint32_t width, uint32_t height,
17 uint32_t format)
18 {
19@@ -138,7 +138,7 @@ struct wld_drawable * intel_create_drawable
20 &tiling_mode, &intel->drm.base.pitch, 0);
21 drm_intel_bo_gem_export_to_prime(intel->bo, &intel->drm.fd);
22
23- return &intel->drm.base;
24+ return &intel->drm;
25 }
26
27 static void intel_fill_rectangle(struct wld_drawable * drawable, uint32_t color,
+33,
-82
1@@ -24,6 +24,7 @@
2 #include "wayland-drm.h"
3 #include "wayland-drm-client-protocol.h"
4 #include "wayland.h"
5+#include "drm.h"
6 #include "wayland-private.h"
7 #include "wld-private.h"
8 #include "drm-private.h"
9@@ -36,17 +37,16 @@
10
11 #include <stdio.h>
12
13-struct wld_drm_context
14+struct wld_wayland_drm_context
15 {
16+ struct wld_drm_context context;
17+
18 struct wl_drm * wl;
19 struct wl_registry * registry;
20 struct wl_array formats;
21 uint32_t capabilities;
22 int fd;
23 bool authenticated;
24-
25- const struct wld_drm_interface * interface;
26- void * context;
27 };
28
29 static void registry_global(void * data, struct wl_registry * registry,
30@@ -60,10 +60,12 @@ static void drm_capabilities(void * data, struct wl_drm * wl,
31 uint32_t capabilities);
32
33 const struct wld_wayland_interface wayland_drm_interface = {
34- .create_context = (wayland_create_context_func_t) &wld_drm_create_context,
35+ .create_context
36+ = (wayland_create_context_func_t) &wld_wayland_drm_create_context,
37 .destroy_context
38- = (wayland_destroy_context_func_t) &wld_drm_destroy_context,
39- .create_drawable = (wayland_create_drawable_func_t) &wld_drm_create_drawable
40+ = (wayland_destroy_context_func_t) &wld_wayland_drm_destroy_context,
41+ .create_drawable
42+ = (wayland_create_drawable_func_t) &wld_wayland_drm_create_drawable
43 };
44
45 const static struct wl_registry_listener registry_listener = {
46@@ -77,53 +79,10 @@ const static struct wl_drm_listener drm_listener = {
47 .capabilities = &drm_capabilities
48 };
49
50-const static struct wld_drm_interface * drm_interfaces[] = {
51-#if ENABLE_INTEL
52- &intel_drm
53-#endif
54-};
55-
56-static const struct wld_drm_interface * find_drm_interface(int fd)
57-{
58- char path[64], id[32];
59- uint32_t vendor_id, device_id;
60- char * path_part;
61- struct stat st;
62- FILE * file;
63- uint32_t index;
64-
65- if (fstat(fd, &st) == -1)
66- return NULL;
67-
68- snprintf(path, sizeof path, "/sys/dev/char/%u:%u/",
69- major(st.st_rdev), minor(st.st_rdev));
70- path_part = path + strlen(path);
71-
72- strcpy(path_part, "device/vendor");
73- file = fopen(path, "r");
74- fgets(id, sizeof id, file);
75- fclose(file);
76- vendor_id = strtoul(id, NULL, 0);
77-
78- strcpy(path_part, "device/device");
79- file = fopen(path, "r");
80- fgets(id, sizeof id, file);
81- fclose(file);
82- device_id = strtoul(id, NULL, 0);
83-
84- for (index = 0; index < ARRAY_LENGTH(drm_interfaces); ++index)
85- {
86- if (drm_interfaces[index]->device_supported(vendor_id, device_id))
87- return drm_interfaces[index];
88- }
89-
90- return NULL;
91-}
92-
93-struct wld_drm_context * wld_drm_create_context(struct wl_display * display,
94- struct wl_event_queue * queue)
95+struct wld_wayland_drm_context * wld_wayland_drm_create_context
96+ (struct wl_display * display, struct wl_event_queue * queue)
97 {
98- struct wld_drm_context * drm;
99+ struct wld_wayland_drm_context * drm;
100
101 drm = malloc(sizeof *drm);
102
103@@ -178,19 +137,9 @@ struct wld_drm_context * wld_drm_create_context(struct wl_display * display,
104 goto error4;
105 }
106
107- drm->interface = find_drm_interface(drm->fd);
108-
109- if (!drm->interface)
110- {
111- DEBUG("Couldn't find drawable implementation for DRM device\n");
112- goto error4;
113- }
114-
115- drm->context = drm->interface->create_context(drm->fd);
116-
117- if (!drm->context)
118+ if (!drm_initialize_context(&drm->context, drm->fd))
119 {
120- DEBUG("Couldn't create context for DRM drawable implementation\n");
121+ DEBUG("Couldn't initialize context for DRM device\n");
122 goto error4;
123 }
124
125@@ -209,9 +158,9 @@ struct wld_drm_context * wld_drm_create_context(struct wl_display * display,
126 return NULL;
127 }
128
129-void wld_drm_destroy_context(struct wld_drm_context * drm)
130+void wld_wayland_drm_destroy_context(struct wld_wayland_drm_context * drm)
131 {
132- drm->interface->destroy_context(drm->context);
133+ drm_finalize_context(&drm->context);
134 close(drm->fd);
135 wl_drm_destroy(drm->wl);
136 wl_registry_destroy(drm->registry);
137@@ -220,7 +169,8 @@ void wld_drm_destroy_context(struct wld_drm_context * drm)
138 free(drm);
139 }
140
141-bool wld_drm_has_format(struct wld_drm_context * drm, uint32_t format)
142+bool wld_wayland_drm_has_format(struct wld_wayland_drm_context * drm,
143+ uint32_t format)
144 {
145 uint32_t * supported_format;
146
147@@ -233,23 +183,24 @@ bool wld_drm_has_format(struct wld_drm_context * drm, uint32_t format)
148 return false;
149 }
150
151-int wld_drm_get_fd(struct wld_drm_context * drm)
152+int wld_wayland_drm_get_fd(struct wld_wayland_drm_context * drm)
153 {
154 return drm->authenticated ? drm->fd : -1;
155 }
156
157-struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
158- uint32_t width, uint32_t height,
159- enum wld_format format,
160- struct wl_buffer ** buffer)
161+struct wld_drawable * wld_wayland_drm_create_drawable
162+ (struct wld_wayland_drm_context * drm, uint32_t width, uint32_t height,
163+ enum wld_format format, struct wl_buffer ** buffer)
164 {
165 struct drm_drawable * drawable;
166
167- if (buffer && !wld_drm_has_format(drm, format))
168+ if (buffer && !wld_wayland_drm_has_format(drm, format))
169 return NULL;
170
171- drawable = (void *) drm->interface->create_drawable(drm->context,
172- width, height, format);
173+ drawable = (void *) wld_drm_create_drawable(&drm->context, width, height, format);
174+
175+ if (!drawable)
176+ return NULL;
177
178 if (buffer)
179 {
180@@ -261,7 +212,7 @@ struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * drm,
181 return &drawable->base;
182 }
183
184-int wld_drm_get_prime_fd(struct wld_drawable * drawable)
185+int wld_wayland_drm_get_prime_fd(struct wld_drawable * drawable)
186 {
187 return ((struct drm_drawable *)(void *) drawable)->fd;
188 }
189@@ -269,7 +220,7 @@ int wld_drm_get_prime_fd(struct wld_drawable * drawable)
190 void registry_global(void * data, struct wl_registry * registry, uint32_t name,
191 const char * interface, uint32_t version)
192 {
193- struct wld_drm_context * drm = data;
194+ struct wld_wayland_drm_context * drm = data;
195
196 if (strcmp(interface, "wl_drm") == 0 && version >= 2)
197 drm->wl = wl_registry_bind(registry, name, &wl_drm_interface, 2);
198@@ -277,7 +228,7 @@ void registry_global(void * data, struct wl_registry * registry, uint32_t name,
199
200 void drm_device(void * data, struct wl_drm * wl, const char * name)
201 {
202- struct wld_drm_context * drm = data;
203+ struct wld_wayland_drm_context * drm = data;
204 drm_magic_t magic;
205
206 drm->fd = open(name, O_RDWR);
207@@ -294,21 +245,21 @@ void drm_device(void * data, struct wl_drm * wl, const char * name)
208
209 void drm_format(void * data, struct wl_drm * wl, uint32_t format)
210 {
211- struct wld_drm_context * drm = data;
212+ struct wld_wayland_drm_context * drm = data;
213
214 *((uint32_t *) wl_array_add(&drm->formats, sizeof format)) = format;
215 }
216
217 void drm_authenticated(void * data, struct wl_drm * wl)
218 {
219- struct wld_drm_context * drm = data;
220+ struct wld_wayland_drm_context * drm = data;
221
222 drm->authenticated = true;
223 }
224
225 void drm_capabilities(void * data, struct wl_drm * wl, uint32_t capabilities)
226 {
227- struct wld_drm_context * drm = data;
228+ struct wld_wayland_drm_context * drm = data;
229
230 drm->capabilities = capabilities;
231 }
+12,
-13
1@@ -27,7 +27,7 @@
2 #include <stdbool.h>
3 #include <stdint.h>
4
5-struct wld_context;
6+struct wld_wayland_drm_context;
7 struct wld_drawable;
8 enum wld_format;
9
10@@ -39,41 +39,40 @@ struct wl_buffer;
11 * Create a new drawable context which creates Wayland buffers through the
12 * wl_drm interface, backed by hardware specific drawable implementations.
13 */
14-struct wld_drm_context * wld_drm_create_context(struct wl_display * display,
15- struct wl_event_queue * queue);
16+struct wld_wayland_drm_context * wld_wayland_drm_create_context
17+ (struct wl_display * display, struct wl_event_queue * queue);
18
19 /**
20- * Destroy a DRM context.
21+ * Destroy a Wayland DRM context.
22 */
23-void wld_drm_destroy_context(struct wld_drm_context * context);
24+void wld_wayland_drm_destroy_context(struct wld_wayland_drm_context * context);
25
26 /**
27 * Check if the wl_drm global has the specified pixel format.
28 *
29 * @see enum wld_format
30 */
31-bool wld_drm_has_format(struct wld_drm_context * context,
32- enum wld_format format);
33+bool wld_wayland_drm_has_format(struct wld_wayland_drm_context * context,
34+ enum wld_format format);
35
36 /**
37 * Get the opened file descriptor for the DRM device.
38 */
39-int wld_drm_get_fd(struct wld_drm_context * context);
40+int wld_wayland_drm_get_fd(struct wld_wayland_drm_context * context);
41
42 /**
43 * Create a new DRM drawable with the specified dimensions.
44 */
45-struct wld_drawable * wld_drm_create_drawable(struct wld_drm_context * context,
46- uint32_t width, uint32_t height,
47- enum wld_format format,
48- struct wl_buffer ** buffer);
49+struct wld_drawable * wld_wayland_drm_create_drawable
50+ (struct wld_wayland_drm_context * context, uint32_t width, uint32_t height,
51+ enum wld_format format, struct wl_buffer ** buffer);
52
53 /**
54 * Get a PRIME file descriptor for this DRM drawable.
55 *
56 * @note The drawable must have been created with wld_drm_create_drawable
57 */
58-int wld_drm_get_prime_fd(struct wld_drawable * drawable);
59+int wld_wayland_drm_get_prime_fd(struct wld_drawable * drawable);
60
61 #endif
62