OSDN Git Service

minigbm: Fix cursor and scanout flags
[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 "drv.h"
16 #include "gbm_priv.h"
17 #include "gbm_helpers.h"
18 #include "util.h"
19
20 PUBLIC int
21 gbm_device_get_fd(struct gbm_device *gbm)
22 {
23
24         return drv_get_fd(gbm->drv);
25 }
26
27 PUBLIC const char *
28 gbm_device_get_backend_name(struct gbm_device *gbm)
29 {
30         return drv_get_name(gbm->drv);
31 }
32
33 PUBLIC int
34 gbm_device_is_format_supported(struct gbm_device *gbm,
35                                uint32_t format, uint32_t usage)
36 {
37         uint64_t drv_usage;
38
39         if (usage & GBM_BO_USE_CURSOR &&
40                 usage & GBM_BO_USE_RENDERING)
41                 return 0;
42
43         drv_usage = gbm_convert_flags(usage);
44
45         return drv_is_combination_supported(gbm->drv, format, drv_usage,
46                                             DRM_FORMAT_MOD_NONE);
47 }
48
49 PUBLIC struct gbm_device *gbm_create_device(int fd)
50 {
51         struct gbm_device *gbm;
52
53         gbm = (struct gbm_device*) malloc(sizeof(*gbm));
54
55         if (!gbm)
56                 return NULL;
57
58         gbm->drv = drv_create(fd);
59         if (!gbm->drv) {
60                 free(gbm);
61                 return NULL;
62         }
63
64         return gbm;
65 }
66
67 PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
68 {
69         drv_destroy(gbm->drv);
70         free(gbm);
71 }
72
73 PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm,
74                                               uint32_t width, uint32_t height,
75                                               uint32_t format, uint32_t flags)
76 {
77         struct gbm_surface *surface =
78                 (struct gbm_surface*) malloc(sizeof(*surface));
79
80         if (!surface)
81                 return NULL;
82
83         return surface;
84 }
85
86 PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
87 {
88         free(surface);
89 }
90
91 PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
92 {
93         return NULL;
94 }
95
96 PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface,
97                                        struct gbm_bo *bo)
98 {
99 }
100
101 static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format)
102 {
103         struct gbm_bo *bo;
104
105         bo = (struct gbm_bo*) calloc(1, sizeof(*bo));
106         if (!bo)
107                 return NULL;
108
109         bo->gbm = gbm;
110         bo->gbm_format = format;
111
112         return bo;
113 }
114
115 PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width,
116                                     uint32_t height, uint32_t format,
117                                     uint32_t flags)
118 {
119         struct gbm_bo *bo;
120
121         if (!gbm_device_is_format_supported(gbm, format, flags))
122                 return NULL;
123
124         bo = gbm_bo_new(gbm, format);
125
126         if (!bo)
127                 return NULL;
128
129         bo->bo = drv_bo_create(gbm->drv, width, height, format,
130                                gbm_convert_flags(flags));
131
132         if (!bo->bo) {
133                 free(bo);
134                 return NULL;
135         }
136
137         return bo;
138 }
139
140 PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
141 {
142         if (bo->destroy_user_data) {
143                 bo->destroy_user_data(bo, bo->user_data);
144                 bo->destroy_user_data = NULL;
145                 bo->user_data = NULL;
146         }
147
148         drv_bo_destroy(bo->bo);
149         free(bo);
150 }
151
152 PUBLIC struct gbm_bo *
153 gbm_bo_import(struct gbm_device *gbm, uint32_t type,
154               void *buffer, uint32_t usage)
155 {
156         struct gbm_bo *bo;
157         struct drv_import_fd_data drv_data;
158         struct gbm_import_fd_data *fd_data = buffer;
159         struct gbm_import_fd_planar_data *fd_planar_data = buffer;
160         uint32_t gbm_format;
161         size_t num_planes, i;
162
163         memset(&drv_data, 0, sizeof(drv_data));
164
165         switch (type) {
166         case GBM_BO_IMPORT_FD:
167                 gbm_format = fd_data->format;
168                 drv_data.width = fd_data->width;
169                 drv_data.height = fd_data->height;
170                 drv_data.format = fd_data->format;
171                 drv_data.fds[0] = fd_data->fd;
172                 drv_data.strides[0] = fd_data->stride;
173                 drv_data.sizes[0] = fd_data->height * fd_data->stride;
174                 break;
175         case GBM_BO_IMPORT_FD_PLANAR:
176                 gbm_format = fd_planar_data->format;
177                 drv_data.width = fd_planar_data->width;
178                 drv_data.height = fd_planar_data->height;
179                 drv_data.format = fd_planar_data->format;
180                 num_planes = drv_num_planes_from_format(drv_data.format);
181
182                 assert(num_planes);
183
184                 for (i = 0; i < num_planes; i++) {
185                         drv_data.fds[i] = fd_planar_data->fds[i];
186                         drv_data.offsets[i] = fd_planar_data->offsets[i];
187                         drv_data.strides[i] = fd_planar_data->strides[i];
188                         drv_data.format_modifiers[i] =
189                                 fd_planar_data->format_modifiers[i];
190
191                         drv_data.sizes[i] = drv_size_from_format(
192                                                 drv_data.format,
193                                                 drv_data.strides[i],
194                                                 drv_data.height,
195                                                 i);
196                 }
197
198                 for (i = num_planes; i < GBM_MAX_PLANES; i++)
199                         drv_data.fds[i] = -1;
200
201                 break;
202         default:
203                 return NULL;
204         }
205
206         if (!gbm_device_is_format_supported(gbm, gbm_format, usage))
207                 return NULL;
208
209         bo = gbm_bo_new(gbm, gbm_format);
210
211         if (!bo)
212                 return NULL;
213
214         bo->bo = drv_bo_import(gbm->drv, &drv_data);
215
216         if (!bo->bo) {
217                 free(bo);
218                 return NULL;
219         }
220
221         return bo;
222 }
223
224 PUBLIC void *
225 gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width,
226            uint32_t height, uint32_t flags, uint32_t *stride, void **map_data,
227            size_t plane)
228 {
229         if (!bo || width == 0 || height == 0 || !stride || !map_data)
230                 return NULL;
231
232         *stride = gbm_bo_get_plane_stride(bo, plane);
233         return drv_bo_map(bo->bo, x, y, width, height, 0, map_data, plane);
234 }
235
236 PUBLIC void
237 gbm_bo_unmap(struct gbm_bo *bo, void *map_data)
238 {
239         assert(bo);
240         drv_bo_unmap(bo->bo, map_data);
241 }
242
243 PUBLIC uint32_t
244 gbm_bo_get_width(struct gbm_bo *bo)
245 {
246         return drv_bo_get_width(bo->bo);
247 }
248
249 PUBLIC uint32_t
250 gbm_bo_get_height(struct gbm_bo *bo)
251 {
252         return drv_bo_get_height(bo->bo);
253 }
254
255 PUBLIC uint32_t
256 gbm_bo_get_stride(struct gbm_bo *bo)
257 {
258         return gbm_bo_get_plane_stride(bo, 0);
259 }
260
261 PUBLIC uint32_t
262 gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
263 {
264         return drv_bo_get_stride_or_tiling(bo->bo);
265 }
266
267 PUBLIC uint32_t
268 gbm_bo_get_format(struct gbm_bo *bo)
269 {
270         return bo->gbm_format;
271 }
272
273 PUBLIC uint64_t
274 gbm_bo_get_format_modifier(struct gbm_bo *bo)
275 {
276         return gbm_bo_get_plane_format_modifier(bo, 0);
277 }
278
279 PUBLIC struct gbm_device *
280 gbm_bo_get_device(struct gbm_bo *bo)
281 {
282         return bo->gbm;
283 }
284
285 PUBLIC union gbm_bo_handle
286 gbm_bo_get_handle(struct gbm_bo *bo)
287 {
288         return gbm_bo_get_plane_handle(bo, 0);
289 }
290
291 PUBLIC int
292 gbm_bo_get_fd(struct gbm_bo *bo)
293 {
294         return gbm_bo_get_plane_fd(bo, 0);
295 }
296
297 PUBLIC size_t
298 gbm_bo_get_num_planes(struct gbm_bo *bo)
299 {
300         return drv_bo_get_num_planes(bo->bo);
301 }
302
303 PUBLIC union gbm_bo_handle
304 gbm_bo_get_plane_handle(struct gbm_bo *bo, size_t plane)
305 {
306         return (union gbm_bo_handle) drv_bo_get_plane_handle(bo->bo, plane).u64;
307 }
308
309 PUBLIC int
310 gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane)
311 {
312         return drv_bo_get_plane_fd(bo->bo, plane);
313 }
314
315 PUBLIC uint32_t
316 gbm_bo_get_plane_offset(struct gbm_bo *bo, size_t plane)
317 {
318         return drv_bo_get_plane_offset(bo->bo, plane);
319 }
320
321 PUBLIC uint32_t
322 gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane)
323 {
324         return drv_bo_get_plane_size(bo->bo, plane);
325 }
326
327 PUBLIC uint32_t
328 gbm_bo_get_plane_stride(struct gbm_bo *bo, size_t plane)
329 {
330         return drv_bo_get_plane_stride(bo->bo, plane);
331 }
332
333 PUBLIC uint64_t
334 gbm_bo_get_plane_format_modifier(struct gbm_bo *bo, size_t plane)
335 {
336         return drv_bo_get_plane_format_modifier(bo->bo, plane);
337 }
338
339 PUBLIC void
340 gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
341                      void (*destroy_user_data)(struct gbm_bo *, void *))
342 {
343         bo->user_data = data;
344         bo->destroy_user_data = destroy_user_data;
345 }
346
347 PUBLIC void *
348 gbm_bo_get_user_data(struct gbm_bo *bo)
349 {
350         return bo->user_data;
351 }