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>
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
25 #define LOG_TAG "GRALLOC-GBM"
27 #include <cutils/log.h>
33 #include <hardware/gralloc.h>
34 #include <system/graphics.h>
38 #include "gralloc_drm.h"
39 #include "gralloc_gbm_priv.h"
42 gralloc_module_t base;
44 pthread_mutex_t mutex;
45 struct gbm_device *gbm;
48 static inline int gralloc_gbm_get_bpp(int format)
53 case HAL_PIXEL_FORMAT_RGBA_8888:
54 case HAL_PIXEL_FORMAT_RGBX_8888:
55 case HAL_PIXEL_FORMAT_BGRA_8888:
58 case HAL_PIXEL_FORMAT_RGB_888:
61 case HAL_PIXEL_FORMAT_RGB_565:
62 case HAL_PIXEL_FORMAT_YCbCr_422_I:
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:
80 * Initialize the DRM device object
82 static int gbm_init(struct gbm_module_t *dmod)
86 pthread_mutex_lock(&dmod->mutex);
88 dmod->gbm = gbm_dev_create();
92 pthread_mutex_unlock(&dmod->mutex);
97 static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
99 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
102 uint32_t uop = static_cast<uint32_t>(op);
104 err = gbm_init(dmod);
110 case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
112 int *fd = va_arg(args, int *);
113 *fd = gbm_device_get_fd(dmod->gbm);
117 /* TODO: This is a stub and should be implemented fully */
118 case GRALLOC_MODULE_PERFORM_GET_USAGE:
132 static int gbm_mod_register_buffer(const gralloc_module_t *mod,
133 buffer_handle_t handle)
135 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
138 err = gbm_init(dmod);
142 pthread_mutex_lock(&dmod->mutex);
143 err = gralloc_gbm_handle_register(handle, dmod->gbm);
144 pthread_mutex_unlock(&dmod->mutex);
149 static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
150 buffer_handle_t handle)
152 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
155 pthread_mutex_lock(&dmod->mutex);
156 err = gralloc_gbm_handle_unregister(handle);
157 pthread_mutex_unlock(&dmod->mutex);
162 static int gbm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
163 int usage, int x, int y, int w, int h, void **ptr)
165 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
166 struct gralloc_gbm_bo_t *bo;
169 pthread_mutex_lock(&dmod->mutex);
171 bo = gralloc_gbm_bo_from_handle(handle);
177 err = gralloc_gbm_bo_lock(bo, usage, x, y, w, h, ptr);
178 ALOGE("buffer %p lock usage = %08x", handle, usage);
181 pthread_mutex_unlock(&dmod->mutex);
185 static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
187 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
188 struct gralloc_gbm_bo_t *bo;
191 pthread_mutex_lock(&dmod->mutex);
193 bo = gralloc_gbm_bo_from_handle(handle);
199 gralloc_gbm_bo_unlock(bo);
202 pthread_mutex_unlock(&dmod->mutex);
206 static int gbm_mod_close_gpu0(struct hw_device_t *dev)
208 struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
209 struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
211 gbm_dev_destroy(dmod->gbm);
217 static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
219 struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
220 struct gralloc_gbm_bo_t *bo;
223 pthread_mutex_lock(&dmod->mutex);
225 bo = gralloc_gbm_bo_from_handle(handle);
231 gralloc_gbm_bo_decref(bo);
234 pthread_mutex_unlock(&dmod->mutex);
238 static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
239 int w, int h, int format, int usage,
240 buffer_handle_t *handle, int *stride)
242 struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
243 struct gralloc_gbm_bo_t *bo;
246 pthread_mutex_lock(&dmod->mutex);
248 bo = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage);
254 *handle = gralloc_gbm_bo_get_handle(bo);
256 *stride = gbm_bo_get_stride(gralloc_gbm_bo_to_gbm_bo(bo)) /
257 gralloc_gbm_get_bpp(format);
259 ALOGE("buffer %p usage = %08x", *handle, usage);
261 pthread_mutex_unlock(&dmod->mutex);
265 static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
267 struct alloc_device_t *alloc;
270 err = gbm_init(dmod);
274 alloc = new alloc_device_t;
278 alloc->common.tag = HARDWARE_DEVICE_TAG;
279 alloc->common.version = 0;
280 alloc->common.module = &dmod->base.common;
281 alloc->common.close = gbm_mod_close_gpu0;
283 alloc->alloc = gbm_mod_alloc_gpu0;
284 alloc->free = gbm_mod_free_gpu0;
286 *dev = &alloc->common;
291 static int gbm_mod_open(const struct hw_module_t *mod,
292 const char *name, struct hw_device_t **dev)
294 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
297 if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
298 err = gbm_mod_open_gpu0(dmod, dev);
305 static struct hw_module_methods_t gbm_mod_methods = {
309 struct gbm_module_t HAL_MODULE_INFO_SYM = {
312 .tag = HARDWARE_MODULE_TAG,
315 .id = GRALLOC_HARDWARE_MODULE_ID,
316 .name = "GBM Memory Allocator",
317 .author = "Rob Herring - Linaro",
318 .methods = &gbm_mod_methods
320 .registerBuffer = gbm_mod_register_buffer,
321 .unregisterBuffer = gbm_mod_unregister_buffer,
322 .lock = gbm_mod_lock,
323 .unlock = gbm_mod_unlock,
324 .perform = gbm_mod_perform
327 .mutex = PTHREAD_MUTEX_INITIALIZER,