OSDN Git Service

Use alternative GRALLOC_GBM_HANDLE_MAGIC
[android-x86/external-gbm_gralloc.git] / gralloc.cpp
1 /*
2  * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
3  * Copyright (C) 2010-2011 LunarG Inc.
4  * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #define LOG_TAG "GRALLOC-GBM"
26
27 #include <cutils/log.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <pthread.h>
31 #include <errno.h>
32
33 #include <hardware/gralloc.h>
34 #include <system/graphics.h>
35
36 #include <gbm.h>
37
38 #include "gralloc_drm.h"
39 #include "gralloc_gbm_priv.h"
40
41 struct gbm_module_t {
42         gralloc_module_t base;
43
44         pthread_mutex_t mutex;
45         struct gbm_device *gbm;
46 };
47
48 static inline int gralloc_gbm_get_bpp(int format)
49 {
50         int bpp;
51
52         switch (format) {
53         case HAL_PIXEL_FORMAT_RGBA_8888:
54         case HAL_PIXEL_FORMAT_RGBX_8888:
55         case HAL_PIXEL_FORMAT_BGRA_8888:
56                 bpp = 4;
57                 break;
58         case HAL_PIXEL_FORMAT_RGB_888:
59                 bpp = 3;
60                 break;
61         case HAL_PIXEL_FORMAT_RGB_565:
62         case HAL_PIXEL_FORMAT_YCbCr_422_I:
63                 bpp = 2;
64                 break;
65         /* planar; only Y is considered */
66         case HAL_PIXEL_FORMAT_YV12:
67         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
68         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
69                 bpp = 1;
70                 break;
71         default:
72                 bpp = 0;
73                 break;
74         }
75
76         return bpp;
77 }
78
79 /*
80  * Initialize the DRM device object
81  */
82 static int gbm_init(struct gbm_module_t *dmod)
83 {
84         int err = 0;
85
86         pthread_mutex_lock(&dmod->mutex);
87         if (!dmod->gbm) {
88                 dmod->gbm = gbm_dev_create();
89                 if (!dmod->gbm)
90                         err = -EINVAL;
91         }
92         pthread_mutex_unlock(&dmod->mutex);
93
94         return err;
95 }
96
97 static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
98 {
99         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
100         va_list args;
101         int err;
102         uint32_t uop = static_cast<uint32_t>(op);
103
104         err = gbm_init(dmod);
105         if (err)
106                 return err;
107
108         va_start(args, op);
109         switch (uop) {
110         case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
111                 {
112                         int *fd = va_arg(args, int *);
113                         *fd = gbm_device_get_fd(dmod->gbm);
114                         err = 0;
115                 }
116                 break;
117         /* TODO: This is a stub and should be implemented fully */
118         case GRALLOC_MODULE_PERFORM_GET_USAGE:
119                 {
120                         int *buffer_usage = va_arg(args, int *);
121                         *buffer_usage = 0;
122                         err = 0;
123                 }
124                 break;
125         default:
126                 err = -EINVAL;
127                 break;
128         }
129         va_end(args);
130
131         return err;
132 }
133
134 static int gbm_mod_register_buffer(const gralloc_module_t *mod,
135                 buffer_handle_t handle)
136 {
137         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
138         int err;
139
140         err = gbm_init(dmod);
141         if (err)
142                 return err;
143
144         pthread_mutex_lock(&dmod->mutex);
145         err = gralloc_gbm_handle_register(handle, dmod->gbm);
146         pthread_mutex_unlock(&dmod->mutex);
147
148         return err;
149 }
150
151 static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
152                 buffer_handle_t handle)
153 {
154         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
155         int err;
156
157         pthread_mutex_lock(&dmod->mutex);
158         err = gralloc_gbm_handle_unregister(handle);
159         pthread_mutex_unlock(&dmod->mutex);
160
161         return err;
162 }
163
164 static int gbm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
165                 int usage, int x, int y, int w, int h, void **ptr)
166 {
167         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
168         struct gralloc_gbm_bo_t *bo;
169         int err;
170
171         pthread_mutex_lock(&dmod->mutex);
172
173         bo = gralloc_gbm_bo_from_handle(handle);
174         if (!bo) {
175                 err = -EINVAL;
176                 goto unlock;
177         }
178
179         err = gralloc_gbm_bo_lock(bo, usage, x, y, w, h, ptr);
180         ALOGE("buffer %p lock usage = %08x", handle, usage);
181
182 unlock:
183         pthread_mutex_unlock(&dmod->mutex);
184         return err;
185 }
186
187 static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
188 {
189         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
190         struct gralloc_gbm_bo_t *bo;
191         int err = 0;
192
193         pthread_mutex_lock(&dmod->mutex);
194
195         bo = gralloc_gbm_bo_from_handle(handle);
196         if (!bo) {
197                 err = -EINVAL;
198                 goto unlock;
199         }
200
201         gralloc_gbm_bo_unlock(bo);
202
203 unlock:
204         pthread_mutex_unlock(&dmod->mutex);
205         return err;
206 }
207
208 static int gbm_mod_close_gpu0(struct hw_device_t *dev)
209 {
210         struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
211         struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
212
213         gbm_dev_destroy(dmod->gbm);
214         delete alloc;
215
216         return 0;
217 }
218
219 static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
220 {
221         struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
222         struct gralloc_gbm_bo_t *bo;
223         int err = 0;
224
225         pthread_mutex_lock(&dmod->mutex);
226
227         bo = gralloc_gbm_bo_from_handle(handle);
228         if (!bo) {
229                 err = -EINVAL;
230                 goto unlock;
231         }
232
233         gralloc_gbm_bo_decref(bo);
234
235 unlock:
236         pthread_mutex_unlock(&dmod->mutex);
237         return err;
238 }
239
240 static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
241                 int w, int h, int format, int usage,
242                 buffer_handle_t *handle, int *stride)
243 {
244         struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
245         struct gralloc_gbm_bo_t *bo;
246         int err = 0;
247
248         pthread_mutex_lock(&dmod->mutex);
249
250         bo = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage);
251         if (!bo) {
252                 err = -errno;
253                 goto unlock;
254         }
255
256         *handle = gralloc_gbm_bo_get_handle(bo);
257         /* in pixels */
258         *stride = gbm_bo_get_stride(gralloc_gbm_bo_to_gbm_bo(bo)) /
259                 gralloc_gbm_get_bpp(format);
260
261         ALOGE("buffer %p usage = %08x", *handle, usage);
262 unlock:
263         pthread_mutex_unlock(&dmod->mutex);
264         return err;
265 }
266
267 static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
268 {
269         struct alloc_device_t *alloc;
270         int err;
271
272         err = gbm_init(dmod);
273         if (err)
274                 return err;
275
276         alloc = new alloc_device_t;
277         if (!alloc)
278                 return -EINVAL;
279
280         alloc->common.tag = HARDWARE_DEVICE_TAG;
281         alloc->common.version = 0;
282         alloc->common.module = &dmod->base.common;
283         alloc->common.close = gbm_mod_close_gpu0;
284
285         alloc->alloc = gbm_mod_alloc_gpu0;
286         alloc->free = gbm_mod_free_gpu0;
287
288         *dev = &alloc->common;
289
290         return 0;
291 }
292
293 static int gbm_mod_open(const struct hw_module_t *mod,
294                 const char *name, struct hw_device_t **dev)
295 {
296         struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
297         int err;
298
299         if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
300                 err = gbm_mod_open_gpu0(dmod, dev);
301         else
302                 err = -EINVAL;
303
304         return err;
305 }
306
307 static struct hw_module_methods_t gbm_mod_methods = {
308         .open = gbm_mod_open
309 };
310
311 struct gbm_module_t HAL_MODULE_INFO_SYM = {
312         .base = {
313                 .common = {
314                         .tag = HARDWARE_MODULE_TAG,
315                         .version_major = 1,
316                         .version_minor = 0,
317                         .id = GRALLOC_HARDWARE_MODULE_ID,
318                         .name = "GBM Memory Allocator",
319                         .author = "Rob Herring - Linaro",
320                         .methods = &gbm_mod_methods
321                 },
322                 .registerBuffer = gbm_mod_register_buffer,
323                 .unregisterBuffer = gbm_mod_unregister_buffer,
324                 .lock = gbm_mod_lock,
325                 .unlock = gbm_mod_unlock,
326                 .perform = gbm_mod_perform
327         },
328
329         .mutex = PTHREAD_MUTEX_INITIALIZER,
330         .gbm = NULL,
331 };