blob: b96faf0eaf781ea300d818f87c173e5c5c953413 [file] [log] [blame]
Stéphane Marchesin25a26062014-09-12 16:18:59 -07001/*
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 <stdlib.h>
8#include <stdint.h>
9#include <string.h>
Dominik Behrf7b33d72014-11-11 07:17:11 -080010#include <fcntl.h>
Stéphane Marchesin25a26062014-09-12 16:18:59 -070011#include <xf86drm.h>
12
13#include "gbm_priv.h"
14#include "util.h"
15
16/*
17gbm_buffer_base.cc: gbm_bo_get_width(bo),
18gbm_buffer_base.cc: gbm_bo_get_height(bo),
19gbm_buffer_base.cc: gbm_bo_get_stride(bo),
20gbm_buffer_base.cc: gbm_bo_get_handle(bo).u32,
21gbm_buffer_base.cc: return gbm_bo_get_handle(bo_).u32;
22gbm_buffer_base.cc: return gfx::Size(gbm_bo_get_width(bo_), gbm_bo_get_height(bo_));
23gbm_buffer.cc: gbm_bo_destroy(bo());
24gbm_buffer.cc: gbm_bo* bo = gbm_bo_create(device,
25gbm_surface.cc: gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy);
26gbm_surface.cc: static_cast<GbmSurfaceBuffer*>(gbm_bo_get_user_data(buffer)));
27gbm_surface.cc: gbm_surface_release_buffer(native_surface_, current_buffer_);
28gbm_surface.cc: gbm_surface_destroy(native_surface_);
29gbm_surface.cc: native_surface_ = gbm_surface_create(
30gbm_surface.cc: gbm_bo* pending_buffer = gbm_surface_lock_front_buffer(native_surface_);
31gbm_surface.cc: gbm_surface_release_buffer(native_surface_, current_buffer_);
32ozone_platform_gbm.cc: device_(gbm_create_device(dri_->get_fd())) {}
33ozone_platform_gbm.cc: gbm_device_destroy(device_);
34*/
35
36extern struct gbm_driver gbm_driver_cirrus;
37#ifdef GBM_EXYNOS
38extern struct gbm_driver gbm_driver_exynos;
39#endif
40extern struct gbm_driver gbm_driver_gma500;
41#ifdef GBM_I915
42extern struct gbm_driver gbm_driver_i915;
43#endif
JB Tsai0c16a0f2015-03-19 14:30:31 +080044#ifdef GBM_MEDIATEK
45extern struct gbm_driver gbm_driver_mediatek;
46#endif
Stéphane Marchesin25a26062014-09-12 16:18:59 -070047#ifdef GBM_ROCKCHIP
48extern struct gbm_driver gbm_driver_rockchip;
49#endif
50#ifdef GBM_TEGRA
51extern struct gbm_driver gbm_driver_tegra;
52#endif
53extern struct gbm_driver gbm_driver_udl;
54
55static struct gbm_driver *gbm_get_driver(int fd)
56{
57 drmVersionPtr drm_version;
58 unsigned int i;
59
60 drm_version = drmGetVersion(fd);
61
62 if (!drm_version)
63 return NULL;
64
65 struct gbm_driver *driver_list[] = {
66 &gbm_driver_cirrus,
67#ifdef GBM_EXYNOS
68 &gbm_driver_exynos,
69#endif
70 &gbm_driver_gma500,
71#ifdef GBM_I915
72 &gbm_driver_i915,
73#endif
JB Tsai0c16a0f2015-03-19 14:30:31 +080074#ifdef GBM_MEDIATEK
75 &gbm_driver_mediatek,
76#endif
Stéphane Marchesin25a26062014-09-12 16:18:59 -070077#ifdef GBM_ROCKCHIP
78 &gbm_driver_rockchip,
79#endif
80#ifdef GBM_TEGRA
81 &gbm_driver_tegra,
82#endif
83 &gbm_driver_udl,
84 };
85
86 for(i = 0; i < ARRAY_SIZE(driver_list); i++)
87 if (!strcmp(drm_version->name, driver_list[i]->name))
88 {
89 drmFreeVersion(drm_version);
90 return driver_list[i];
91 }
92
93 drmFreeVersion(drm_version);
94 return NULL;
95}
96
97PUBLIC int
98gbm_device_get_fd(struct gbm_device *gbm)
99{
100 return gbm->fd;
101}
102
103PUBLIC const char *
104gbm_device_get_backend_name(struct gbm_device *gbm)
105{
106 return gbm->driver->name;
107}
108
109PUBLIC int
110gbm_device_is_format_supported(struct gbm_device *gbm,
111 uint32_t format, uint32_t usage)
112{
113 unsigned i;
114
115 if (format == GBM_BO_FORMAT_XRGB8888)
116 format = GBM_FORMAT_XRGB8888;
117 if (format == GBM_BO_FORMAT_ARGB8888)
118 format = GBM_FORMAT_ARGB8888;
119
120 if (usage & GBM_BO_USE_CURSOR &&
121 usage & GBM_BO_USE_RENDERING)
122 return 0;
123
124 for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++)
125 {
126 if (!gbm->driver->format_list[i].format)
127 break;
128
129 if (gbm->driver->format_list[i].format == format &&
130 (gbm->driver->format_list[i].usage & usage) == usage)
131 return 1;
132 }
133
134 return 0;
135}
136
137PUBLIC struct gbm_device *gbm_create_device(int fd)
138{
139 struct gbm_device *gbm;
140 int ret;
141
142 gbm = (struct gbm_device*) malloc(sizeof(*gbm));
143 if (!gbm)
144 return NULL;
145
146 gbm->fd = fd;
147
148 gbm->driver = gbm_get_driver(fd);
149 if (!gbm->driver) {
150 free(gbm);
151 return NULL;
152 }
153
154 if (gbm->driver->init) {
155 ret = gbm->driver->init(gbm);
156 if (ret) {
157 free(gbm);
158 return NULL;
159 }
160 }
161
162 return gbm;
163}
164
165PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
166{
167 if (gbm->driver->close)
168 gbm->driver->close(gbm);
169 free(gbm);
170}
171
172PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
173{
174 struct gbm_surface *surface = (struct gbm_surface*) malloc(sizeof(*surface));
175 if (!surface)
176 return NULL;
177
178 return surface;
179}
180
181PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
182{
183 free(surface);
184}
185
186PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
187{
188 return NULL;
189}
190
191PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo)
192{
193}
194
195PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
196{
197 struct gbm_bo *bo;
198 int ret;
199
200 bo = (struct gbm_bo*) malloc(sizeof(*bo));
201 if (!bo)
202 return NULL;
203
204 bo->gbm = gbm;
205 bo->width = width;
206 bo->height = height;
207 bo->stride = 0;
208 bo->format = format;
209 bo->handle.u32 = 0;
210 bo->destroy_user_data = NULL;
211 bo->user_data = NULL;
212
213 ret = gbm->driver->bo_create(bo, width, height, format, flags);
214 if (ret) {
215 free(bo);
216 return NULL;
217 }
218
219 return bo;
220}
221
222PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
223{
224 if (bo->destroy_user_data) {
225 bo->destroy_user_data(bo, bo->user_data);
226 bo->destroy_user_data = NULL;
227 bo->user_data = NULL;
228 }
229
230 bo->gbm->driver->bo_destroy(bo);
231 free(bo);
232}
233
234PUBLIC uint32_t
235gbm_bo_get_width(struct gbm_bo *bo)
236{
237 return bo->width;
238}
239
240PUBLIC uint32_t
241gbm_bo_get_height(struct gbm_bo *bo)
242{
243 return bo->height;
244}
245
246PUBLIC uint32_t
247gbm_bo_get_stride(struct gbm_bo *bo)
248{
249 return bo->stride;
250}
251
252PUBLIC uint32_t
Lauri Peltonen7842d8f2014-12-17 23:01:37 -0800253gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
254{
255 return bo->tiling ? bo->tiling : bo->stride;
256}
257
258PUBLIC uint32_t
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700259gbm_bo_get_format(struct gbm_bo *bo)
260{
261 return bo->format;
262}
263
264PUBLIC struct gbm_device *
265gbm_bo_get_device(struct gbm_bo *bo)
266{
267 return bo->gbm;
268}
269
270PUBLIC union gbm_bo_handle
271gbm_bo_get_handle(struct gbm_bo *bo)
272{
273 return bo->handle;
274}
275
276PUBLIC int
277gbm_bo_get_fd(struct gbm_bo *bo)
278{
Stéphane Marchesin5bb6adc2014-11-05 20:21:25 -0800279 int fd;
280
Dominik Behrf7b33d72014-11-11 07:17:11 -0800281 if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
282 gbm_bo_get_handle(bo).u32,
Stéphane Marchesin5bb6adc2014-11-05 20:21:25 -0800283 DRM_CLOEXEC,
284 &fd))
Dominik Behrf7b33d72014-11-11 07:17:11 -0800285 return -1;
Zach Reiznerd224eaa2015-01-09 11:25:02 -0800286 else
287 return fd;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700288}
289
290PUBLIC void
291gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
292 void (*destroy_user_data)(struct gbm_bo *, void *))
293{
294 bo->user_data = data;
295 bo->destroy_user_data = destroy_user_data;
296}
297
298PUBLIC void *
299gbm_bo_get_user_data(struct gbm_bo *bo)
300{
301 return bo->user_data;
302}