summaryrefslogtreecommitdiff
path: root/gralloc/gralloc_gbm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gralloc/gralloc_gbm.cpp')
-rw-r--r--gralloc/gralloc_gbm.cpp475
1 files changed, 0 insertions, 475 deletions
diff --git a/gralloc/gralloc_gbm.cpp b/gralloc/gralloc_gbm.cpp
deleted file mode 100644
index ab6c12b..0000000
--- a/gralloc/gralloc_gbm.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@gmail.com>
- * Copyright (C) 2010-2011 LunarG Inc.
- * Copyright (C) 2016 Linaro, Ltd., Rob Herring <robh@kernel.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#define LOG_TAG "GRALLOC-GBM"
-
-#include <cutils/log.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include <hardware/gralloc.h>
-#include <system/graphics.h>
-
-#include <gbm.h>
-
-#include "gralloc_gbm_priv.h"
-#include <android/gralloc_handle.h>
-
-#include <unordered_map>
-
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-#define unlikely(x) __builtin_expect(!!(x), 0)
-
-static std::unordered_map<buffer_handle_t, struct gbm_bo *> gbm_bo_handle_map;
-
-struct bo_data_t {
- void *map_data;
- int lock_count;
- int locked_for;
-};
-
-void gralloc_gbm_destroy_user_data(struct gbm_bo *bo, void *data)
-{
- struct bo_data_t *bo_data = (struct bo_data_t *)data;
- delete bo_data;
-
- (void)bo;
-}
-
-static struct bo_data_t *gbm_bo_data(struct gbm_bo *bo) {
- return (struct bo_data_t *)gbm_bo_get_user_data(bo);
-}
-
-
-static uint32_t get_gbm_format(int format)
-{
- uint32_t fmt;
-
- switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- fmt = GBM_FORMAT_ABGR8888;
- break;
- case HAL_PIXEL_FORMAT_RGBX_8888:
- fmt = GBM_FORMAT_XBGR8888;
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- fmt = GBM_FORMAT_RGB888;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- fmt = GBM_FORMAT_RGB565;
- break;
- case HAL_PIXEL_FORMAT_BGRA_8888:
- fmt = GBM_FORMAT_ARGB8888;
- break;
- case HAL_PIXEL_FORMAT_YV12:
- /* YV12 is planar, but must be a single buffer so ask for GR88 */
- fmt = GBM_FORMAT_GR88;
- break;
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- default:
- fmt = 0;
- break;
- }
-
- return fmt;
-}
-
-static int gralloc_gbm_get_bpp(int format)
-{
- int bpp;
-
- switch (format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGBX_8888:
- case HAL_PIXEL_FORMAT_BGRA_8888:
- bpp = 4;
- break;
- case HAL_PIXEL_FORMAT_RGB_888:
- bpp = 3;
- break;
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_YCbCr_422_I:
- bpp = 2;
- break;
- /* planar; only Y is considered */
- case HAL_PIXEL_FORMAT_YV12:
- case HAL_PIXEL_FORMAT_YCbCr_422_SP:
- case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- bpp = 1;
- break;
- default:
- bpp = 0;
- break;
- }
-
- return bpp;
-}
-
-static unsigned int get_pipe_bind(int usage)
-{
- unsigned int bind = 0;
-
- if (usage & (GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN))
- bind |= GBM_BO_USE_LINEAR;
- if (usage & GRALLOC_USAGE_CURSOR)
- ;//bind |= GBM_BO_USE_CURSOR;
- if (usage & (GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE))
- bind |= GBM_BO_USE_RENDERING;
- if (usage & GRALLOC_USAGE_HW_FB)
- bind |= GBM_BO_USE_SCANOUT;
- if (usage & GRALLOC_USAGE_HW_COMPOSER)
- bind |= GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING;
-
- return bind;
-}
-
-static struct gbm_bo *gbm_import(struct gbm_device *gbm,
- buffer_handle_t _handle)
-{
- struct gbm_bo *bo;
- struct gralloc_handle_t *handle = gralloc_handle(_handle);
- #ifdef GBM_BO_IMPORT_FD_MODIFIER
- struct gbm_import_fd_modifier_data data;
- #else
- struct gbm_import_fd_data data;
- #endif
-
- int format = get_gbm_format(handle->format);
- if (handle->prime_fd < 0)
- return NULL;
-
- memset(&data, 0, sizeof(data));
- data.width = handle->width;
- data.height = handle->height;
- data.format = format;
- /* Adjust the width and height for a GBM GR88 buffer */
- if (handle->format == HAL_PIXEL_FORMAT_YV12) {
- data.width /= 2;
- data.height += handle->height / 2;
- }
-
- #ifdef GBM_BO_IMPORT_FD_MODIFIER
- data.num_fds = 1;
- data.fds[0] = handle->prime_fd;
- data.strides[0] = handle->stride;
- data.modifier = handle->modifier;
- bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD_MODIFIER, &data, 0);
- #else
- data.fd = handle->prime_fd;
- data.stride = handle->stride;
- bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD, &data, 0);
- #endif
-
- return bo;
-}
-
-static struct gbm_bo *gbm_alloc(struct gbm_device *gbm,
- buffer_handle_t _handle)
-{
- struct gbm_bo *bo;
- struct gralloc_handle_t *handle = gralloc_handle(_handle);
- int format = get_gbm_format(handle->format);
- int usage = get_pipe_bind(handle->usage);
- int width, height;
-
- width = handle->width;
- height = handle->height;
- if (usage & GBM_BO_USE_CURSOR) {
- if (handle->width < 64)
- width = 64;
- if (handle->height < 64)
- height = 64;
- }
-
- /*
- * For YV12, we request GR88, so halve the width since we're getting
- * 16bpp. Then increase the height by 1.5 for the U and V planes.
- */
- if (handle->format == HAL_PIXEL_FORMAT_YV12) {
- width /= 2;
- height += handle->height / 2;
- }
-
- ALOGV("create BO, size=%dx%d, fmt=%d, usage=%x",
- handle->width, handle->height, handle->format, usage);
- bo = gbm_bo_create(gbm, width, height, format, usage);
- if (!bo) {
- ALOGE("failed to create BO, size=%dx%d, fmt=%d, usage=%x",
- handle->width, handle->height, handle->format, usage);
- return NULL;
- }
-
- handle->prime_fd = gbm_bo_get_fd(bo);
- handle->stride = gbm_bo_get_stride(bo);
- #ifdef GBM_BO_IMPORT_FD_MODIFIER
- handle->modifier = gbm_bo_get_modifier(bo);
- #endif
-
- return bo;
-}
-
-void gbm_free(buffer_handle_t handle)
-{
- struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
-
- if (!bo)
- return;
-
- gbm_bo_handle_map.erase(handle);
- gbm_bo_destroy(bo);
-}
-
-/*
- * Return the bo of a registered handle.
- */
-struct gbm_bo *gralloc_gbm_bo_from_handle(buffer_handle_t handle)
-{
- return gbm_bo_handle_map[handle];
-}
-
-static int gbm_map(buffer_handle_t handle, int x, int y, int w, int h,
- int enable_write, void **addr)
-{
- int err = 0;
- int flags = GBM_BO_TRANSFER_READ;
- struct gralloc_gbm_handle_t *gbm_handle = gralloc_handle(handle);
- struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
- struct bo_data_t *bo_data = gbm_bo_data(bo);
- uint32_t stride;
-
- if (bo_data->map_data)
- return -EINVAL;
-
- if (gbm_handle->format == HAL_PIXEL_FORMAT_YV12) {
- if (x || y)
- ALOGE("can't map with offset for planar %p", bo);
- w /= 2;
- h += h / 2;
- }
-
- if (enable_write)
- flags |= GBM_BO_TRANSFER_WRITE;
-
- *addr = gbm_bo_map(bo, 0, 0, x + w, y + h, flags, &stride, &bo_data->map_data);
- ALOGV("mapped bo %p (%d, %d)-(%d, %d) at %p", bo, x, y, w, h, *addr);
- if (*addr == NULL)
- return -ENOMEM;
-
- assert(stride == gbm_bo_get_stride(bo));
-
- return err;
-}
-
-static void gbm_unmap(struct gbm_bo *bo)
-{
- struct bo_data_t *bo_data = gbm_bo_data(bo);
-
- gbm_bo_unmap(bo, bo_data->map_data);
- bo_data->map_data = NULL;
-}
-
-void gbm_dev_destroy(struct gbm_device *gbm)
-{
- int fd = gbm_device_get_fd(gbm);
-
- gbm_device_destroy(gbm);
- close(fd);
-}
-
-struct gbm_device *gbm_dev_create(void)
-{
- struct gbm_device *gbm;
- char path[PROPERTY_VALUE_MAX];
- int fd;
-
- property_get("gralloc.gbm.device", path, "/dev/dri/renderD128");
- fd = open(path, O_RDWR | O_CLOEXEC);
- if (fd < 0) {
- ALOGE("failed to open %s", path);
- return NULL;
- }
-
- gbm = gbm_create_device(fd);
- if (!gbm) {
- ALOGE("failed to create gbm device");
- close(fd);
- }
-
- return gbm;
-}
-
-/*
- * Register a buffer handle.
- */
-int gralloc_gbm_handle_register(buffer_handle_t _handle, struct gbm_device *gbm)
-{
- struct gbm_bo *bo;
-
- if (!_handle)
- return -EINVAL;
-
- if (gbm_bo_handle_map.count(_handle))
- return -EINVAL;
-
- bo = gbm_import(gbm, _handle);
- if (!bo)
- return -EINVAL;
-
- gbm_bo_handle_map.emplace(_handle, bo);
-
- return 0;
-}
-
-/*
- * Unregister a buffer handle. It is no-op for handles created locally.
- */
-int gralloc_gbm_handle_unregister(buffer_handle_t handle)
-{
- gbm_free(handle);
-
- return 0;
-}
-
-/*
- * Create a bo.
- */
-buffer_handle_t gralloc_gbm_bo_create(struct gbm_device *gbm,
- int width, int height, int format, int usage, int *stride)
-{
- struct gbm_bo *bo;
- native_handle_t *handle;
-
- handle = gralloc_handle_create(width, height, format, usage);
- if (!handle)
- return NULL;
-
- bo = gbm_alloc(gbm, handle);
- if (!bo) {
- native_handle_delete(handle);
- return NULL;
- }
-
- gbm_bo_handle_map.emplace(handle, bo);
-
- /* in pixels */
- struct gralloc_handle_t *ghandle = gralloc_handle(handle);
- *stride = ghandle->stride / gralloc_gbm_get_bpp(format);
-
- return handle;
-}
-
-/*
- * Lock a bo. XXX thread-safety?
- */
-int gralloc_gbm_bo_lock(buffer_handle_t handle,
- int usage, int x, int y, int w, int h,
- void **addr)
-{
- struct gralloc_handle_t *gbm_handle = gralloc_handle(handle);
- struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
- struct bo_data_t *bo_data;
-
- if (!bo)
- return -EINVAL;
-
- if ((gbm_handle->usage & usage) != (uint32_t)usage) {
- /* make FB special for testing software renderer with */
-
- if (!(gbm_handle->usage & GRALLOC_USAGE_SW_READ_OFTEN) &&
- !(gbm_handle->usage & GRALLOC_USAGE_HW_FB) &&
- !(gbm_handle->usage & GRALLOC_USAGE_HW_TEXTURE)) {
- ALOGE("bo.usage:x%X/usage:x%X is not GRALLOC_USAGE_HW_FB or GRALLOC_USAGE_HW_TEXTURE",
- gbm_handle->usage, usage);
- return -EINVAL;
- }
- }
-
- bo_data = gbm_bo_data(bo);
- if (!bo_data) {
- bo_data = new struct bo_data_t();
- gbm_bo_set_user_data(bo, bo_data, gralloc_gbm_destroy_user_data);
- }
-
- ALOGI("lock bo %p, cnt=%d, usage=%x", bo, bo_data->lock_count, usage);
-
- /* allow multiple locks with compatible usages */
- if (bo_data->lock_count && (bo_data->locked_for & usage) != usage)
- return -EINVAL;
-
- usage |= bo_data->locked_for;
-
- if (usage & (GRALLOC_USAGE_SW_WRITE_MASK |
- GRALLOC_USAGE_SW_READ_MASK)) {
- /* the driver is supposed to wait for the bo */
- int write = !!(usage & GRALLOC_USAGE_SW_WRITE_MASK);
- int err = gbm_map(handle, x, y, w, h, write, addr);
- if (err)
- return err;
- }
- else {
- /* kernel handles the synchronization here */
- }
-
- bo_data->lock_count++;
- bo_data->locked_for |= usage;
-
- return 0;
-}
-
-/*
- * Unlock a bo.
- */
-int gralloc_gbm_bo_unlock(buffer_handle_t handle)
-{
- struct gbm_bo *bo = gralloc_gbm_bo_from_handle(handle);
- struct bo_data_t *bo_data;
- if (!bo)
- return -EINVAL;
-
- bo_data = gbm_bo_data(bo);
-
- int mapped = bo_data->locked_for &
- (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK);
-
- if (!bo_data->lock_count)
- return 0;
-
- if (mapped)
- gbm_unmap(bo);
-
- bo_data->lock_count--;
- if (!bo_data->lock_count)
- bo_data->locked_for = 0;
-
- return 0;
-}