1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <string.h>
6
7 #include <drm.h>
8 #include <drm_fourcc.h>
9 #include <errno.h>
10 #include <xf86drm.h>
11 #include <xf86drmMode.h>
12
13 #include "bo.h"
14 #include "dev.h"
15 #include "modeset.h"
16
17 #if 0//def USE_ATOMIC_API
18 static uint32_t get_prop_id(struct sp_dev* dev,
19 drmModeObjectPropertiesPtr props, const char* name) {
20 drmModePropertyPtr p;
21 uint32_t i, prop_id = 0; /* Property ID should always be > 0 */
22
23 for (i = 0; !prop_id && i < props->count_props; i++) {
24 p = drmModeGetProperty(dev->fd, props->props[i]);
25 if (!strcmp(p->name, name))
26 prop_id = p->prop_id;
27 drmModeFreeProperty(p);
28 }
29 if (!prop_id)
30 printf("Could not find %s property\n", name);
31 return prop_id;
32 }
33 #endif
34
is_supported_format(struct sp_plane * plane,uint32_t format)35 int is_supported_format(struct sp_plane* plane, uint32_t format) {
36 uint32_t i;
37
38 for (i = 0; i < plane->plane->count_formats; i++) {
39 if (plane->plane->formats[i] == format)
40 return 1;
41 }
42 return 0;
43 }
44
get_supported_format(struct sp_plane * plane,uint32_t * format)45 static int get_supported_format(struct sp_plane* plane, uint32_t* format) {
46 uint32_t i;
47
48 for (i = 0; i < plane->plane->count_formats; i++) {
49 if (plane->plane->formats[i] == DRM_FORMAT_XRGB8888 ||
50 plane->plane->formats[i] == DRM_FORMAT_ARGB8888 ||
51 plane->plane->formats[i] == DRM_FORMAT_RGBA8888) {
52 *format = plane->plane->formats[i];
53 return 0;
54 }
55 }
56 printf("No suitable formats found!\n");
57 return -ENOENT;
58 }
59
create_sp_dev(void)60 struct sp_dev* create_sp_dev(void) {
61 struct sp_dev* dev;
62 int ret, fd, i, j;
63 drmModeRes* r = NULL;
64 drmModePlaneRes* pr = NULL;
65
66 fd = open("/dev/dri/card0", O_RDWR);
67 if (fd < 0) {
68 printf("failed to open card0\n");
69 return NULL;
70 }
71
72 dev = (struct sp_dev*)calloc(1, sizeof(*dev));
73 if (!dev) {
74 printf("failed to allocate dev\n");
75 return NULL;
76 }
77
78 dev->fd = fd;
79
80 #if 1
81 ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_ATOMIC, 1);
82 if (ret) {
83 printf("failed to set client cap atomic\n");
84 goto err;
85 }
86 ret = drmSetClientCap(dev->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
87 if (ret) {
88 printf("failed to set client cap\n");
89 goto err;
90 }
91 #endif
92
93 r = drmModeGetResources(dev->fd);
94 if (!r) {
95 printf("failed to get r\n");
96 goto err;
97 }
98
99 dev->num_connectors = r->count_connectors;
100 dev->connectors = (drmModeConnectorPtr*)calloc(dev->num_connectors, sizeof(*dev->connectors));
101 if (!dev->connectors) {
102 printf("failed to allocate connectors\n");
103 goto err;
104 }
105 for (i = 0; i < dev->num_connectors; i++) {
106 dev->connectors[i] = drmModeGetConnector(dev->fd,
107 r->connectors[i]);
108 if (!dev->connectors[i]) {
109 printf("failed to get connector %d\n", i);
110 goto err;
111 }
112 }
113
114 dev->num_encoders = r->count_encoders;
115 dev->encoders = (drmModeEncoderPtr*)calloc(dev->num_encoders, sizeof(*dev->encoders));
116 if (!dev->encoders) {
117 printf("failed to allocate encoders\n");
118 goto err;
119 }
120 for (i = 0; i < dev->num_encoders; i++) {
121 dev->encoders[i] = drmModeGetEncoder(dev->fd, r->encoders[i]);
122 if (!dev->encoders[i]) {
123 printf("failed to get encoder %d\n", i);
124 goto err;
125 }
126 }
127
128 dev->num_crtcs = r->count_crtcs;
129 dev->crtcs = (struct sp_crtc*)calloc(dev->num_crtcs, sizeof(struct sp_crtc));
130 if (!dev->crtcs) {
131 printf("failed to allocate crtcs\n");
132 goto err;
133 }
134 for (i = 0; i < dev->num_crtcs; i++) {
135 dev->crtcs[i].crtc = drmModeGetCrtc(dev->fd, r->crtcs[i]);
136 if (!dev->crtcs[i].crtc) {
137 printf("failed to get crtc %d\n", i);
138 goto err;
139 }
140 dev->crtcs[i].scanout = NULL;
141 dev->crtcs[i].pipe = i;
142 dev->crtcs[i].num_planes = 0;
143 }
144
145 pr = drmModeGetPlaneResources(dev->fd);
146 if (!pr) {
147 printf("failed to get plane resources\n");
148 goto err;
149 }
150 dev->num_planes = pr->count_planes;
151 dev->planes = (struct sp_plane*)calloc(dev->num_planes, sizeof(struct sp_plane));
152 for (i = 0; i < dev->num_planes; i++) {
153 drmModeObjectPropertiesPtr props;
154 struct sp_plane* plane = &dev->planes[i];
155
156 plane->dev = dev;
157 plane->plane = drmModeGetPlane(dev->fd, pr->planes[i]);
158 if (!plane->plane) {
159 printf("failed to get plane %d\n", i);
160 goto err;
161 }
162 plane->bo = NULL;
163 plane->in_use = 0;
164
165 ret = get_supported_format(plane, &plane->format);
166 if (ret) {
167 printf("failed to get supported format: %d\n", ret);
168 goto err;
169 }
170
171 for (j = 0; j < dev->num_crtcs; j++) {
172 if (plane->plane->possible_crtcs & (1 << j))
173 dev->crtcs[j].num_planes++;
174 }
175
176 props = drmModeObjectGetProperties(dev->fd, pr->planes[i],
177 DRM_MODE_OBJECT_PLANE);
178 if (!props) {
179 printf("failed to get plane properties\n");
180 goto err;
181 }
182 #if 0//def USE_ATOMIC_API
183 plane->crtc_pid = get_prop_id(dev, props, "CRTC_ID");
184 if (!plane->crtc_pid) {
185 drmModeFreeObjectProperties(props);
186 goto err;
187 }
188 plane->fb_pid = get_prop_id(dev, props, "FB_ID");
189 if (!plane->fb_pid) {
190 drmModeFreeObjectProperties(props);
191 goto err;
192 }
193 plane->crtc_x_pid = get_prop_id(dev, props, "CRTC_X");
194 if (!plane->crtc_x_pid) {
195 drmModeFreeObjectProperties(props);
196 goto err;
197 }
198 plane->crtc_y_pid = get_prop_id(dev, props, "CRTC_Y");
199 if (!plane->crtc_y_pid) {
200 drmModeFreeObjectProperties(props);
201 goto err;
202 }
203 plane->crtc_w_pid = get_prop_id(dev, props, "CRTC_W");
204 if (!plane->crtc_w_pid) {
205 drmModeFreeObjectProperties(props);
206 goto err;
207 }
208 plane->crtc_h_pid = get_prop_id(dev, props, "CRTC_H");
209 if (!plane->crtc_h_pid) {
210 drmModeFreeObjectProperties(props);
211 goto err;
212 }
213 plane->src_x_pid = get_prop_id(dev, props, "SRC_X");
214 if (!plane->src_x_pid) {
215 drmModeFreeObjectProperties(props);
216 goto err;
217 }
218 plane->src_y_pid = get_prop_id(dev, props, "SRC_Y");
219 if (!plane->src_y_pid) {
220 drmModeFreeObjectProperties(props);
221 goto err;
222 }
223 plane->src_w_pid = get_prop_id(dev, props, "SRC_W");
224 if (!plane->src_w_pid) {
225 drmModeFreeObjectProperties(props);
226 goto err;
227 }
228 plane->src_h_pid = get_prop_id(dev, props, "SRC_H");
229 if (!plane->src_h_pid) {
230 drmModeFreeObjectProperties(props);
231 goto err;
232 }
233 #endif
234 drmModeFreeObjectProperties(props);
235 }
236
237 if (pr)
238 drmModeFreePlaneResources(pr);
239 if (r)
240 drmModeFreeResources(r);
241
242 return dev;
243 err:
244 if (pr)
245 drmModeFreePlaneResources(pr);
246 if (r)
247 drmModeFreeResources(r);
248 destroy_sp_dev(dev);
249 return NULL;
250 }
251
destroy_sp_dev(struct sp_dev * dev)252 void destroy_sp_dev(struct sp_dev* dev) {
253 int i;
254
255 if (dev->planes) {
256 for (i = 0; i < dev->num_planes; i++) {
257 if (dev->planes[i].in_use)
258 put_sp_plane(&dev->planes[i]);
259 if (dev->planes[i].plane)
260 drmModeFreePlane(dev->planes[i].plane);
261 if (dev->planes[i].bo)
262 free_sp_bo(dev->planes[i].bo);
263 }
264 free(dev->planes);
265 }
266 if (dev->crtcs) {
267 for (i = 0; i < dev->num_crtcs; i++) {
268 if (dev->crtcs[i].crtc)
269 drmModeFreeCrtc(dev->crtcs[i].crtc);
270 if (dev->crtcs[i].scanout)
271 free_sp_bo(dev->crtcs[i].scanout);
272 }
273 free(dev->crtcs);
274 }
275 if (dev->encoders) {
276 for (i = 0; i < dev->num_encoders; i++) {
277 if (dev->encoders[i])
278 drmModeFreeEncoder(dev->encoders[i]);
279 }
280 free(dev->encoders);
281 }
282 if (dev->connectors) {
283 for (i = 0; i < dev->num_connectors; i++) {
284 if (dev->connectors[i])
285 drmModeFreeConnector(dev->connectors[i]);
286 }
287 free(dev->connectors);
288 }
289
290 close(dev->fd);
291 free(dev);
292 }
293