OSDN Git Service

fix incorrect error detection in gbm_bo_get_fd
[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 <stdlib.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <fcntl.h>
11 #include <xf86drm.h>
12
13 #include "gbm_priv.h"
14 #include "util.h"
15
16 /*
17 gbm_buffer_base.cc:  gbm_bo_get_width(bo),
18 gbm_buffer_base.cc:  gbm_bo_get_height(bo),
19 gbm_buffer_base.cc:  gbm_bo_get_stride(bo),
20 gbm_buffer_base.cc:  gbm_bo_get_handle(bo).u32,
21 gbm_buffer_base.cc:  return gbm_bo_get_handle(bo_).u32;
22 gbm_buffer_base.cc:  return gfx::Size(gbm_bo_get_width(bo_), gbm_bo_get_height(bo_));
23 gbm_buffer.cc:    gbm_bo_destroy(bo());
24 gbm_buffer.cc:  gbm_bo* bo = gbm_bo_create(device,
25 gbm_surface.cc:    gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy);
26 gbm_surface.cc:      static_cast<GbmSurfaceBuffer*>(gbm_bo_get_user_data(buffer)));
27 gbm_surface.cc:    gbm_surface_release_buffer(native_surface_, current_buffer_);
28 gbm_surface.cc:    gbm_surface_destroy(native_surface_);
29 gbm_surface.cc:  native_surface_ = gbm_surface_create(
30 gbm_surface.cc:  gbm_bo* pending_buffer = gbm_surface_lock_front_buffer(native_surface_);
31 gbm_surface.cc:    gbm_surface_release_buffer(native_surface_, current_buffer_);
32 ozone_platform_gbm.cc:        device_(gbm_create_device(dri_->get_fd())) {}
33 ozone_platform_gbm.cc:    gbm_device_destroy(device_);
34 */
35
36 extern struct gbm_driver gbm_driver_cirrus;
37 #ifdef GBM_EXYNOS
38 extern struct gbm_driver gbm_driver_exynos;
39 #endif
40 extern struct gbm_driver gbm_driver_gma500;
41 #ifdef GBM_I915
42 extern struct gbm_driver gbm_driver_i915;
43 #endif
44 #ifdef GBM_ROCKCHIP
45 extern struct gbm_driver gbm_driver_rockchip;
46 #endif
47 #ifdef GBM_TEGRA
48 extern struct gbm_driver gbm_driver_tegra;
49 #endif
50 extern struct gbm_driver gbm_driver_udl;
51
52 static 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
91 PUBLIC int
92 gbm_device_get_fd(struct gbm_device *gbm)
93 {
94         return gbm->fd;
95 }
96
97 PUBLIC const char *
98 gbm_device_get_backend_name(struct gbm_device *gbm)
99 {
100         return gbm->driver->name;
101 }
102
103 PUBLIC int
104 gbm_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
131 PUBLIC 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
159 PUBLIC void gbm_device_destroy(struct gbm_device *gbm)
160 {
161         if (gbm->driver->close)
162                 gbm->driver->close(gbm);
163         free(gbm);
164 }
165
166 PUBLIC 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
175 PUBLIC void gbm_surface_destroy(struct gbm_surface *surface)
176 {
177         free(surface);
178 }
179
180 PUBLIC struct gbm_bo *gbm_surface_lock_front_buffer(struct gbm_surface *surface)
181 {
182         return NULL;
183 }
184
185 PUBLIC void gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo)
186 {
187 }
188
189 PUBLIC 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
216 PUBLIC 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
228 PUBLIC uint32_t
229 gbm_bo_get_width(struct gbm_bo *bo)
230 {
231         return bo->width;
232 }
233
234 PUBLIC uint32_t
235 gbm_bo_get_height(struct gbm_bo *bo)
236 {
237         return bo->height;
238 }
239
240 PUBLIC uint32_t
241 gbm_bo_get_stride(struct gbm_bo *bo)
242 {
243         return bo->stride;
244 }
245
246 PUBLIC uint32_t
247 gbm_bo_get_format(struct gbm_bo *bo)
248 {
249         return bo->format;
250 }
251
252 PUBLIC struct gbm_device *
253 gbm_bo_get_device(struct gbm_bo *bo)
254 {
255         return bo->gbm;
256 }
257
258 PUBLIC union gbm_bo_handle
259 gbm_bo_get_handle(struct gbm_bo *bo)
260 {
261         return bo->handle;
262 }
263
264 PUBLIC int
265 gbm_bo_get_fd(struct gbm_bo *bo)
266 {
267         int fd;
268
269         if (drmPrimeHandleToFD(gbm_device_get_fd(bo->gbm),
270                                 gbm_bo_get_handle(bo).u32,
271                                 DRM_CLOEXEC,
272                                 &fd))
273                 return -1;
274         else
275                 return fd;
276 }
277
278 PUBLIC void
279 gbm_bo_set_user_data(struct gbm_bo *bo, void *data,
280                      void (*destroy_user_data)(struct gbm_bo *, void *))
281 {
282         bo->user_data = data;
283         bo->destroy_user_data = destroy_user_data;
284 }
285
286 PUBLIC void *
287 gbm_bo_get_user_data(struct gbm_bo *bo)
288 {
289         return bo->user_data;
290 }