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"
34 #include <hardware/gralloc.h>
35 #include <system/graphics.h>
38 #include <drm_framebuffer.h>
40 #include "gralloc_drm.h"
41 #include "gralloc_gbm_priv.h"
44 gralloc_module_t base;
46 pthread_mutex_t mutex;
47 struct gbm_device *gbm;
48 struct drm_framebuffer *fb;
52 * Initialize the DRM device object
54 static int gbm_init(struct gbm_module_t *dmod, bool master = false)
58 pthread_mutex_lock(&dmod->mutex);
60 dmod->gbm = gbm_dev_create(master);
64 pthread_mutex_unlock(&dmod->mutex);
69 static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
71 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
74 uint32_t uop = static_cast<uint32_t>(op);
82 case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
84 int *fd = va_arg(args, int *);
85 *fd = gbm_device_get_fd(dmod->gbm);
98 static int gbm_mod_register_buffer(const gralloc_module_t *mod,
99 buffer_handle_t handle)
101 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
104 err = gbm_init(dmod);
108 pthread_mutex_lock(&dmod->mutex);
109 err = gralloc_gbm_handle_register(handle, dmod->gbm);
110 if (err == 0 && dmod->fb)
111 drm_framebuffer_import(dmod->fb, handle);
112 pthread_mutex_unlock(&dmod->mutex);
117 static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
118 buffer_handle_t handle)
120 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
123 pthread_mutex_lock(&dmod->mutex);
124 err = gralloc_gbm_handle_unregister(handle);
125 pthread_mutex_unlock(&dmod->mutex);
130 static int gbm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
131 int usage, int x, int y, int w, int h, void **ptr)
133 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
136 pthread_mutex_lock(&dmod->mutex);
138 err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, ptr);
139 ALOGV("buffer %p lock usage = %08x", handle, usage);
141 pthread_mutex_unlock(&dmod->mutex);
145 static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
147 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
150 pthread_mutex_lock(&dmod->mutex);
151 err = gralloc_gbm_bo_unlock(handle);
152 pthread_mutex_unlock(&dmod->mutex);
157 static int gbm_mod_lock_ycbcr(gralloc_module_t const *mod, buffer_handle_t handle,
158 int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr)
160 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
163 pthread_mutex_lock(&dmod->mutex);
164 err = gralloc_gbm_bo_lock_ycbcr(handle, usage, x, y, w, h, ycbcr);
165 pthread_mutex_unlock(&dmod->mutex);
170 static int gbm_mod_close_gpu0(struct hw_device_t *dev)
172 struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
173 struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
175 gbm_dev_destroy(dmod->gbm);
181 static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
183 struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
185 pthread_mutex_lock(&dmod->mutex);
187 native_handle_close(handle);
190 pthread_mutex_unlock(&dmod->mutex);
194 static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
195 int w, int h, int format, int usage,
196 buffer_handle_t *handle, int *stride)
198 struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
201 pthread_mutex_lock(&dmod->mutex);
203 *handle = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage, stride);
207 ALOGV("buffer %p usage = %08x", *handle, usage);
208 pthread_mutex_unlock(&dmod->mutex);
212 static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
214 struct alloc_device_t *alloc;
217 err = gbm_init(dmod);
221 alloc = new alloc_device_t();
225 alloc->common.tag = HARDWARE_DEVICE_TAG;
226 alloc->common.version = 0;
227 alloc->common.module = &dmod->base.common;
228 alloc->common.close = gbm_mod_close_gpu0;
230 alloc->alloc = gbm_mod_alloc_gpu0;
231 alloc->free = gbm_mod_free_gpu0;
233 *dev = &alloc->common;
238 static int gbm_mod_open_fb0(struct gbm_module_t *dmod, hw_device_t **dev)
240 int err = gbm_init(dmod, true);
244 pthread_mutex_lock(&dmod->mutex);
245 err = drm_framebuffer_open(gbm_device_get_fd(dmod->gbm), &dmod->fb, dev);
246 pthread_mutex_unlock(&dmod->mutex);
251 static int gbm_mod_open(const struct hw_module_t *mod,
252 const char *name, struct hw_device_t **dev)
254 struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
257 if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
258 err = gbm_mod_open_gpu0(dmod, dev);
259 else if (strcmp(name, GRALLOC_HARDWARE_FB0) == 0)
260 err = gbm_mod_open_fb0(dmod, dev);
267 static struct hw_module_methods_t gbm_mod_methods = {
271 struct gbm_module_t HAL_MODULE_INFO_SYM = {
274 .tag = HARDWARE_MODULE_TAG,
277 .id = GRALLOC_HARDWARE_MODULE_ID,
278 .name = "GBM Memory Allocator",
279 .author = "Rob Herring - Linaro",
280 .methods = &gbm_mod_methods
282 .registerBuffer = gbm_mod_register_buffer,
283 .unregisterBuffer = gbm_mod_unregister_buffer,
284 .lock = gbm_mod_lock,
285 .unlock = gbm_mod_unlock,
286 .lock_ycbcr = gbm_mod_lock_ycbcr,
287 .perform = gbm_mod_perform
290 .mutex = PTHREAD_MUTEX_INITIALIZER,