OSDN Git Service

minigbm: Add evdi minigbm driver.
[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 <fcntl.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <xf86drm.h>
13
14 #include "gbm_priv.h"
15 #include "helpers.h"
16 #include "util.h"
17
18 extern struct gbm_driver gbm_driver_cirrus;
19 extern struct gbm_driver gbm_driver_evdi;
20 #ifdef GBM_EXYNOS
21 extern struct gbm_driver gbm_driver_exynos;
22 #endif
23 extern struct gbm_driver gbm_driver_gma500;
24 #ifdef GBM_I915
25 extern struct gbm_driver gbm_driver_i915;
26 #endif
27 #ifdef GBM_MARVELL
28 extern struct gbm_driver gbm_driver_marvell;
29 #endif
30 #ifdef GBM_MEDIATEK
31 extern struct gbm_driver gbm_driver_mediatek;
32 #endif
33 #ifdef GBM_ROCKCHIP
34 extern struct gbm_driver gbm_driver_rockchip;
35 #endif
36 #ifdef GBM_TEGRA
37 extern struct gbm_driver gbm_driver_tegra;
38 #endif
39 extern struct gbm_driver gbm_driver_udl;
40
41 static struct gbm_driver *gbm_get_driver(int fd)
42 {
43         drmVersionPtr drm_version;
44         unsigned int i;
45
46         drm_version = drmGetVersion(fd);
47
48         if (!drm_version)
49                 return NULL;
50
51         struct gbm_driver *driver_list[] = {
52                 &gbm_driver_cirrus,
53                 &gbm_driver_evdi,
54 #ifdef GBM_EXYNOS
55                 &gbm_driver_exynos,
56 #endif
57                 &gbm_driver_gma500,
58 #ifdef GBM_I915
59                 &gbm_driver_i915,
60 #endif
61 #ifdef GBM_MARVELL
62                 &gbm_driver_marvell,
63 #endif
64 #ifdef GBM_MEDIATEK
65                 &gbm_driver_mediatek,
66 #endif
67 #ifdef GBM_ROCKCHIP
68                 &gbm_driver_rockchip,
69 #endif
70 #ifdef GBM_TEGRA
71                 &gbm_driver_tegra,
72 #endif
73                 &gbm_driver_udl,
74         };
75
76         for(i = 0; i < ARRAY_SIZE(driver_list); i++)
77                 if (!strcmp(drm_version->name, driver_list[i]->name))
78                 {
79                         drmFreeVersion(drm_version);
80                         return driver_list[i];
81                 }
82
83         drmFreeVersion(drm_version);
84         return NULL;
85 }
86
87 PUBLIC int
88 gbm_device_get_fd(struct gbm_device *gbm)
89 {
90         return gbm->fd;
91 }
92
93 PUBLIC const char *
94 gbm_device_get_backend_name(struct gbm_device *gbm)
95 {
96         return gbm->driver->name;
97 }
98
99 PUBLIC int
100 gbm_device_is_format_supported(struct gbm_device *gbm,
101                                uint32_t format, uint32_t usage)
102 {
103         unsigned i;
104
105         if (format == GBM_BO_FORMAT_XRGB8888)
106                 format = GBM_FORMAT_XRGB8888;
107         if (format == GBM_BO_FORMAT_ARGB8888)
108                 format = GBM_FORMAT_ARGB8888;
109
110         if (usage & GBM_BO_USE_CURSOR &&
111                 usage & GBM_BO_USE_RENDERING)
112                 return 0;
113
114         for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++)
115         {
116                 if (!gbm->driver->format_list[i].format)
117                         break;
118
119                 if (gbm->driver->format_list[i].format == format &&
120                         (gbm->driver->format_list[i].usage & usage) == usage)
121                         return 1;
122         }
123
124         return 0;
125 }
126
127 PUBLIC struct gbm_device *gbm_create_device(int fd)
128 {
129         struct gbm_device *gbm;
130         int ret;
131
132         gbm = (struct gbm_device*) malloc(sizeof(*gbm));
133         if (!gbm)
134                 return NULL;
135
136         gbm->fd = fd;
137
138         gbm->driver = gbm_get_driver(fd);
139         if (!gbm->driver) {
140                 free(gbm);
141                 return NULL;
142         }
143
144         if (gbm->driver->init) {
145                 ret = gbm->driver->init(gbm);
146                 if (ret) {
147                         free(gbm);
148                         return NULL;
149                 }
150         }
151
152         return gbm;
153 }
154
155 PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
156 {
157         if (gbm->driver->close)
158                 gbm->driver->close(gbm);
159         free(gbm);
160 }
161
162 PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm,
163                                               uint32_t width, uint32_t height,
164                                               uint32_t format, uint32_t flags)
165 {
166         struct gbm_surface *surface =
167                 (struct gbm_surface*) malloc(sizeof(*surface));
168
169         if (!surface)
170                 return NULL;
171
172         return surface;
173 }
174
175 PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
176 {
177         free(surface);
178 }
179
180 PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
181 {
182         return NULL;
183 }
184
185 PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface,
186                                        struct gbm_bo *bo)
187 {
188 }
189
190 static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm,
191                                  uint32_t width, uint32_t height,
192                                  uint32_t format, uint32_t stride)
193 {
194         struct gbm_bo *bo;
195
196         bo = (struct gbm_bo*) malloc(sizeof(*bo));
197         if (!bo)
198                 return NULL;
199
200         bo->gbm = gbm;
201         bo->width = width;
202         bo->height = height;
203         bo->stride = stride;
204         bo->format = format;
205         bo->handle.u32 = 0;
206         bo->destroy_user_data = NULL;
207         bo->user_data = NULL;
208
209         return bo;
210 }
211
212 PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width,
213                                     uint32_t height, uint32_t format,
214                                     uint32_t flags)
215 {
216         struct gbm_bo *bo;
217         int ret;
218
219         bo = gbm_bo_new(gbm, width, height, format,
220                         width * gbm_bytes_from_format(format));
221         if (!bo)
222                 return NULL;
223
224         ret = gbm->driver->bo_create(bo, width, height, format, flags);
225         if (ret) {
226                 free(bo);
227                 return NULL;
228         }
229
230         return bo;
231 }
232
233 PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
234 {
235         if (bo->destroy_user_data) {
236                 bo->destroy_user_data(bo, bo->user_data);
237                 bo->destroy_user_data = NULL;
238                 bo->user_data = NULL;
239         }
240
241         bo->gbm->driver->bo_destroy(bo);
242         free(bo);
243 }
244
245 PUBLIC struct gbm_bo *
246 gbm_bo_import(struct gbm_device *gbm, uint32_t type,
247               void *buffer, uint32_t usage)
248 {
249         struct gbm_import_fd_data *fd_data = buffer;
250         struct gbm_bo *bo;
251         struct drm_prime_handle prime_handle;
252         int ret;
253
254         if (type != GBM_BO_IMPORT_FD)
255                 return NULL;
256
257         if (!gbm_device_is_format_supported(gbm, fd_data->format, usage))
258                 return NULL;
259
260         bo = gbm_bo_new(gbm, fd_data->width, fd_data->height, fd_data->format,
261                         fd_data->stride);
262         if (!bo)
263                 return NULL;
264
265         prime_handle.fd = fd_data->fd;
266
267         ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_handle);
268         if (ret) {
269                 fprintf(stderr, "minigbm: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
270                                 "(fd=%u)\n", prime_handle.fd);
271                 free(bo);
272                 return NULL;
273         }
274
275         bo->handle.u32 = prime_handle.handle;
276
277         return bo;
278 }
279
280 PUBLIC uint32_t
281 gbm_bo_get_width(struct gbm_bo *bo)
282 {
283         return bo->width;
284 }
285
286 PUBLIC uint32_t
287 gbm_bo_get_height(struct gbm_bo *bo)
288 {
289         return bo->height;
290 }
291
292 PUBLIC uint32_t
293 gbm_bo_get_stride(struct gbm_bo *bo)
294 {
295         return bo->stride;
296 }
297
298 PUBLIC uint32_t
299 gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
300 {
301         return bo->tiling ? bo->tiling : bo->stride;
302 }
303
304 PUBLIC uint32_t
305 gbm_bo_get_format(struct gbm_bo *bo)
306 {
307         return bo->format;
308 }
309
310 PUBLIC struct gbm_device *
311 gbm_bo_get_device(struct gbm_bo *bo)
312 {
313         return bo->gbm;
314 }
315
316 PUBLIC union gbm_bo_handle
317 gbm_bo_get_handle(struct gbm_bo *bo)
318 {
319         return bo->handle;
320 }
321
322 PUBLIC int
323 gbm_bo_get_fd(struct gbm_bo *bo)
324 {
325         int fd;
326
327         if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
328                                 gbm_bo_get_handle(bo).u32,
329                                 DRM_CLOEXEC,
330                                 &fd))
331                 return -1;
332         else
333                 return fd;
334 }
335
336 PUBLIC void
337 gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
338                      void (*destroy_user_data)(struct gbm_bo *, void *))
339 {
340         bo->user_data = data;
341         bo->destroy_user_data = destroy_user_data;
342 }
343
344 PUBLIC void *
345 gbm_bo_get_user_data(struct gbm_bo *bo)
346 {
347         return bo->user_data;
348 }