blob: b9f08f247ac7b8c782f7dd085b7cb7f2269ecea2 [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
44#ifdef GBM_ROCKCHIP
45extern struct gbm_driver gbm_driver_rockchip;
46#endif
47#ifdef GBM_TEGRA
48extern struct gbm_driver gbm_driver_tegra;
49#endif
50extern struct gbm_driver gbm_driver_udl;
51
52static struct gbm_driver *gbm_get_driver(int fd)
53{
54 drmVersionPtr drm_version;
55 unsigned int i;
56
57 drm_version = drmGetVersion(fd);
58
59 if (!drm_version)
60 return NULL;
61
62 struct gbm_driver *driver_list[] = {
63 &gbm_driver_cirrus,
64#ifdef GBM_EXYNOS
65 &gbm_driver_exynos,
66#endif
67 &gbm_driver_gma500,
68#ifdef GBM_I915
69 &gbm_driver_i915,
70#endif
71#ifdef GBM_ROCKCHIP
72 &gbm_driver_rockchip,
73#endif
74#ifdef GBM_TEGRA
75 &gbm_driver_tegra,
76#endif
77 &gbm_driver_udl,
78 };
79
80 for(i = 0; i < ARRAY_SIZE(driver_list); i++)
81 if (!strcmp(drm_version->name, driver_list[i]->name))
82 {
83 drmFreeVersion(drm_version);
84 return driver_list[i];
85 }
86
87 drmFreeVersion(drm_version);
88 return NULL;
89}
90
91PUBLIC int
92gbm_device_get_fd(struct gbm_device *gbm)
93{
94 return gbm->fd;
95}
96
97PUBLIC const char *
98gbm_device_get_backend_name(struct gbm_device *gbm)
99{
100 return gbm->driver->name;
101}
102
103PUBLIC int
104gbm_device_is_format_supported(struct gbm_device *gbm,
105 uint32_t format, uint32_t usage)
106{
107 unsigned i;
108
109 if (format == GBM_BO_FORMAT_XRGB8888)
110 format = GBM_FORMAT_XRGB8888;
111 if (format == GBM_BO_FORMAT_ARGB8888)
112 format = GBM_FORMAT_ARGB8888;
113
114 if (usage & GBM_BO_USE_CURSOR &&
115 usage & GBM_BO_USE_RENDERING)
116 return 0;
117
118 for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++)
119 {
120 if (!gbm->driver->format_list[i].format)
121 break;
122
123 if (gbm->driver->format_list[i].format == format &&
124 (gbm->driver->format_list[i].usage & usage) == usage)
125 return 1;
126 }
127
128 return 0;
129}
130
131PUBLIC struct gbm_device *gbm_create_device(int fd)
132{
133 struct gbm_device *gbm;
134 int ret;
135
136 gbm = (struct gbm_device*) malloc(sizeof(*gbm));
137 if (!gbm)
138 return NULL;
139
140 gbm->fd = fd;
141
142 gbm->driver = gbm_get_driver(fd);
143 if (!gbm->driver) {
144 free(gbm);
145 return NULL;
146 }
147
148 if (gbm->driver->init) {
149 ret = gbm->driver->init(gbm);
150 if (ret) {
151 free(gbm);
152 return NULL;
153 }
154 }
155
156 return gbm;
157}
158
159PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
160{
161 if (gbm->driver->close)
162 gbm->driver->close(gbm);
163 free(gbm);
164}
165
166PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
167{
168 struct gbm_surface *surface = (struct gbm_surface*) malloc(sizeof(*surface));
169 if (!surface)
170 return NULL;
171
172 return surface;
173}
174
175PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
176{
177 free(surface);
178}
179
180PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
181{
182 return NULL;
183}
184
185PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo)
186{
187}
188
189PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags)
190{
191 struct gbm_bo *bo;
192 int ret;
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 = 0;
202 bo->format = format;
203 bo->handle.u32 = 0;
204 bo->destroy_user_data = NULL;
205 bo->user_data = NULL;
206
207 ret = gbm->driver->bo_create(bo, width, height, format, flags);
208 if (ret) {
209 free(bo);
210 return NULL;
211 }
212
213 return bo;
214}
215
216PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
217{
218 if (bo->destroy_user_data) {
219 bo->destroy_user_data(bo, bo->user_data);
220 bo->destroy_user_data = NULL;
221 bo->user_data = NULL;
222 }
223
224 bo->gbm->driver->bo_destroy(bo);
225 free(bo);
226}
227
228PUBLIC uint32_t
229gbm_bo_get_width(struct gbm_bo *bo)
230{
231 return bo->width;
232}
233
234PUBLIC uint32_t
235gbm_bo_get_height(struct gbm_bo *bo)
236{
237 return bo->height;
238}
239
240PUBLIC uint32_t
241gbm_bo_get_stride(struct gbm_bo *bo)
242{
243 return bo->stride;
244}
245
246PUBLIC uint32_t
Lauri Peltonen7842d8f2014-12-17 23:01:37 -0800247gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
248{
249 return bo->tiling ? bo->tiling : bo->stride;
250}
251
252PUBLIC uint32_t
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700253gbm_bo_get_format(struct gbm_bo *bo)
254{
255 return bo->format;
256}
257
258PUBLIC struct gbm_device *
259gbm_bo_get_device(struct gbm_bo *bo)
260{
261 return bo->gbm;
262}
263
264PUBLIC union gbm_bo_handle
265gbm_bo_get_handle(struct gbm_bo *bo)
266{
267 return bo->handle;
268}
269
270PUBLIC int
271gbm_bo_get_fd(struct gbm_bo *bo)
272{
Stéphane Marchesin5bb6adc2014-11-05 20:21:25 -0800273 int fd;
274
Dominik Behrf7b33d72014-11-11 07:17:11 -0800275 if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
276 gbm_bo_get_handle(bo).u32,
Stéphane Marchesin5bb6adc2014-11-05 20:21:25 -0800277 DRM_CLOEXEC,
278 &fd))
Dominik Behrf7b33d72014-11-11 07:17:11 -0800279 return -1;
Zach Reiznerd224eaa2015-01-09 11:25:02 -0800280 else
281 return fd;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700282}
283
284PUBLIC void
285gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
286 void (*destroy_user_data)(struct gbm_bo *, void *))
287{
288 bo->user_data = data;
289 bo->destroy_user_data = destroy_user_data;
290}
291
292PUBLIC void *
293gbm_bo_get_user_data(struct gbm_bo *bo)
294{
295 return bo->user_data;
296}