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>
28 #include <cutils/atomic.h>
29 #include <cutils/properties.h>
32 #include <sys/types.h>
36 #include <hardware/gralloc.h>
37 #include <system/graphics.h>
41 #include "gralloc_gbm_priv.h"
42 #include "gralloc_drm_handle.h"
44 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
46 #define unlikely(x) __builtin_expect(!!(x), 0)
48 struct gralloc_gbm_bo_t {
52 struct gralloc_gbm_handle_t *handle;
54 int imported; /* the handle is from a remote proces when true */
59 unsigned int refcount;
62 static int32_t gralloc_gbm_pid = 0;
64 static uint32_t get_gbm_format(int format)
69 case HAL_PIXEL_FORMAT_RGBA_8888:
70 fmt = GBM_FORMAT_ABGR8888;
72 case HAL_PIXEL_FORMAT_RGBX_8888:
73 fmt = GBM_FORMAT_XBGR8888;
75 case HAL_PIXEL_FORMAT_RGB_888:
76 fmt = GBM_FORMAT_RGB888;
78 case HAL_PIXEL_FORMAT_RGB_565:
79 fmt = GBM_FORMAT_BGR565;
81 case HAL_PIXEL_FORMAT_BGRA_8888:
82 fmt = GBM_FORMAT_ARGB8888;
84 case HAL_PIXEL_FORMAT_YV12:
85 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
86 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
95 static unsigned int get_pipe_bind(int usage)
97 unsigned int bind = 0;
99 if (usage & (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN))
100 bind |= GBM_BO_USE_LINEAR;
101 if (usage & GRALLOC_USAGE_CURSOR)
102 ;//bind |= GBM_BO_USE_CURSOR;
103 if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
104 bind |= GBM_BO_USE_RENDERING;
105 if (usage & GRALLOC_USAGE_HW_FB)
106 bind |= GBM_BO_USE_SCANOUT;
111 static struct gralloc_gbm_bo_t *gbm_import(struct gbm_device *gbm,
112 struct gralloc_gbm_handle_t *handle)
114 struct gralloc_gbm_bo_t *buf;
115 struct gbm_import_fd_data data;
116 int format = get_gbm_format(handle->format);
117 int usage = get_pipe_bind(handle->usage);
119 if (handle->prime_fd < 0)
122 buf = new struct gralloc_gbm_bo_t();
124 ALOGE("failed to allocate pipe buffer");
128 data.fd = handle->prime_fd;
129 data.width = handle->width;
130 data.height = handle->height;
131 data.stride = handle->stride;
132 data.format = format;
134 buf->bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD, &data, 0);
142 static struct gralloc_gbm_bo_t *gbm_alloc(struct gbm_device *gbm,
143 struct gralloc_gbm_handle_t *handle)
145 struct gralloc_gbm_bo_t *buf;
146 int format = get_gbm_format(handle->format);
147 int usage = get_pipe_bind(handle->usage);
150 buf = new struct gralloc_gbm_bo_t();
152 ALOGE("failed to allocate pipe buffer");
156 width = handle->width;
157 height = handle->height;
158 if (usage & GBM_BO_USE_CURSOR) {
159 if (handle->width < 64)
161 if (handle->height < 64)
165 ALOGD("create BO, size=%dx%d, fmt=%d, usage=%x",
166 handle->width, handle->height, handle->format, usage);
167 buf->bo = gbm_bo_create(gbm, width, height, format, usage);
169 ALOGE("failed to create BO, size=%dx%d, fmt=%d, usage=%x",
170 handle->width, handle->height, handle->format, usage);
175 handle->prime_fd = gbm_bo_get_fd(buf->bo);
176 handle->stride = gbm_bo_get_stride(buf->bo);
181 static void gbm_free(struct gralloc_gbm_bo_t *bo)
183 struct gralloc_gbm_handle_t *handle = bo->handle;
185 close(handle->prime_fd);
186 handle->prime_fd = -1;
188 gbm_bo_destroy(bo->bo);
192 static int gbm_map(struct gralloc_gbm_bo_t *bo, int x, int y, int w, int h,
193 int enable_write, void **addr)
200 *addr = gbm_bo_map(bo->bo, x, y, w, h, 0, &bo->map_data);
201 ALOGE("mapped bo %p at %p", bo, *addr);
208 static void gbm_unmap(struct gralloc_gbm_bo_t *bo)
210 gbm_bo_unmap(bo->bo, bo->map_data);
214 void gbm_dev_destroy(struct gbm_device *gbm)
216 int fd = gbm_device_get_fd(gbm);
218 gbm_device_destroy(gbm);
222 struct gbm_device *gbm_dev_create(void)
224 struct gbm_device *gbm;
225 char path[PROPERTY_VALUE_MAX];
228 property_get("gralloc.gbm.device", path, "/dev/dri/renderD128");
229 fd = open(path, O_RDWR);
231 ALOGE("failed to open %s", path);
235 gbm = gbm_create_device(fd);
237 ALOGE("failed to create gbm device");
244 * Return the pid of the process.
246 static int gralloc_gbm_get_pid(void)
248 if (unlikely(!gralloc_gbm_pid))
249 android_atomic_write((int32_t) getpid(), &gralloc_gbm_pid);
251 return gralloc_gbm_pid;
255 * Validate a buffer handle and return the associated bo.
257 static struct gralloc_gbm_bo_t *validate_handle(buffer_handle_t _handle,
258 struct gbm_device *gbm)
260 struct gralloc_gbm_bo_t *bo;
261 struct gralloc_gbm_handle_t *handle = gralloc_gbm_handle(_handle);
266 /* the buffer handle is passed to a new process */
267 //ALOGE("data_owner=%d gralloc_pid=%d data=%p\n", handle->data_owner, gralloc_gbm_get_pid(), handle->data);
268 if (handle->data_owner == gralloc_gbm_get_pid())
269 return (struct gralloc_gbm_bo_t *)handle->data;
275 ALOGE("handle: name=%d pfd=%d\n", handle->name,
277 /* create the struct gralloc_gbm_bo_t locally */
278 if (handle->name || handle->prime_fd >= 0)
279 bo = gbm_import(gbm, handle);
280 else /* an invalid handle */
288 handle->data_owner = gralloc_gbm_get_pid();
295 * Register a buffer handle.
297 int gralloc_gbm_handle_register(buffer_handle_t handle, struct gbm_device *gbm)
299 return (validate_handle(handle, gbm)) ? 0 : -EINVAL;
303 * Unregister a buffer handle. It is no-op for handles created locally.
305 int gralloc_gbm_handle_unregister(buffer_handle_t handle)
307 struct gralloc_gbm_bo_t *bo;
309 bo = validate_handle(handle, NULL);
314 gralloc_gbm_bo_decref(bo);
320 * Create a buffer handle.
322 static struct gralloc_gbm_handle_t *create_bo_handle(int width,
323 int height, int format, int usage)
325 struct gralloc_gbm_handle_t *handle;
327 handle = new gralloc_gbm_handle_t();
331 handle->base.version = sizeof(handle->base);
332 handle->base.numInts = GRALLOC_GBM_HANDLE_NUM_INTS;
333 handle->base.numFds = GRALLOC_GBM_HANDLE_NUM_FDS;
335 handle->magic = GRALLOC_GBM_HANDLE_MAGIC;
336 handle->width = width;
337 handle->height = height;
338 handle->format = format;
339 handle->usage = usage;
340 handle->prime_fd = -1;
348 struct gralloc_gbm_bo_t *gralloc_gbm_bo_create(struct gbm_device *gbm,
349 int width, int height, int format, int usage)
351 struct gralloc_gbm_bo_t *bo;
352 struct gralloc_gbm_handle_t *handle;
354 handle = create_bo_handle(width, height, format, usage);
358 bo = gbm_alloc(gbm, handle);
368 handle->data_owner = gralloc_gbm_get_pid();
377 static void gralloc_gbm_bo_destroy(struct gralloc_gbm_bo_t *bo)
379 struct gralloc_gbm_handle_t *handle = bo->handle;
380 int imported = bo->imported;
382 /* gralloc still has a reference */
388 handle->data_owner = 0;
397 * Decrease refcount, if no refs anymore then destroy.
399 void gralloc_gbm_bo_decref(struct gralloc_gbm_bo_t *bo)
402 gralloc_gbm_bo_destroy(bo);
406 * Return the bo of a registered handle.
408 struct gralloc_gbm_bo_t *gralloc_gbm_bo_from_handle(buffer_handle_t handle)
410 return validate_handle(handle, NULL);
414 * Get the buffer handle and stride of a bo.
416 buffer_handle_t gralloc_gbm_bo_get_handle(struct gralloc_gbm_bo_t *bo)
418 return &bo->handle->base;
422 * Get the buffer handle and stride of a bo.
424 struct gbm_bo *gralloc_gbm_bo_to_gbm_bo(struct gralloc_gbm_bo_t *_bo)
430 * Query YUV component offsets for a buffer handle
432 void gralloc_gbm_resolve_format(buffer_handle_t _handle,
433 uint32_t *pitches, uint32_t *offsets, uint32_t *handles)
437 * Lock a bo. XXX thread-safety?
439 int gralloc_gbm_bo_lock(struct gralloc_gbm_bo_t *bo,
440 int usage, int x, int y, int w, int h,
443 if ((bo->handle->usage & usage) != usage) {
444 /* make FB special for testing software renderer with */
446 if (!(bo->handle->usage & GRALLOC_USAGE_SW_READ_OFTEN) &&
447 !(bo->handle->usage & GRALLOC_USAGE_HW_FB) &&
448 !(bo->handle->usage & GRALLOC_USAGE_HW_TEXTURE)) {
449 ALOGE("bo.usage:x%X/usage:x%X is not GRALLOC_USAGE_HW_FB or GRALLOC_USAGE_HW_TEXTURE",
450 bo->handle->usage, usage);
455 /* allow multiple locks with compatible usages */
456 if (bo->lock_count && (bo->locked_for & usage) != usage)
459 usage |= bo->locked_for;
461 if (usage & (GRALLOC_USAGE_SW_WRITE_MASK |
462 GRALLOC_USAGE_SW_READ_MASK)) {
463 /* the driver is supposed to wait for the bo */
464 int write = !!(usage & GRALLOC_USAGE_SW_WRITE_MASK);
465 int err = gbm_map(bo, x, y, w, h, write, addr);
470 /* kernel handles the synchronization here */
474 bo->locked_for |= usage;
482 void gralloc_gbm_bo_unlock(struct gralloc_gbm_bo_t *bo)
484 int mapped = bo->locked_for &
485 (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK);