OSDN Git Service

remove enum gbm_bo_format
[android-x86/external-minigbm.git] / gbm.c
1 /*
2  * Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <xf86drm.h>
14
15 #include "gbm_priv.h"
16 #include "helpers.h"
17 #include "util.h"
18
19 extern struct gbm_driver gbm_driver_cirrus;
20 extern struct gbm_driver gbm_driver_evdi;
21 #ifdef GBM_EXYNOS
22 extern struct gbm_driver gbm_driver_exynos;
23 #endif
24 extern struct gbm_driver gbm_driver_gma500;
25 #ifdef GBM_I915
26 extern struct gbm_driver gbm_driver_i915;
27 #endif
28 #ifdef GBM_MARVELL
29 extern struct gbm_driver gbm_driver_marvell;
30 #endif
31 #ifdef GBM_MEDIATEK
32 extern struct gbm_driver gbm_driver_mediatek;
33 #endif
34 #ifdef GBM_ROCKCHIP
35 extern struct gbm_driver gbm_driver_rockchip;
36 #endif
37 #ifdef GBM_TEGRA
38 extern struct gbm_driver gbm_driver_tegra;
39 #endif
40 extern struct gbm_driver gbm_driver_udl;
41 extern struct gbm_driver gbm_driver_virtio_gpu;
42
43 static struct gbm_driver *gbm_get_driver(int fd)
44 {
45         drmVersionPtr drm_version;
46         unsigned int i;
47
48         drm_version = drmGetVersion(fd);
49
50         if (!drm_version)
51                 return NULL;
52
53         struct gbm_driver *driver_list[] = {
54                 &gbm_driver_cirrus,
55                 &gbm_driver_evdi,
56 #ifdef GBM_EXYNOS
57                 &gbm_driver_exynos,
58 #endif
59                 &gbm_driver_gma500,
60 #ifdef GBM_I915
61                 &gbm_driver_i915,
62 #endif
63 #ifdef GBM_MARVELL
64                 &gbm_driver_marvell,
65 #endif
66 #ifdef GBM_MEDIATEK
67                 &gbm_driver_mediatek,
68 #endif
69 #ifdef GBM_ROCKCHIP
70                 &gbm_driver_rockchip,
71 #endif
72 #ifdef GBM_TEGRA
73                 &gbm_driver_tegra,
74 #endif
75                 &gbm_driver_udl,
76                 &gbm_driver_virtio_gpu,
77         };
78
79         for(i = 0; i < ARRAY_SIZE(driver_list); i++)
80                 if (!strcmp(drm_version->name, driver_list[i]->name))
81                 {
82                         drmFreeVersion(drm_version);
83                         return driver_list[i];
84                 }
85
86         drmFreeVersion(drm_version);
87         return NULL;
88 }
89
90 PUBLIC int
91 gbm_device_get_fd(struct gbm_device *gbm)
92 {
93         return gbm->fd;
94 }
95
96 PUBLIC const char *
97 gbm_device_get_backend_name(struct gbm_device *gbm)
98 {
99         return gbm->driver->name;
100 }
101
102 PUBLIC int
103 gbm_device_is_format_supported(struct gbm_device *gbm,
104                                uint32_t format, uint32_t usage)
105 {
106         unsigned i;
107
108         if (usage & GBM_BO_USE_CURSOR &&
109                 usage & GBM_BO_USE_RENDERING)
110                 return 0;
111
112         for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++)
113         {
114                 if (!gbm->driver->format_list[i].format)
115                         break;
116
117                 if (gbm->driver->format_list[i].format == format &&
118                         (gbm->driver->format_list[i].usage & usage) == usage)
119                         return 1;
120         }
121
122         return 0;
123 }
124
125 PUBLIC struct gbm_device *gbm_create_device(int fd)
126 {
127         struct gbm_device *gbm;
128         int ret;
129
130         gbm = (struct gbm_device*) malloc(sizeof(*gbm));
131         if (!gbm)
132                 return NULL;
133
134         gbm->fd = fd;
135
136         gbm->driver = gbm_get_driver(fd);
137         if (!gbm->driver) {
138                 free(gbm);
139                 return NULL;
140         }
141
142         if (gbm->driver->init) {
143                 ret = gbm->driver->init(gbm);
144                 if (ret) {
145                         free(gbm);
146                         return NULL;
147                 }
148         }
149
150         return gbm;
151 }
152
153 PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
154 {
155         if (gbm->driver->close)
156                 gbm->driver->close(gbm);
157         free(gbm);
158 }
159
160 PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm,
161                                               uint32_t width, uint32_t height,
162                                               uint32_t format, uint32_t flags)
163 {
164         struct gbm_surface *surface =
165                 (struct gbm_surface*) malloc(sizeof(*surface));
166
167         if (!surface)
168                 return NULL;
169
170         return surface;
171 }
172
173 PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
174 {
175         free(surface);
176 }
177
178 PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
179 {
180         return NULL;
181 }
182
183 PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface,
184                                        struct gbm_bo *bo)
185 {
186 }
187
188 static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm,
189                                  uint32_t width, uint32_t height,
190                                  uint32_t format)
191 {
192         struct gbm_bo *bo;
193
194         bo = (struct gbm_bo*) calloc(1, sizeof(*bo));
195         if (!bo)
196                 return NULL;
197
198         bo->gbm = gbm;
199         bo->width = width;
200         bo->height = height;
201         bo->format = format;
202         bo->num_planes = gbm_num_planes_from_format(format);
203         if (!bo->num_planes) {
204                 free(bo);
205                 return NULL;
206         }
207
208         return bo;
209 }
210
211 PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width,
212                                     uint32_t height, uint32_t format,
213                                     uint32_t flags)
214 {
215         struct gbm_bo *bo;
216         int ret;
217
218         if (!gbm_device_is_format_supported(gbm, format, flags))
219                 return NULL;
220
221         bo = gbm_bo_new(gbm, width, height, format);
222         if (!bo)
223                 return NULL;
224
225         ret = gbm->driver->bo_create(bo, width, height, format, flags);
226         if (ret) {
227                 free(bo);
228                 return NULL;
229         }
230
231         return bo;
232 }
233
234 PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
235 {
236         if (bo->destroy_user_data) {
237                 bo->destroy_user_data(bo, bo->user_data);
238                 bo->destroy_user_data = NULL;
239                 bo->user_data = NULL;
240         }
241
242         bo->gbm->driver->bo_destroy(bo);
243         free(bo);
244 }
245
246 PUBLIC struct gbm_bo *
247 gbm_bo_import(struct gbm_device *gbm, uint32_t type,
248               void *buffer, uint32_t usage)
249 {
250         struct gbm_import_fd_data *fd_data = buffer;
251         struct gbm_bo *bo;
252         struct drm_prime_handle prime_handle;
253         int ret;
254
255         if (type != GBM_BO_IMPORT_FD)
256                 return NULL;
257
258         if (!gbm_device_is_format_supported(gbm, fd_data->format, usage))
259                 return NULL;
260
261         /* This function can support only single plane formats. */
262         /* If multi-plane import is desired, new function should be added. */
263         if (gbm_num_planes_from_format(fd_data->format) != 1)
264                 return NULL;
265
266         bo = gbm_bo_new(gbm, fd_data->width, fd_data->height, fd_data->format);
267         if (!bo)
268                 return NULL;
269
270         bo->strides[0] = fd_data->stride;
271         bo->sizes[0] = fd_data->height * fd_data->stride;
272
273         memset(&prime_handle, 0, sizeof(prime_handle));
274         prime_handle.fd = fd_data->fd;
275
276         ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_handle);
277         if (ret) {
278                 fprintf(stderr, "minigbm: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
279                                 "(fd=%u)\n", prime_handle.fd);
280                 free(bo);
281                 return NULL;
282         }
283
284         bo->handles[0].u32 = prime_handle.handle;
285
286         return bo;
287 }
288
289 PUBLIC uint32_t
290 gbm_bo_get_width(struct gbm_bo *bo)
291 {
292         return bo->width;
293 }
294
295 PUBLIC uint32_t
296 gbm_bo_get_height(struct gbm_bo *bo)
297 {
298         return bo->height;
299 }
300
301 PUBLIC uint32_t
302 gbm_bo_get_stride(struct gbm_bo *bo)
303 {
304         return gbm_bo_get_plane_stride(bo, 0);
305 }
306
307 PUBLIC uint32_t
308 gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
309 {
310         return bo->tiling ? bo->tiling : gbm_bo_get_stride(bo);
311 }
312
313 PUBLIC uint32_t
314 gbm_bo_get_format(struct gbm_bo *bo)
315 {
316         return bo->format;
317 }
318
319 PUBLIC struct gbm_device *
320 gbm_bo_get_device(struct gbm_bo *bo)
321 {
322         return bo->gbm;
323 }
324
325 PUBLIC union gbm_bo_handle
326 gbm_bo_get_handle(struct gbm_bo *bo)
327 {
328         return gbm_bo_get_plane_handle(bo, 0);
329 }
330
331 PUBLIC int
332 gbm_bo_get_fd(struct gbm_bo *bo)
333 {
334         return gbm_bo_get_plane_fd(bo, 0);
335 }
336
337 PUBLIC size_t
338 gbm_bo_get_num_planes(struct gbm_bo *bo)
339 {
340         return bo->num_planes;
341 }
342
343 PUBLIC union gbm_bo_handle
344 gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane)
345 {
346         assert(plane < bo->num_planes);
347         return bo->handles[plane];
348 }
349
350 #ifndef DRM_RDWR
351 #define DRM_RDWR O_RDWR
352 #endif
353
354 PUBLIC int
355 gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane)
356 {
357         int fd;
358         assert(plane < bo->num_planes);
359
360         if (drmPrimeHandleToFD(
361                         gbm_device_get_fd(bo->gbm),
362                         gbm_bo_get_plane_handle(bo, plane).u32,
363                         DRM_CLOEXEC | DRM_RDWR,
364                         &fd))
365                 return -1;
366         else
367                 return fd;
368 }
369
370 PUBLIC uint32_t
371 gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane)
372 {
373         assert(plane < bo->num_planes);
374         return bo->offsets[plane];
375 }
376
377 PUBLIC uint32_t
378 gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane)
379 {
380         assert(plane < bo->num_planes);
381         return bo->sizes[plane];
382 }
383
384 PUBLIC uint32_t
385 gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane)
386 {
387         assert(plane < bo->num_planes);
388         return bo->strides[plane];
389 }
390
391 PUBLIC void
392 gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
393                      void (*destroy_user_data)(struct gbm_bo *, void *))
394 {
395         bo->user_data = data;
396         bo->destroy_user_data = destroy_user_data;
397 }
398
399 PUBLIC void *
400 gbm_bo_get_user_data(struct gbm_bo *bo)
401 {
402         return bo->user_data;
403 }