1*d95af8dfSAndroid Build Coastguard Worker /*
2*d95af8dfSAndroid Build Coastguard Worker * Copyright 2014 The Chromium OS Authors. All rights reserved.
3*d95af8dfSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
4*d95af8dfSAndroid Build Coastguard Worker * found in the LICENSE file.
5*d95af8dfSAndroid Build Coastguard Worker */
6*d95af8dfSAndroid Build Coastguard Worker
7*d95af8dfSAndroid Build Coastguard Worker #include <assert.h>
8*d95af8dfSAndroid Build Coastguard Worker #include <fcntl.h>
9*d95af8dfSAndroid Build Coastguard Worker #include <stdint.h>
10*d95af8dfSAndroid Build Coastguard Worker #include <stdio.h>
11*d95af8dfSAndroid Build Coastguard Worker #include <stdlib.h>
12*d95af8dfSAndroid Build Coastguard Worker #include <string.h>
13*d95af8dfSAndroid Build Coastguard Worker #include <sys/mman.h>
14*d95af8dfSAndroid Build Coastguard Worker #include <xf86drm.h>
15*d95af8dfSAndroid Build Coastguard Worker
16*d95af8dfSAndroid Build Coastguard Worker #include "drv.h"
17*d95af8dfSAndroid Build Coastguard Worker #include "gbm_helpers.h"
18*d95af8dfSAndroid Build Coastguard Worker #include "gbm_priv.h"
19*d95af8dfSAndroid Build Coastguard Worker #include "util.h"
20*d95af8dfSAndroid Build Coastguard Worker
gbm_device_get_fd(struct gbm_device * gbm)21*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_device_get_fd(struct gbm_device *gbm)
22*d95af8dfSAndroid Build Coastguard Worker {
23*d95af8dfSAndroid Build Coastguard Worker
24*d95af8dfSAndroid Build Coastguard Worker return drv_get_fd(gbm->drv);
25*d95af8dfSAndroid Build Coastguard Worker }
26*d95af8dfSAndroid Build Coastguard Worker
gbm_device_get_backend_name(struct gbm_device * gbm)27*d95af8dfSAndroid Build Coastguard Worker PUBLIC const char *gbm_device_get_backend_name(struct gbm_device *gbm)
28*d95af8dfSAndroid Build Coastguard Worker {
29*d95af8dfSAndroid Build Coastguard Worker return drv_get_name(gbm->drv);
30*d95af8dfSAndroid Build Coastguard Worker }
31*d95af8dfSAndroid Build Coastguard Worker
gbm_device_is_format_supported(struct gbm_device * gbm,uint32_t format,uint32_t usage)32*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage)
33*d95af8dfSAndroid Build Coastguard Worker {
34*d95af8dfSAndroid Build Coastguard Worker uint64_t use_flags;
35*d95af8dfSAndroid Build Coastguard Worker
36*d95af8dfSAndroid Build Coastguard Worker if (usage & GBM_BO_USE_CURSOR && usage & GBM_BO_USE_RENDERING)
37*d95af8dfSAndroid Build Coastguard Worker return 0;
38*d95af8dfSAndroid Build Coastguard Worker
39*d95af8dfSAndroid Build Coastguard Worker use_flags = gbm_convert_usage(usage);
40*d95af8dfSAndroid Build Coastguard Worker
41*d95af8dfSAndroid Build Coastguard Worker return (drv_get_combination(gbm->drv, format, use_flags) != NULL);
42*d95af8dfSAndroid Build Coastguard Worker }
43*d95af8dfSAndroid Build Coastguard Worker
gbm_device_get_format_modifier_plane_count(struct gbm_device * gbm,uint32_t format,uint64_t modifier)44*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, uint32_t format,
45*d95af8dfSAndroid Build Coastguard Worker uint64_t modifier)
46*d95af8dfSAndroid Build Coastguard Worker {
47*d95af8dfSAndroid Build Coastguard Worker return 0;
48*d95af8dfSAndroid Build Coastguard Worker }
49*d95af8dfSAndroid Build Coastguard Worker
gbm_create_device(int fd)50*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_device *gbm_create_device(int fd)
51*d95af8dfSAndroid Build Coastguard Worker {
52*d95af8dfSAndroid Build Coastguard Worker struct gbm_device *gbm;
53*d95af8dfSAndroid Build Coastguard Worker
54*d95af8dfSAndroid Build Coastguard Worker gbm = (struct gbm_device *)malloc(sizeof(*gbm));
55*d95af8dfSAndroid Build Coastguard Worker
56*d95af8dfSAndroid Build Coastguard Worker if (!gbm)
57*d95af8dfSAndroid Build Coastguard Worker return NULL;
58*d95af8dfSAndroid Build Coastguard Worker
59*d95af8dfSAndroid Build Coastguard Worker gbm->drv = drv_create(fd);
60*d95af8dfSAndroid Build Coastguard Worker if (!gbm->drv) {
61*d95af8dfSAndroid Build Coastguard Worker free(gbm);
62*d95af8dfSAndroid Build Coastguard Worker return NULL;
63*d95af8dfSAndroid Build Coastguard Worker }
64*d95af8dfSAndroid Build Coastguard Worker
65*d95af8dfSAndroid Build Coastguard Worker return gbm;
66*d95af8dfSAndroid Build Coastguard Worker }
67*d95af8dfSAndroid Build Coastguard Worker
gbm_device_destroy(struct gbm_device * gbm)68*d95af8dfSAndroid Build Coastguard Worker PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
69*d95af8dfSAndroid Build Coastguard Worker {
70*d95af8dfSAndroid Build Coastguard Worker drv_destroy(gbm->drv);
71*d95af8dfSAndroid Build Coastguard Worker free(gbm);
72*d95af8dfSAndroid Build Coastguard Worker }
73*d95af8dfSAndroid Build Coastguard Worker
gbm_surface_create(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,uint32_t usage)74*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width,
75*d95af8dfSAndroid Build Coastguard Worker uint32_t height, uint32_t format, uint32_t usage)
76*d95af8dfSAndroid Build Coastguard Worker {
77*d95af8dfSAndroid Build Coastguard Worker struct gbm_surface *surface = (struct gbm_surface *)malloc(sizeof(*surface));
78*d95af8dfSAndroid Build Coastguard Worker
79*d95af8dfSAndroid Build Coastguard Worker if (!surface)
80*d95af8dfSAndroid Build Coastguard Worker return NULL;
81*d95af8dfSAndroid Build Coastguard Worker
82*d95af8dfSAndroid Build Coastguard Worker return surface;
83*d95af8dfSAndroid Build Coastguard Worker }
84*d95af8dfSAndroid Build Coastguard Worker
gbm_surface_create_with_modifiers(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,const unsigned int count)85*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_surface *gbm_surface_create_with_modifiers(struct gbm_device *gbm, uint32_t width,
86*d95af8dfSAndroid Build Coastguard Worker uint32_t height, uint32_t format,
87*d95af8dfSAndroid Build Coastguard Worker const uint64_t *modifiers,
88*d95af8dfSAndroid Build Coastguard Worker const unsigned int count)
89*d95af8dfSAndroid Build Coastguard Worker {
90*d95af8dfSAndroid Build Coastguard Worker return gbm_surface_create_with_modifiers2(gbm, width, height, format, modifiers, count, 0);
91*d95af8dfSAndroid Build Coastguard Worker }
92*d95af8dfSAndroid Build Coastguard Worker
93*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_surface *
gbm_surface_create_with_modifiers2(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,const unsigned int count,uint32_t flags)94*d95af8dfSAndroid Build Coastguard Worker gbm_surface_create_with_modifiers2(struct gbm_device *gbm, uint32_t width, uint32_t height,
95*d95af8dfSAndroid Build Coastguard Worker uint32_t format, const uint64_t *modifiers,
96*d95af8dfSAndroid Build Coastguard Worker const unsigned int count, uint32_t flags)
97*d95af8dfSAndroid Build Coastguard Worker {
98*d95af8dfSAndroid Build Coastguard Worker if (count != 0 || modifiers != NULL)
99*d95af8dfSAndroid Build Coastguard Worker return NULL;
100*d95af8dfSAndroid Build Coastguard Worker
101*d95af8dfSAndroid Build Coastguard Worker if (flags != 0)
102*d95af8dfSAndroid Build Coastguard Worker return NULL;
103*d95af8dfSAndroid Build Coastguard Worker
104*d95af8dfSAndroid Build Coastguard Worker return gbm_surface_create(gbm, width, height, format, flags);
105*d95af8dfSAndroid Build Coastguard Worker }
106*d95af8dfSAndroid Build Coastguard Worker
gbm_surface_lock_front_buffer(struct gbm_surface * surface)107*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
108*d95af8dfSAndroid Build Coastguard Worker {
109*d95af8dfSAndroid Build Coastguard Worker return NULL;
110*d95af8dfSAndroid Build Coastguard Worker }
111*d95af8dfSAndroid Build Coastguard Worker
gbm_surface_release_buffer(struct gbm_surface * surface,struct gbm_bo * bo)112*d95af8dfSAndroid Build Coastguard Worker PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo)
113*d95af8dfSAndroid Build Coastguard Worker {
114*d95af8dfSAndroid Build Coastguard Worker }
115*d95af8dfSAndroid Build Coastguard Worker
gbm_surface_has_free_buffers(struct gbm_surface * surface)116*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_surface_has_free_buffers(struct gbm_surface *surface)
117*d95af8dfSAndroid Build Coastguard Worker {
118*d95af8dfSAndroid Build Coastguard Worker return 0;
119*d95af8dfSAndroid Build Coastguard Worker }
120*d95af8dfSAndroid Build Coastguard Worker
gbm_surface_destroy(struct gbm_surface * surface)121*d95af8dfSAndroid Build Coastguard Worker PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
122*d95af8dfSAndroid Build Coastguard Worker {
123*d95af8dfSAndroid Build Coastguard Worker free(surface);
124*d95af8dfSAndroid Build Coastguard Worker }
125*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_new(struct gbm_device * gbm,uint32_t format)126*d95af8dfSAndroid Build Coastguard Worker static struct gbm_bo *gbm_bo_new(struct gbm_device *gbm, uint32_t format)
127*d95af8dfSAndroid Build Coastguard Worker {
128*d95af8dfSAndroid Build Coastguard Worker struct gbm_bo *bo;
129*d95af8dfSAndroid Build Coastguard Worker
130*d95af8dfSAndroid Build Coastguard Worker bo = (struct gbm_bo *)calloc(1, sizeof(*bo));
131*d95af8dfSAndroid Build Coastguard Worker if (!bo)
132*d95af8dfSAndroid Build Coastguard Worker return NULL;
133*d95af8dfSAndroid Build Coastguard Worker
134*d95af8dfSAndroid Build Coastguard Worker bo->gbm = gbm;
135*d95af8dfSAndroid Build Coastguard Worker bo->gbm_format = format;
136*d95af8dfSAndroid Build Coastguard Worker
137*d95af8dfSAndroid Build Coastguard Worker return bo;
138*d95af8dfSAndroid Build Coastguard Worker }
139*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_create(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,uint32_t usage)140*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height,
141*d95af8dfSAndroid Build Coastguard Worker uint32_t format, uint32_t usage)
142*d95af8dfSAndroid Build Coastguard Worker {
143*d95af8dfSAndroid Build Coastguard Worker struct gbm_bo *bo;
144*d95af8dfSAndroid Build Coastguard Worker
145*d95af8dfSAndroid Build Coastguard Worker if (!gbm_device_is_format_supported(gbm, format, usage))
146*d95af8dfSAndroid Build Coastguard Worker return NULL;
147*d95af8dfSAndroid Build Coastguard Worker
148*d95af8dfSAndroid Build Coastguard Worker bo = gbm_bo_new(gbm, format);
149*d95af8dfSAndroid Build Coastguard Worker
150*d95af8dfSAndroid Build Coastguard Worker if (!bo)
151*d95af8dfSAndroid Build Coastguard Worker return NULL;
152*d95af8dfSAndroid Build Coastguard Worker
153*d95af8dfSAndroid Build Coastguard Worker /*
154*d95af8dfSAndroid Build Coastguard Worker * HACK: See b/132939420. This is for HAL_PIXEL_FORMAT_YV12 buffers allocated by arcvm. None
155*d95af8dfSAndroid Build Coastguard Worker * of our platforms can display YV12, so we can treat as a SW buffer. Remove once this can
156*d95af8dfSAndroid Build Coastguard Worker * be intelligently resolved in the guest. Also see virgl_resolve_use_flags.
157*d95af8dfSAndroid Build Coastguard Worker */
158*d95af8dfSAndroid Build Coastguard Worker if (format == GBM_FORMAT_YVU420 && (usage & GBM_BO_USE_LINEAR))
159*d95af8dfSAndroid Build Coastguard Worker format = DRM_FORMAT_YVU420_ANDROID;
160*d95af8dfSAndroid Build Coastguard Worker
161*d95af8dfSAndroid Build Coastguard Worker bo->bo = drv_bo_create(gbm->drv, width, height, format, gbm_convert_usage(usage));
162*d95af8dfSAndroid Build Coastguard Worker
163*d95af8dfSAndroid Build Coastguard Worker if (!bo->bo) {
164*d95af8dfSAndroid Build Coastguard Worker free(bo);
165*d95af8dfSAndroid Build Coastguard Worker return NULL;
166*d95af8dfSAndroid Build Coastguard Worker }
167*d95af8dfSAndroid Build Coastguard Worker
168*d95af8dfSAndroid Build Coastguard Worker return bo;
169*d95af8dfSAndroid Build Coastguard Worker }
170*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_create_with_modifiers(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,uint32_t count)171*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers(struct gbm_device *gbm, uint32_t width,
172*d95af8dfSAndroid Build Coastguard Worker uint32_t height, uint32_t format,
173*d95af8dfSAndroid Build Coastguard Worker const uint64_t *modifiers, uint32_t count)
174*d95af8dfSAndroid Build Coastguard Worker {
175*d95af8dfSAndroid Build Coastguard Worker return gbm_bo_create_with_modifiers2(gbm, width, height, format, modifiers, count, 0);
176*d95af8dfSAndroid Build Coastguard Worker }
177*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_create_with_modifiers2(struct gbm_device * gbm,uint32_t width,uint32_t height,uint32_t format,const uint64_t * modifiers,const unsigned int count,uint32_t flags)178*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_bo *gbm_bo_create_with_modifiers2(struct gbm_device *gbm, uint32_t width,
179*d95af8dfSAndroid Build Coastguard Worker uint32_t height, uint32_t format,
180*d95af8dfSAndroid Build Coastguard Worker const uint64_t *modifiers,
181*d95af8dfSAndroid Build Coastguard Worker const unsigned int count, uint32_t flags)
182*d95af8dfSAndroid Build Coastguard Worker {
183*d95af8dfSAndroid Build Coastguard Worker struct gbm_bo *bo;
184*d95af8dfSAndroid Build Coastguard Worker
185*d95af8dfSAndroid Build Coastguard Worker if (flags != 0)
186*d95af8dfSAndroid Build Coastguard Worker return NULL;
187*d95af8dfSAndroid Build Coastguard Worker
188*d95af8dfSAndroid Build Coastguard Worker bo = gbm_bo_new(gbm, format);
189*d95af8dfSAndroid Build Coastguard Worker
190*d95af8dfSAndroid Build Coastguard Worker if (!bo)
191*d95af8dfSAndroid Build Coastguard Worker return NULL;
192*d95af8dfSAndroid Build Coastguard Worker
193*d95af8dfSAndroid Build Coastguard Worker bo->bo = drv_bo_create_with_modifiers(gbm->drv, width, height, format, modifiers, count);
194*d95af8dfSAndroid Build Coastguard Worker
195*d95af8dfSAndroid Build Coastguard Worker if (!bo->bo) {
196*d95af8dfSAndroid Build Coastguard Worker free(bo);
197*d95af8dfSAndroid Build Coastguard Worker return NULL;
198*d95af8dfSAndroid Build Coastguard Worker }
199*d95af8dfSAndroid Build Coastguard Worker
200*d95af8dfSAndroid Build Coastguard Worker return bo;
201*d95af8dfSAndroid Build Coastguard Worker }
202*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_destroy(struct gbm_bo * bo)203*d95af8dfSAndroid Build Coastguard Worker PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
204*d95af8dfSAndroid Build Coastguard Worker {
205*d95af8dfSAndroid Build Coastguard Worker if (bo->destroy_user_data) {
206*d95af8dfSAndroid Build Coastguard Worker bo->destroy_user_data(bo, bo->user_data);
207*d95af8dfSAndroid Build Coastguard Worker bo->destroy_user_data = NULL;
208*d95af8dfSAndroid Build Coastguard Worker bo->user_data = NULL;
209*d95af8dfSAndroid Build Coastguard Worker }
210*d95af8dfSAndroid Build Coastguard Worker
211*d95af8dfSAndroid Build Coastguard Worker drv_bo_destroy(bo->bo);
212*d95af8dfSAndroid Build Coastguard Worker free(bo);
213*d95af8dfSAndroid Build Coastguard Worker }
214*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_import(struct gbm_device * gbm,uint32_t type,void * buffer,uint32_t usage)215*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_bo *gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer,
216*d95af8dfSAndroid Build Coastguard Worker uint32_t usage)
217*d95af8dfSAndroid Build Coastguard Worker {
218*d95af8dfSAndroid Build Coastguard Worker struct gbm_bo *bo;
219*d95af8dfSAndroid Build Coastguard Worker struct drv_import_fd_data drv_data = { 0 };
220*d95af8dfSAndroid Build Coastguard Worker struct gbm_import_fd_data *fd_data = buffer;
221*d95af8dfSAndroid Build Coastguard Worker struct gbm_import_fd_modifier_data *fd_modifier_data = buffer;
222*d95af8dfSAndroid Build Coastguard Worker uint32_t gbm_format;
223*d95af8dfSAndroid Build Coastguard Worker size_t num_planes, i, num_fds;
224*d95af8dfSAndroid Build Coastguard Worker
225*d95af8dfSAndroid Build Coastguard Worker drv_data.use_flags = gbm_convert_usage(usage);
226*d95af8dfSAndroid Build Coastguard Worker switch (type) {
227*d95af8dfSAndroid Build Coastguard Worker case GBM_BO_IMPORT_FD:
228*d95af8dfSAndroid Build Coastguard Worker gbm_format = fd_data->format;
229*d95af8dfSAndroid Build Coastguard Worker drv_data.width = fd_data->width;
230*d95af8dfSAndroid Build Coastguard Worker drv_data.height = fd_data->height;
231*d95af8dfSAndroid Build Coastguard Worker drv_data.format = fd_data->format;
232*d95af8dfSAndroid Build Coastguard Worker drv_data.fds[0] = fd_data->fd;
233*d95af8dfSAndroid Build Coastguard Worker drv_data.strides[0] = fd_data->stride;
234*d95af8dfSAndroid Build Coastguard Worker drv_data.format_modifier = DRM_FORMAT_MOD_INVALID;
235*d95af8dfSAndroid Build Coastguard Worker
236*d95af8dfSAndroid Build Coastguard Worker break;
237*d95af8dfSAndroid Build Coastguard Worker case GBM_BO_IMPORT_FD_MODIFIER:
238*d95af8dfSAndroid Build Coastguard Worker gbm_format = fd_modifier_data->format;
239*d95af8dfSAndroid Build Coastguard Worker drv_data.width = fd_modifier_data->width;
240*d95af8dfSAndroid Build Coastguard Worker drv_data.height = fd_modifier_data->height;
241*d95af8dfSAndroid Build Coastguard Worker drv_data.format = fd_modifier_data->format;
242*d95af8dfSAndroid Build Coastguard Worker num_planes = drv_num_planes_from_modifier(gbm->drv, drv_data.format,
243*d95af8dfSAndroid Build Coastguard Worker fd_modifier_data->modifier);
244*d95af8dfSAndroid Build Coastguard Worker assert(num_planes);
245*d95af8dfSAndroid Build Coastguard Worker
246*d95af8dfSAndroid Build Coastguard Worker num_fds = fd_modifier_data->num_fds;
247*d95af8dfSAndroid Build Coastguard Worker if (!num_fds || num_fds > num_planes)
248*d95af8dfSAndroid Build Coastguard Worker return NULL;
249*d95af8dfSAndroid Build Coastguard Worker
250*d95af8dfSAndroid Build Coastguard Worker drv_data.format_modifier = fd_modifier_data->modifier;
251*d95af8dfSAndroid Build Coastguard Worker for (i = 0; i < num_planes; i++) {
252*d95af8dfSAndroid Build Coastguard Worker if (num_fds != num_planes)
253*d95af8dfSAndroid Build Coastguard Worker drv_data.fds[i] = fd_modifier_data->fds[0];
254*d95af8dfSAndroid Build Coastguard Worker else
255*d95af8dfSAndroid Build Coastguard Worker drv_data.fds[i] = fd_modifier_data->fds[i];
256*d95af8dfSAndroid Build Coastguard Worker drv_data.offsets[i] = fd_modifier_data->offsets[i];
257*d95af8dfSAndroid Build Coastguard Worker drv_data.strides[i] = fd_modifier_data->strides[i];
258*d95af8dfSAndroid Build Coastguard Worker }
259*d95af8dfSAndroid Build Coastguard Worker
260*d95af8dfSAndroid Build Coastguard Worker for (i = num_planes; i < GBM_MAX_PLANES; i++)
261*d95af8dfSAndroid Build Coastguard Worker drv_data.fds[i] = -1;
262*d95af8dfSAndroid Build Coastguard Worker
263*d95af8dfSAndroid Build Coastguard Worker break;
264*d95af8dfSAndroid Build Coastguard Worker default:
265*d95af8dfSAndroid Build Coastguard Worker return NULL;
266*d95af8dfSAndroid Build Coastguard Worker }
267*d95af8dfSAndroid Build Coastguard Worker
268*d95af8dfSAndroid Build Coastguard Worker if (!gbm_device_is_format_supported(gbm, gbm_format, usage))
269*d95af8dfSAndroid Build Coastguard Worker return NULL;
270*d95af8dfSAndroid Build Coastguard Worker
271*d95af8dfSAndroid Build Coastguard Worker bo = gbm_bo_new(gbm, gbm_format);
272*d95af8dfSAndroid Build Coastguard Worker
273*d95af8dfSAndroid Build Coastguard Worker if (!bo)
274*d95af8dfSAndroid Build Coastguard Worker return NULL;
275*d95af8dfSAndroid Build Coastguard Worker
276*d95af8dfSAndroid Build Coastguard Worker bo->bo = drv_bo_import(gbm->drv, &drv_data);
277*d95af8dfSAndroid Build Coastguard Worker
278*d95af8dfSAndroid Build Coastguard Worker if (!bo->bo) {
279*d95af8dfSAndroid Build Coastguard Worker free(bo);
280*d95af8dfSAndroid Build Coastguard Worker return NULL;
281*d95af8dfSAndroid Build Coastguard Worker }
282*d95af8dfSAndroid Build Coastguard Worker
283*d95af8dfSAndroid Build Coastguard Worker return bo;
284*d95af8dfSAndroid Build Coastguard Worker }
285*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_map(struct gbm_bo * bo,uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint32_t transfer_flags,uint32_t * stride,void ** map_data)286*d95af8dfSAndroid Build Coastguard Worker PUBLIC void *gbm_bo_map(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
287*d95af8dfSAndroid Build Coastguard Worker uint32_t transfer_flags, uint32_t *stride, void **map_data)
288*d95af8dfSAndroid Build Coastguard Worker {
289*d95af8dfSAndroid Build Coastguard Worker return gbm_bo_map2(bo, x, y, width, height, transfer_flags, stride, map_data, 0);
290*d95af8dfSAndroid Build Coastguard Worker }
291*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_map_info(struct gbm_bo * bo)292*d95af8dfSAndroid Build Coastguard Worker PUBLIC enum gbm_bo_map_cache_mode gbm_bo_get_map_info(struct gbm_bo *bo)
293*d95af8dfSAndroid Build Coastguard Worker {
294*d95af8dfSAndroid Build Coastguard Worker if (drv_bo_cached(bo->bo))
295*d95af8dfSAndroid Build Coastguard Worker return GBM_BO_MAP_CACHE_CACHED;
296*d95af8dfSAndroid Build Coastguard Worker return GBM_BO_MAP_CACHE_WC;
297*d95af8dfSAndroid Build Coastguard Worker }
298*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_unmap(struct gbm_bo * bo,void * map_data)299*d95af8dfSAndroid Build Coastguard Worker PUBLIC void gbm_bo_unmap(struct gbm_bo *bo, void *map_data)
300*d95af8dfSAndroid Build Coastguard Worker {
301*d95af8dfSAndroid Build Coastguard Worker assert(bo);
302*d95af8dfSAndroid Build Coastguard Worker drv_bo_flush_or_unmap(bo->bo, map_data);
303*d95af8dfSAndroid Build Coastguard Worker }
304*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_width(struct gbm_bo * bo)305*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_width(struct gbm_bo *bo)
306*d95af8dfSAndroid Build Coastguard Worker {
307*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_width(bo->bo);
308*d95af8dfSAndroid Build Coastguard Worker }
309*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_height(struct gbm_bo * bo)310*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_height(struct gbm_bo *bo)
311*d95af8dfSAndroid Build Coastguard Worker {
312*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_height(bo->bo);
313*d95af8dfSAndroid Build Coastguard Worker }
314*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_stride(struct gbm_bo * bo)315*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_stride(struct gbm_bo *bo)
316*d95af8dfSAndroid Build Coastguard Worker {
317*d95af8dfSAndroid Build Coastguard Worker return gbm_bo_get_stride_for_plane(bo, 0);
318*d95af8dfSAndroid Build Coastguard Worker }
319*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_format(struct gbm_bo * bo)320*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_format(struct gbm_bo *bo)
321*d95af8dfSAndroid Build Coastguard Worker {
322*d95af8dfSAndroid Build Coastguard Worker return bo->gbm_format;
323*d95af8dfSAndroid Build Coastguard Worker }
324*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_bpp(struct gbm_bo * bo)325*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_bpp(struct gbm_bo *bo)
326*d95af8dfSAndroid Build Coastguard Worker {
327*d95af8dfSAndroid Build Coastguard Worker return drv_bytes_per_pixel_from_format(drv_bo_get_format(bo->bo), 0);
328*d95af8dfSAndroid Build Coastguard Worker }
329*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_modifier(struct gbm_bo * bo)330*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint64_t gbm_bo_get_modifier(struct gbm_bo *bo)
331*d95af8dfSAndroid Build Coastguard Worker {
332*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_format_modifier(bo->bo);
333*d95af8dfSAndroid Build Coastguard Worker }
334*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_device(struct gbm_bo * bo)335*d95af8dfSAndroid Build Coastguard Worker PUBLIC struct gbm_device *gbm_bo_get_device(struct gbm_bo *bo)
336*d95af8dfSAndroid Build Coastguard Worker {
337*d95af8dfSAndroid Build Coastguard Worker return bo->gbm;
338*d95af8dfSAndroid Build Coastguard Worker }
339*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_handle(struct gbm_bo * bo)340*d95af8dfSAndroid Build Coastguard Worker PUBLIC union gbm_bo_handle gbm_bo_get_handle(struct gbm_bo *bo)
341*d95af8dfSAndroid Build Coastguard Worker {
342*d95af8dfSAndroid Build Coastguard Worker return gbm_bo_get_handle_for_plane(bo, 0);
343*d95af8dfSAndroid Build Coastguard Worker }
344*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_fd(struct gbm_bo * bo)345*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_bo_get_fd(struct gbm_bo *bo)
346*d95af8dfSAndroid Build Coastguard Worker {
347*d95af8dfSAndroid Build Coastguard Worker return gbm_bo_get_plane_fd(bo, 0);
348*d95af8dfSAndroid Build Coastguard Worker }
349*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_plane_count(struct gbm_bo * bo)350*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_bo_get_plane_count(struct gbm_bo *bo)
351*d95af8dfSAndroid Build Coastguard Worker {
352*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_num_planes(bo->bo);
353*d95af8dfSAndroid Build Coastguard Worker }
354*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_handle_for_plane(struct gbm_bo * bo,int plane)355*d95af8dfSAndroid Build Coastguard Worker PUBLIC union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane)
356*d95af8dfSAndroid Build Coastguard Worker {
357*d95af8dfSAndroid Build Coastguard Worker return (union gbm_bo_handle)drv_bo_get_plane_handle(bo->bo, (size_t)plane).u64;
358*d95af8dfSAndroid Build Coastguard Worker }
359*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_fd_for_plane(struct gbm_bo * bo,int plane)360*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane)
361*d95af8dfSAndroid Build Coastguard Worker {
362*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_plane_fd(bo->bo, plane);
363*d95af8dfSAndroid Build Coastguard Worker }
364*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_offset(struct gbm_bo * bo,int plane)365*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_offset(struct gbm_bo *bo, int plane)
366*d95af8dfSAndroid Build Coastguard Worker {
367*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_plane_offset(bo->bo, (size_t)plane);
368*d95af8dfSAndroid Build Coastguard Worker }
369*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_stride_for_plane(struct gbm_bo * bo,int plane)370*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane)
371*d95af8dfSAndroid Build Coastguard Worker {
372*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_plane_stride(bo->bo, (size_t)plane);
373*d95af8dfSAndroid Build Coastguard Worker }
374*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_set_user_data(struct gbm_bo * bo,void * data,void (* destroy_user_data)(struct gbm_bo *,void *))375*d95af8dfSAndroid Build Coastguard Worker PUBLIC void gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
376*d95af8dfSAndroid Build Coastguard Worker void (*destroy_user_data)(struct gbm_bo *, void *))
377*d95af8dfSAndroid Build Coastguard Worker {
378*d95af8dfSAndroid Build Coastguard Worker bo->user_data = data;
379*d95af8dfSAndroid Build Coastguard Worker bo->destroy_user_data = destroy_user_data;
380*d95af8dfSAndroid Build Coastguard Worker }
381*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_user_data(struct gbm_bo * bo)382*d95af8dfSAndroid Build Coastguard Worker PUBLIC void *gbm_bo_get_user_data(struct gbm_bo *bo)
383*d95af8dfSAndroid Build Coastguard Worker {
384*d95af8dfSAndroid Build Coastguard Worker return bo->user_data;
385*d95af8dfSAndroid Build Coastguard Worker }
386*d95af8dfSAndroid Build Coastguard Worker
387*d95af8dfSAndroid Build Coastguard Worker /* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_*
388*d95af8dfSAndroid Build Coastguard Worker * formats of the same name. We want to accept them whenever someone
389*d95af8dfSAndroid Build Coastguard Worker * has a GBM format, but never return them to the user.
390*d95af8dfSAndroid Build Coastguard Worker */
gbm_format_canonicalize(uint32_t gbm_format)391*d95af8dfSAndroid Build Coastguard Worker static uint32_t gbm_format_canonicalize(uint32_t gbm_format)
392*d95af8dfSAndroid Build Coastguard Worker {
393*d95af8dfSAndroid Build Coastguard Worker switch (gbm_format) {
394*d95af8dfSAndroid Build Coastguard Worker case GBM_BO_FORMAT_XRGB8888:
395*d95af8dfSAndroid Build Coastguard Worker return GBM_FORMAT_XRGB8888;
396*d95af8dfSAndroid Build Coastguard Worker case GBM_BO_FORMAT_ARGB8888:
397*d95af8dfSAndroid Build Coastguard Worker return GBM_FORMAT_ARGB8888;
398*d95af8dfSAndroid Build Coastguard Worker default:
399*d95af8dfSAndroid Build Coastguard Worker return gbm_format;
400*d95af8dfSAndroid Build Coastguard Worker }
401*d95af8dfSAndroid Build Coastguard Worker }
402*d95af8dfSAndroid Build Coastguard Worker
403*d95af8dfSAndroid Build Coastguard Worker /**
404*d95af8dfSAndroid Build Coastguard Worker * Returns a string representing the fourcc format name.
405*d95af8dfSAndroid Build Coastguard Worker */
gbm_format_get_name(uint32_t gbm_format,struct gbm_format_name_desc * desc)406*d95af8dfSAndroid Build Coastguard Worker PUBLIC char *gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)
407*d95af8dfSAndroid Build Coastguard Worker {
408*d95af8dfSAndroid Build Coastguard Worker gbm_format = gbm_format_canonicalize(gbm_format);
409*d95af8dfSAndroid Build Coastguard Worker
410*d95af8dfSAndroid Build Coastguard Worker desc->name[0] = gbm_format;
411*d95af8dfSAndroid Build Coastguard Worker desc->name[1] = gbm_format >> 8;
412*d95af8dfSAndroid Build Coastguard Worker desc->name[2] = gbm_format >> 16;
413*d95af8dfSAndroid Build Coastguard Worker desc->name[3] = gbm_format >> 24;
414*d95af8dfSAndroid Build Coastguard Worker desc->name[4] = 0;
415*d95af8dfSAndroid Build Coastguard Worker
416*d95af8dfSAndroid Build Coastguard Worker return desc->name;
417*d95af8dfSAndroid Build Coastguard Worker }
418*d95af8dfSAndroid Build Coastguard Worker
419*d95af8dfSAndroid Build Coastguard Worker /*
420*d95af8dfSAndroid Build Coastguard Worker * The following functions are not deprecated, but not in the Mesa the gbm
421*d95af8dfSAndroid Build Coastguard Worker * header. The main difference is minigbm allows for the possibility of
422*d95af8dfSAndroid Build Coastguard Worker * disjoint YUV images, while Mesa GBM does not.
423*d95af8dfSAndroid Build Coastguard Worker */
gbm_bo_get_plane_size(struct gbm_bo * bo,size_t plane)424*d95af8dfSAndroid Build Coastguard Worker PUBLIC uint32_t gbm_bo_get_plane_size(struct gbm_bo *bo, size_t plane)
425*d95af8dfSAndroid Build Coastguard Worker {
426*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_plane_size(bo->bo, plane);
427*d95af8dfSAndroid Build Coastguard Worker }
428*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_get_plane_fd(struct gbm_bo * bo,size_t plane)429*d95af8dfSAndroid Build Coastguard Worker PUBLIC int gbm_bo_get_plane_fd(struct gbm_bo *bo, size_t plane)
430*d95af8dfSAndroid Build Coastguard Worker {
431*d95af8dfSAndroid Build Coastguard Worker return drv_bo_get_plane_fd(bo->bo, plane);
432*d95af8dfSAndroid Build Coastguard Worker }
433*d95af8dfSAndroid Build Coastguard Worker
gbm_bo_map2(struct gbm_bo * bo,uint32_t x,uint32_t y,uint32_t width,uint32_t height,uint32_t transfer_flags,uint32_t * stride,void ** map_data,int plane)434*d95af8dfSAndroid Build Coastguard Worker PUBLIC void *gbm_bo_map2(struct gbm_bo *bo, uint32_t x, uint32_t y, uint32_t width, uint32_t height,
435*d95af8dfSAndroid Build Coastguard Worker uint32_t transfer_flags, uint32_t *stride, void **map_data, int plane)
436*d95af8dfSAndroid Build Coastguard Worker {
437*d95af8dfSAndroid Build Coastguard Worker void *addr;
438*d95af8dfSAndroid Build Coastguard Worker off_t offset;
439*d95af8dfSAndroid Build Coastguard Worker uint32_t map_flags;
440*d95af8dfSAndroid Build Coastguard Worker plane = (size_t)plane;
441*d95af8dfSAndroid Build Coastguard Worker struct rectangle rect = { .x = x, .y = y, .width = width, .height = height };
442*d95af8dfSAndroid Build Coastguard Worker if (!bo || width == 0 || height == 0 || !stride || !map_data)
443*d95af8dfSAndroid Build Coastguard Worker return NULL;
444*d95af8dfSAndroid Build Coastguard Worker
445*d95af8dfSAndroid Build Coastguard Worker map_flags = (transfer_flags & GBM_BO_TRANSFER_READ) ? BO_MAP_READ : BO_MAP_NONE;
446*d95af8dfSAndroid Build Coastguard Worker map_flags |= (transfer_flags & GBM_BO_TRANSFER_WRITE) ? BO_MAP_WRITE : BO_MAP_NONE;
447*d95af8dfSAndroid Build Coastguard Worker
448*d95af8dfSAndroid Build Coastguard Worker addr = drv_bo_map(bo->bo, &rect, map_flags, (struct mapping **)map_data, plane);
449*d95af8dfSAndroid Build Coastguard Worker if (addr == MAP_FAILED)
450*d95af8dfSAndroid Build Coastguard Worker return MAP_FAILED;
451*d95af8dfSAndroid Build Coastguard Worker
452*d95af8dfSAndroid Build Coastguard Worker *stride = ((struct mapping *)*map_data)->vma->map_strides[plane];
453*d95af8dfSAndroid Build Coastguard Worker
454*d95af8dfSAndroid Build Coastguard Worker offset = *stride * rect.y;
455*d95af8dfSAndroid Build Coastguard Worker offset += rect.x * drv_bytes_per_pixel_from_format(bo->gbm_format, plane);
456*d95af8dfSAndroid Build Coastguard Worker return (void *)((uint8_t *)addr + offset);
457*d95af8dfSAndroid Build Coastguard Worker }
458