blob: 861c1743456160a5b8eacbfda86d586e07f66ce7 [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
Stéphane Marchesin25a26062014-09-12 16:18:59 -070016extern struct gbm_driver gbm_driver_cirrus;
17#ifdef GBM_EXYNOS
18extern struct gbm_driver gbm_driver_exynos;
19#endif
20extern struct gbm_driver gbm_driver_gma500;
21#ifdef GBM_I915
22extern struct gbm_driver gbm_driver_i915;
23#endif
JB Tsai0c16a0f2015-03-19 14:30:31 +080024#ifdef GBM_MEDIATEK
25extern struct gbm_driver gbm_driver_mediatek;
26#endif
Stéphane Marchesin25a26062014-09-12 16:18:59 -070027#ifdef GBM_ROCKCHIP
28extern struct gbm_driver gbm_driver_rockchip;
29#endif
30#ifdef GBM_TEGRA
31extern struct gbm_driver gbm_driver_tegra;
32#endif
33extern struct gbm_driver gbm_driver_udl;
34
35static struct gbm_driver *gbm_get_driver(int fd)
36{
37 drmVersionPtr drm_version;
38 unsigned int i;
39
40 drm_version = drmGetVersion(fd);
41
42 if (!drm_version)
43 return NULL;
44
45 struct gbm_driver *driver_list[] = {
46 &gbm_driver_cirrus,
47#ifdef GBM_EXYNOS
48 &gbm_driver_exynos,
49#endif
50 &gbm_driver_gma500,
51#ifdef GBM_I915
52 &gbm_driver_i915,
53#endif
JB Tsai0c16a0f2015-03-19 14:30:31 +080054#ifdef GBM_MEDIATEK
55 &gbm_driver_mediatek,
56#endif
Stéphane Marchesin25a26062014-09-12 16:18:59 -070057#ifdef GBM_ROCKCHIP
58 &gbm_driver_rockchip,
59#endif
60#ifdef GBM_TEGRA
61 &gbm_driver_tegra,
62#endif
63 &gbm_driver_udl,
64 };
65
66 for(i = 0; i < ARRAY_SIZE(driver_list); i++)
67 if (!strcmp(drm_version->name, driver_list[i]->name))
68 {
69 drmFreeVersion(drm_version);
70 return driver_list[i];
71 }
72
73 drmFreeVersion(drm_version);
74 return NULL;
75}
76
77PUBLIC int
78gbm_device_get_fd(struct gbm_device *gbm)
79{
80 return gbm->fd;
81}
82
83PUBLIC const char *
84gbm_device_get_backend_name(struct gbm_device *gbm)
85{
86 return gbm->driver->name;
87}
88
89PUBLIC int
90gbm_device_is_format_supported(struct gbm_device *gbm,
Stéphane Marchesinec88e892015-11-03 16:14:59 -080091 uint32_t format, uint32_t usage)
Stéphane Marchesin25a26062014-09-12 16:18:59 -070092{
93 unsigned i;
94
95 if (format == GBM_BO_FORMAT_XRGB8888)
96 format = GBM_FORMAT_XRGB8888;
97 if (format == GBM_BO_FORMAT_ARGB8888)
98 format = GBM_FORMAT_ARGB8888;
99
100 if (usage & GBM_BO_USE_CURSOR &&
101 usage & GBM_BO_USE_RENDERING)
102 return 0;
103
104 for(i = 0 ; i < ARRAY_SIZE(gbm->driver->format_list); i++)
105 {
106 if (!gbm->driver->format_list[i].format)
107 break;
108
109 if (gbm->driver->format_list[i].format == format &&
110 (gbm->driver->format_list[i].usage & usage) == usage)
111 return 1;
112 }
113
114 return 0;
115}
116
117PUBLIC struct gbm_device *gbm_create_device(int fd)
118{
119 struct gbm_device *gbm;
120 int ret;
121
122 gbm = (struct gbm_device*) malloc(sizeof(*gbm));
123 if (!gbm)
124 return NULL;
125
126 gbm->fd = fd;
127
128 gbm->driver = gbm_get_driver(fd);
129 if (!gbm->driver) {
130 free(gbm);
131 return NULL;
132 }
133
134 if (gbm->driver->init) {
135 ret = gbm->driver->init(gbm);
136 if (ret) {
137 free(gbm);
138 return NULL;
139 }
140 }
141
142 return gbm;
143}
144
145PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
146{
147 if (gbm->driver->close)
148 gbm->driver->close(gbm);
149 free(gbm);
150}
151
Stéphane Marchesinec88e892015-11-03 16:14:59 -0800152PUBLIC struct gbm_surface *gbm_surface_create(struct gbm_device *gbm,
153 uint32_t width, uint32_t height,
154 uint32_t format, uint32_t flags)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700155{
Stéphane Marchesinec88e892015-11-03 16:14:59 -0800156 struct gbm_surface *surface =
157 (struct gbm_surface*) malloc(sizeof(*surface));
158
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700159 if (!surface)
160 return NULL;
161
162 return surface;
163}
164
165PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
166{
167 free(surface);
168}
169
170PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
171{
172 return NULL;
173}
174
Stéphane Marchesinec88e892015-11-03 16:14:59 -0800175PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface,
176 struct gbm_bo *bo)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700177{
178}
179
Stéphane Marchesinec88e892015-11-03 16:14:59 -0800180PUBLIC struct gbm_bo *gbm_bo_create(struct gbm_device *gbm, uint32_t width,
181 uint32_t height, uint32_t format,
182 uint32_t flags)
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700183{
184 struct gbm_bo *bo;
185 int ret;
186
187 bo = (struct gbm_bo*) malloc(sizeof(*bo));
188 if (!bo)
189 return NULL;
190
191 bo->gbm = gbm;
192 bo->width = width;
193 bo->height = height;
194 bo->stride = 0;
195 bo->format = format;
196 bo->handle.u32 = 0;
197 bo->destroy_user_data = NULL;
198 bo->user_data = NULL;
199
200 ret = gbm->driver->bo_create(bo, width, height, format, flags);
201 if (ret) {
202 free(bo);
203 return NULL;
204 }
205
206 return bo;
207}
208
209PUBLIC void gbm_bo_destroy(struct gbm_bo *bo)
210{
211 if (bo->destroy_user_data) {
212 bo->destroy_user_data(bo, bo->user_data);
213 bo->destroy_user_data = NULL;
214 bo->user_data = NULL;
215 }
216
217 bo->gbm->driver->bo_destroy(bo);
218 free(bo);
219}
220
221PUBLIC uint32_t
222gbm_bo_get_width(struct gbm_bo *bo)
223{
224 return bo->width;
225}
226
227PUBLIC uint32_t
228gbm_bo_get_height(struct gbm_bo *bo)
229{
230 return bo->height;
231}
232
233PUBLIC uint32_t
234gbm_bo_get_stride(struct gbm_bo *bo)
235{
236 return bo->stride;
237}
238
239PUBLIC uint32_t
Lauri Peltonen7842d8f2014-12-17 23:01:37 -0800240gbm_bo_get_stride_or_tiling(struct gbm_bo *bo)
241{
242 return bo->tiling ? bo->tiling : bo->stride;
243}
244
245PUBLIC uint32_t
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700246gbm_bo_get_format(struct gbm_bo *bo)
247{
248 return bo->format;
249}
250
251PUBLIC struct gbm_device *
252gbm_bo_get_device(struct gbm_bo *bo)
253{
254 return bo->gbm;
255}
256
257PUBLIC union gbm_bo_handle
258gbm_bo_get_handle(struct gbm_bo *bo)
259{
260 return bo->handle;
261}
262
263PUBLIC int
264gbm_bo_get_fd(struct gbm_bo *bo)
265{
Stéphane Marchesin5bb6adc2014-11-05 20:21:25 -0800266 int fd;
267
Dominik Behrf7b33d72014-11-11 07:17:11 -0800268 if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
269 gbm_bo_get_handle(bo).u32,
Stéphane Marchesin5bb6adc2014-11-05 20:21:25 -0800270 DRM_CLOEXEC,
271 &fd))
Dominik Behrf7b33d72014-11-11 07:17:11 -0800272 return -1;
Zach Reiznerd224eaa2015-01-09 11:25:02 -0800273 else
274 return fd;
Stéphane Marchesin25a26062014-09-12 16:18:59 -0700275}
276
277PUBLIC void
278gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
279 void (*destroy_user_data)(struct gbm_bo *, void *))
280{
281 bo->user_data = data;
282 bo->destroy_user_data = destroy_user_data;
283}
284
285PUBLIC void *
286gbm_bo_get_user_data(struct gbm_bo *bo)
287{
288 return bo->user_data;
289}