diff options
Diffstat (limited to 'gralloc/gralloc_gbm.cpp')
-rw-r--r-- | gralloc/gralloc_gbm.cpp | 475 |
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; -} |