commit bf1a520
Michael Forney
·
2014-12-25 09:07:14 +0000 UTC
parent 28f2da3
drm: Use render nodes for rendering
1 files changed,
+44,
-31
+44,
-31
1@@ -31,6 +31,7 @@
2 #include "wayland_buffer.h"
3
4 #include <dirent.h>
5+#include <errno.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9@@ -47,7 +48,7 @@ struct swc_drm swc_drm;
10
11 static struct
12 {
13- char * path;
14+ char path[128];
15
16 uint32_t taken_ids;
17
18@@ -58,15 +59,6 @@ static struct
19 static void authenticate(struct wl_client * client,
20 struct wl_resource * resource, uint32_t magic)
21 {
22- int ret;
23-
24- if ((ret = drmAuthMagic(swc.drm->fd, magic)) == 0)
25- wl_drm_send_authenticated(resource);
26- else
27- {
28- wl_resource_post_error(resource, WL_DRM_ERROR_AUTHENTICATE_FAIL,
29- "drmAuthMagic failed: %d\n", ret);
30- }
31 }
32
33 static void create_buffer(struct wl_client * client,
34@@ -138,12 +130,11 @@ static int select_card(const struct dirent * entry)
35 return sscanf(entry->d_name, "card%u", &num) == 1;
36 }
37
38-static bool find_primary_drm_device(char ** device_path)
39+static bool find_primary_drm_device(char * path, size_t size)
40 {
41 struct dirent ** cards, * card = NULL;
42 int num_cards, ret;
43 unsigned index;
44- char path[64];
45 FILE * file;
46 unsigned char boot_vga;
47
48@@ -154,8 +145,8 @@ static bool find_primary_drm_device(char ** device_path)
49
50 for (index = 0; index < num_cards; ++index)
51 {
52- snprintf(path, sizeof path,
53- "/sys/class/drm/%s/device/boot_vga", cards[index]->d_name);
54+ snprintf(path, size, "/sys/class/drm/%s/device/boot_vga",
55+ cards[index]->d_name);
56
57 if ((file = fopen(path, "r")))
58 {
59@@ -182,14 +173,10 @@ static bool find_primary_drm_device(char ** device_path)
60 if (!card)
61 return false;
62
63- *device_path = malloc(sizeof "/dev/dri/" + strlen(card->d_name));
64-
65- if (!*device_path)
66+ if (snprintf(path, size, "/dev/dri/%s", card->d_name) >= size)
67 return false;
68
69- sprintf(*device_path, "/dev/dri/%s", card->d_name);
70 free(card);
71-
72 return true;
73 }
74
75@@ -282,7 +269,9 @@ static void bind_drm(struct wl_client * client, void * data, uint32_t version,
76
77 bool swc_drm_initialize()
78 {
79- if (!find_primary_drm_device(&drm.path))
80+ struct stat master, render;
81+
82+ if (!find_primary_drm_device(drm.path, sizeof drm.path))
83 {
84 ERROR("Could not find DRM device\n");
85 goto error0;
86@@ -294,19 +283,46 @@ bool swc_drm_initialize()
87 if (swc.drm->fd == -1)
88 {
89 ERROR("Could not open DRM device at %s\n", drm.path);
90+ goto error0;
91+ }
92+
93+ if (fstat(swc.drm->fd, &master) != 0)
94+ {
95+ ERROR("Could not fstat DRM FD: %s\n", strerror(errno));
96+ goto error1;
97+ }
98+
99+ if (snprintf(drm.path, sizeof drm.path, "/dev/dri/renderD%d",
100+ minor(master.st_rdev) + 0x80) >= sizeof drm.path)
101+ {
102+ ERROR("Render node path is too long");
103+ goto error1;
104+ }
105+
106+ if (stat(drm.path, &render) != 0)
107+ {
108+ ERROR("Could not stat render node for primary DRM device: %s\n",
109+ strerror(errno));
110+ goto error1;
111+ }
112+
113+ if (master.st_mode != render.st_mode
114+ || minor(master.st_rdev) + 0x80 != minor(render.st_rdev))
115+ {
116+ ERROR("Render node does not have expected mode or minor number\n");
117 goto error1;
118 }
119
120 if (!(swc.drm->context = wld_drm_create_context(swc.drm->fd)))
121 {
122 ERROR("Could not create WLD DRM context\n");
123- goto error2;
124+ goto error1;
125 }
126
127 if (!(swc.drm->renderer = wld_create_renderer(swc.drm->context)))
128 {
129 ERROR("Could not create WLD DRM renderer\n");
130- goto error3;
131+ goto error2;
132 }
133
134 drm.event_source = wl_event_loop_add_fd
135@@ -315,7 +331,7 @@ bool swc_drm_initialize()
136 if (!drm.event_source)
137 {
138 ERROR("Could not create DRM event source\n");
139- goto error4;
140+ goto error3;
141 }
142
143 if (!wld_drm_is_dumb(swc.drm->context))
144@@ -326,22 +342,20 @@ bool swc_drm_initialize()
145 if (!drm.global)
146 {
147 ERROR("Could not create wl_drm global\n");
148- goto error5;
149+ goto error4;
150 }
151 }
152
153 return true;
154
155- error5:
156- wl_event_source_remove(drm.event_source);
157 error4:
158- wld_destroy_renderer(swc.drm->renderer);
159+ wl_event_source_remove(drm.event_source);
160 error3:
161- wld_destroy_context(swc.drm->context);
162+ wld_destroy_renderer(swc.drm->renderer);
163 error2:
164- close(swc.drm->fd);
165+ wld_destroy_context(swc.drm->context);
166 error1:
167- free(drm.path);
168+ close(swc.drm->fd);
169 error0:
170 return false;
171 }
172@@ -353,7 +367,6 @@ void swc_drm_finalize()
173 wl_event_source_remove(drm.event_source);
174 wld_destroy_renderer(swc.drm->renderer);
175 wld_destroy_context(swc.drm->context);
176- free(drm.path);
177 close(swc.drm->fd);
178 }
179