OSDN Git Service

minigbm: Add marvell 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 #ifdef GBM_EXYNOS
20 extern struct gbm_driver gbm_driver_exynos;
21 #endif
22 extern struct gbm_driver gbm_driver_gma500;
23 #ifdef GBM_I915
24 extern struct gbm_driver gbm_driver_i915;
25 #endif
26 #ifdef GBM_MARVELL
27 extern struct gbm_driver gbm_driver_marvell;
28 #endif
29 #ifdef GBM_MEDIATEK
30 extern struct gbm_driver gbm_driver_mediatek;
31 #endif
32 #ifdef GBM_ROCKCHIP
33 extern struct gbm_driver gbm_driver_rockchip;
34 #endif
35 #ifdef GBM_TEGRA
36 extern struct gbm_driver gbm_driver_tegra;
37 #endif
38 extern struct gbm_driver gbm_driver_udl;
39
40 static struct gbm_driver *gbm_get_driver(int fd)
41 {
42         drmVersionPtr drm_version;
43         unsigned int i;
44
45         drm_version = drmGetVersion(fd);
46
47         if (!drm_version)
48                 return NULL;
49
50         struct gbm_driver *driver_list[] = {
51                 &gbm_driver_cirrus,
52 #ifdef GBM_EXYNOS
53                 &gbm_driver_exynos,
54 #endif
55                 &gbm_driver_gma500,
56 #ifdef GBM_I915
57                 &gbm_driver_i915,
58 #endif
59 #ifdef GBM_MARVELL
60                 &gbm_driver_marvell,
61 #endif
62 #ifdef GBM_MEDIATEK
63                 &gbm_driver_mediatek,
64 #endif
65 #ifdef GBM_ROCKCHIP
66                 &gbm_driver_rockchip,
67 #endif
68 #ifdef GBM_TEGRA
69                 &gbm_driver_tegra,
70 #endif
71                 &gbm_driver_udl,
72         };
73
74         for(i = 0; i < ARRAY_SIZE(driver_list); i++)
75                 if (!strcmp(drm_version->name, driver_list[i]->name))
76                 {
77                         drmFreeVersion(drm_version);
78                         return driver_list[i];
79                 }
80
81         drmFreeVersion(drm_version);
82         return NULL;
83 }
84
85 PUBLIC int
86 gbm_device_get_fd(struct gbm_device *gbm)
87 {
88         return gbm->fd;
89 }
90
91 PUBLIC const char *
92 gbm_device_get_backend_name(struct gbm_device *gbm)
93 {
94         return gbm->driver->name;
95 }
96
97 PUBLIC int
98 gbm_device_is_format_supported(struct gbm_device *gbm,
99                                uint32_t format, uint32_t usage)
100 {
101         unsigned i;
102
103         if (format == GBM_BO_FORMAT_XRGB8888)
104                 format = GBM_FORMAT_XRGB8888;
105         if (format == GBM_BO_FORMAT_ARGB8888)
106                 format = GBM_FORMAT_ARGB8888;
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, uint32_t stride)
191 {
192         struct gbm_bo *bo;
193
194         bo = (struct gbm_bo*) malloc(sizeof(*bo));
195         if (!bo)
196                 return NULL;
197
198         bo->gbm = gbm;
199         bo->width = width;
200         bo->height = height;
201         bo->stride = stride;
202         bo->format = format;
203         bo->handle.u32 = 0;
204         bo->destroy_user_data = NULL;
205         bo->user_data = NULL;
206
207         return bo;
208 }
209
210 PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width,
211                                     uint32_t height, uint32_t format,
212                                     uint32_t flags)
213 {
214         struct gbm_bo *bo;
215         int ret;
216
217         bo = gbm_bo_new(gbm, width, height, format,
218                         width * gbm_bytes_from_format(format));
219         if (!bo)
220                 return NULL;
221
222         ret = gbm->driver->bo_create(bo, width, height, format, flags);
223         if (ret) {
224                 free(bo);
225                 return NULL;
226         }
227
228         return bo;
229 }
230
231 PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
232 {
233         if (bo->destroy_user_data) {
234                 bo->destroy_user_data(bo, bo->user_data);
235                 bo->destroy_user_data = NULL;
236                 bo->user_data = NULL;
237         }
238
239         bo->gbm->driver->bo_destroy(bo);
240         free(bo);
241 }
242
243 PUBLIC struct gbm_bo *
244 gbm_bo_import(struct gbm_device *gbm, uint32_t type,
245               void *buffer, uint32_t usage)
246 {
247         struct gbm_import_fd_data *fd_data = buffer;
248         struct gbm_bo *bo;
249         struct drm_prime_handle prime_handle;
250         int ret;
251
252         if (type != GBM_BO_IMPORT_FD)
253                 return NULL;
254
255         if (!gbm_device_is_format_supported(gbm, fd_data->format, usage))
256                 return NULL;
257
258         bo = gbm_bo_new(gbm, fd_data->width, fd_data->height, fd_data->format,
259                         fd_data->stride);
260         if (!bo)
261                 return NULL;
262
263         prime_handle.fd = fd_data->fd;
264
265         ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &prime_handle);
266         if (ret) {
267                 fprintf(stderr, "minigbm: DRM_IOCTL_PRIME_FD_TO_HANDLE failed "
268                                 "(fd=%u)\n", prime_handle.fd);
269                 free(bo);
270                 return NULL;
271         }
272
273         bo->handle.u32 = prime_handle.handle;
274
275         return bo;
276 }
277
278 PUBLIC uint32_t
279 gbm_bo_get_width(struct gbm_bo *bo)
280 {
281         return bo->width;
282 }
283
284 PUBLIC uint32_t
285 gbm_bo_get_height(struct gbm_bo *bo)
286 {
287         return bo->height;
288 }
289
290 PUBLIC uint32_t
291 gbm_bo_get_stride(struct gbm_bo *bo)
292 {
293         return bo->stride;
294 }
295
296 PUBLIC uint32_t
297 gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
298 {
299         return bo->tiling ? bo->tiling : bo->stride;
300 }
301
302 PUBLIC uint32_t
303 gbm_bo_get_format(struct gbm_bo *bo)
304 {
305         return bo->format;
306 }
307
308 PUBLIC struct gbm_device *
309 gbm_bo_get_device(struct gbm_bo *bo)
310 {
311         return bo->gbm;
312 }
313
314 PUBLIC union gbm_bo_handle
315 gbm_bo_get_handle(struct gbm_bo *bo)
316 {
317         return bo->handle;
318 }
319
320 PUBLIC int
321 gbm_bo_get_fd(struct gbm_bo *bo)
322 {
323         int fd;
324
325         if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
326                                 gbm_bo_get_handle(bo).u32,
327                                 DRM_CLOEXEC,
328                                 &fd))
329                 return -1;
330         else
331                 return fd;
332 }
333
334 PUBLIC void
335 gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
336                      void (*destroy_user_data)(struct gbm_bo *, void *))
337 {
338         bo->user_data = data;
339         bo->destroy_user_data = destroy_user_data;
340 }
341
342 PUBLIC void *
343 gbm_bo_get_user_data(struct gbm_bo *bo)
344 {
345         return bo->user_data;
346 }