From d225ab0eaecac84e5fd7199968a433a462af0196 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Mon, 9 Feb 2015 02:31:58 -0500 Subject: drm_gralloc: Move gralloc.c and gralloc_drm.c to cpp Change-Id: Id08a921c74fc431328ed92bb94bfeaa5764c3e5c Signed-off-by: Sean Paul Signed-off-by: Tomasz Figa --- Android.mk | 4 +- gralloc.c | 261 ---------------------------------- gralloc.cpp | 261 ++++++++++++++++++++++++++++++++++ gralloc_drm.c | 432 -------------------------------------------------------- gralloc_drm.cpp | 432 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 695 insertions(+), 695 deletions(-) delete mode 100644 gralloc.c create mode 100644 gralloc.cpp delete mode 100644 gralloc_drm.c create mode 100644 gralloc_drm.cpp diff --git a/Android.mk b/Android.mk index dcceda6..f4d4483 100644 --- a/Android.mk +++ b/Android.mk @@ -82,7 +82,7 @@ LOCAL_MODULE := libgralloc_drm LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := \ - gralloc_drm.c + gralloc_drm.cpp LOCAL_C_INCLUDES := \ external/libdrm \ @@ -150,7 +150,7 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ - gralloc.c \ + gralloc.cpp LOCAL_C_INCLUDES := \ external/libdrm \ diff --git a/gralloc.c b/gralloc.c deleted file mode 100644 index 3ac3995..0000000 --- a/gralloc.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Copyright (C) 2010-2011 Chia-I Wu - * Copyright (C) 2010-2011 LunarG Inc. - * - * 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-MOD" - -#include -#include -#include -#include -#include - -#include "gralloc_drm.h" -#include "gralloc_drm_priv.h" - -/* - * Initialize the DRM device object - */ -static int drm_init(struct drm_module_t *dmod) -{ - int err = 0; - - pthread_mutex_lock(&dmod->mutex); - if (!dmod->drm) { - dmod->drm = gralloc_drm_create(); - if (!dmod->drm) - err = -EINVAL; - } - pthread_mutex_unlock(&dmod->mutex); - - return err; -} - -static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...) -{ - struct drm_module_t *dmod = (struct drm_module_t *) mod; - va_list args; - int err; - - err = drm_init(dmod); - if (err) - return err; - - va_start(args, op); - switch (op) { - case GRALLOC_MODULE_PERFORM_GET_DRM_FD: - { - int *fd = va_arg(args, int *); - *fd = gralloc_drm_get_fd(dmod->drm); - err = 0; - } - break; - /* should we remove this and next ops, and make it transparent? */ - case GRALLOC_MODULE_PERFORM_GET_DRM_MAGIC: - { - int32_t *magic = va_arg(args, int32_t *); - err = gralloc_drm_get_magic(dmod->drm, magic); - } - break; - case GRALLOC_MODULE_PERFORM_AUTH_DRM_MAGIC: - { - int32_t magic = va_arg(args, int32_t); - err = gralloc_drm_auth_magic(dmod->drm, magic); - } - break; - case GRALLOC_MODULE_PERFORM_ENTER_VT: - { - err = gralloc_drm_set_master(dmod->drm); - } - break; - case GRALLOC_MODULE_PERFORM_LEAVE_VT: - { - gralloc_drm_drop_master(dmod->drm); - err = 0; - } - break; - default: - err = -EINVAL; - break; - } - va_end(args); - - return err; -} - -static int drm_mod_register_buffer(const gralloc_module_t *mod, - buffer_handle_t handle) -{ - struct drm_module_t *dmod = (struct drm_module_t *) mod; - int err; - - err = drm_init(dmod); - if (err) - return err; - - return gralloc_drm_handle_register(handle, dmod->drm); -} - -static int drm_mod_unregister_buffer(const gralloc_module_t *mod, - buffer_handle_t handle) -{ - return gralloc_drm_handle_unregister(handle); -} - -static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle, - int usage, int x, int y, int w, int h, void **ptr) -{ - struct gralloc_drm_bo_t *bo; - int err; - - bo = gralloc_drm_bo_from_handle(handle); - if (!bo) - return -EINVAL; - - return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr); -} - -static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle) -{ - struct drm_module_t *dmod = (struct drm_module_t *) mod; - struct gralloc_drm_bo_t *bo; - - bo = gralloc_drm_bo_from_handle(handle); - if (!bo) - return -EINVAL; - - gralloc_drm_bo_unlock(bo); - - return 0; -} - -static int drm_mod_close_gpu0(struct hw_device_t *dev) -{ - struct alloc_device_t *alloc = (struct alloc_device_t *) dev; - - free(alloc); - - return 0; -} - -static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle) -{ - struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module; - struct gralloc_drm_bo_t *bo; - - bo = gralloc_drm_bo_from_handle(handle); - if (!bo) - return -EINVAL; - - gralloc_drm_bo_decref(bo); - - return 0; -} - -static int drm_mod_alloc_gpu0(alloc_device_t *dev, - int w, int h, int format, int usage, - buffer_handle_t *handle, int *stride) -{ - struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module; - struct gralloc_drm_bo_t *bo; - int size, bpp, err; - - bpp = gralloc_drm_get_bpp(format); - if (!bpp) - return -EINVAL; - - bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage); - if (!bo) - return -ENOMEM; - - *handle = gralloc_drm_bo_get_handle(bo, stride); - /* in pixels */ - *stride /= bpp; - - return 0; -} - -static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev) -{ - struct alloc_device_t *alloc; - int err; - - err = drm_init(dmod); - if (err) - return err; - - alloc = calloc(1, sizeof(*alloc)); - if (!alloc) - return -EINVAL; - - alloc->common.tag = HARDWARE_DEVICE_TAG; - alloc->common.version = 0; - alloc->common.module = &dmod->base.common; - alloc->common.close = drm_mod_close_gpu0; - - alloc->alloc = drm_mod_alloc_gpu0; - alloc->free = drm_mod_free_gpu0; - - *dev = &alloc->common; - - return 0; -} - -static int drm_mod_open(const struct hw_module_t *mod, - const char *name, struct hw_device_t **dev) -{ - struct drm_module_t *dmod = (struct drm_module_t *) mod; - int err; - - if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0) - err = drm_mod_open_gpu0(dmod, dev); - else - err = -EINVAL; - - return err; -} - -static struct hw_module_methods_t drm_mod_methods = { - .open = drm_mod_open -}; - -struct drm_module_t HAL_MODULE_INFO_SYM = { - .base = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = GRALLOC_HARDWARE_MODULE_ID, - .name = "DRM Memory Allocator", - .author = "Chia-I Wu", - .methods = &drm_mod_methods - }, - .registerBuffer = drm_mod_register_buffer, - .unregisterBuffer = drm_mod_unregister_buffer, - .lock = drm_mod_lock, - .unlock = drm_mod_unlock, - .perform = drm_mod_perform - }, - - .mutex = PTHREAD_MUTEX_INITIALIZER, - .drm = NULL -}; diff --git a/gralloc.cpp b/gralloc.cpp new file mode 100644 index 0000000..3c377c6 --- /dev/null +++ b/gralloc.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2010-2011 Chia-I Wu + * Copyright (C) 2010-2011 LunarG Inc. + * + * 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-MOD" + +#include +#include +#include +#include +#include + +#include "gralloc_drm.h" +#include "gralloc_drm_priv.h" + +/* + * Initialize the DRM device object + */ +static int drm_init(struct drm_module_t *dmod) +{ + int err = 0; + + pthread_mutex_lock(&dmod->mutex); + if (!dmod->drm) { + dmod->drm = gralloc_drm_create(); + if (!dmod->drm) + err = -EINVAL; + } + pthread_mutex_unlock(&dmod->mutex); + + return err; +} + +static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...) +{ + struct drm_module_t *dmod = (struct drm_module_t *) mod; + va_list args; + int err; + + err = drm_init(dmod); + if (err) + return err; + + va_start(args, op); + switch (op) { + case GRALLOC_MODULE_PERFORM_GET_DRM_FD: + { + int *fd = va_arg(args, int *); + *fd = gralloc_drm_get_fd(dmod->drm); + err = 0; + } + break; + /* should we remove this and next ops, and make it transparent? */ + case GRALLOC_MODULE_PERFORM_GET_DRM_MAGIC: + { + int32_t *magic = va_arg(args, int32_t *); + err = gralloc_drm_get_magic(dmod->drm, magic); + } + break; + case GRALLOC_MODULE_PERFORM_AUTH_DRM_MAGIC: + { + int32_t magic = va_arg(args, int32_t); + err = gralloc_drm_auth_magic(dmod->drm, magic); + } + break; + case GRALLOC_MODULE_PERFORM_ENTER_VT: + { + err = gralloc_drm_set_master(dmod->drm); + } + break; + case GRALLOC_MODULE_PERFORM_LEAVE_VT: + { + gralloc_drm_drop_master(dmod->drm); + err = 0; + } + break; + default: + err = -EINVAL; + break; + } + va_end(args); + + return err; +} + +static int drm_mod_register_buffer(const gralloc_module_t *mod, + buffer_handle_t handle) +{ + struct drm_module_t *dmod = (struct drm_module_t *) mod; + int err; + + err = drm_init(dmod); + if (err) + return err; + + return gralloc_drm_handle_register(handle, dmod->drm); +} + +static int drm_mod_unregister_buffer(const gralloc_module_t *mod, + buffer_handle_t handle) +{ + return gralloc_drm_handle_unregister(handle); +} + +static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle, + int usage, int x, int y, int w, int h, void **ptr) +{ + struct gralloc_drm_bo_t *bo; + int err; + + bo = gralloc_drm_bo_from_handle(handle); + if (!bo) + return -EINVAL; + + return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr); +} + +static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle) +{ + struct drm_module_t *dmod = (struct drm_module_t *) mod; + struct gralloc_drm_bo_t *bo; + + bo = gralloc_drm_bo_from_handle(handle); + if (!bo) + return -EINVAL; + + gralloc_drm_bo_unlock(bo); + + return 0; +} + +static int drm_mod_close_gpu0(struct hw_device_t *dev) +{ + struct alloc_device_t *alloc = (struct alloc_device_t *) dev; + + delete alloc; + + return 0; +} + +static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle) +{ + struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module; + struct gralloc_drm_bo_t *bo; + + bo = gralloc_drm_bo_from_handle(handle); + if (!bo) + return -EINVAL; + + gralloc_drm_bo_decref(bo); + + return 0; +} + +static int drm_mod_alloc_gpu0(alloc_device_t *dev, + int w, int h, int format, int usage, + buffer_handle_t *handle, int *stride) +{ + struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module; + struct gralloc_drm_bo_t *bo; + int size, bpp, err; + + bpp = gralloc_drm_get_bpp(format); + if (!bpp) + return -EINVAL; + + bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage); + if (!bo) + return -ENOMEM; + + *handle = gralloc_drm_bo_get_handle(bo, stride); + /* in pixels */ + *stride /= bpp; + + return 0; +} + +static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev) +{ + struct alloc_device_t *alloc; + int err; + + err = drm_init(dmod); + if (err) + return err; + + alloc = new alloc_device_t; + if (!alloc) + return -EINVAL; + + alloc->common.tag = HARDWARE_DEVICE_TAG; + alloc->common.version = 0; + alloc->common.module = &dmod->base.common; + alloc->common.close = drm_mod_close_gpu0; + + alloc->alloc = drm_mod_alloc_gpu0; + alloc->free = drm_mod_free_gpu0; + + *dev = &alloc->common; + + return 0; +} + +static int drm_mod_open(const struct hw_module_t *mod, + const char *name, struct hw_device_t **dev) +{ + struct drm_module_t *dmod = (struct drm_module_t *) mod; + int err; + + if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0) + err = drm_mod_open_gpu0(dmod, dev); + else + err = -EINVAL; + + return err; +} + +static struct hw_module_methods_t drm_mod_methods = { + .open = drm_mod_open +}; + +struct drm_module_t HAL_MODULE_INFO_SYM = { + .base = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = GRALLOC_HARDWARE_MODULE_ID, + .name = "DRM Memory Allocator", + .author = "Chia-I Wu", + .methods = &drm_mod_methods + }, + .registerBuffer = drm_mod_register_buffer, + .unregisterBuffer = drm_mod_unregister_buffer, + .lock = drm_mod_lock, + .unlock = drm_mod_unlock, + .perform = drm_mod_perform + }, + + .mutex = PTHREAD_MUTEX_INITIALIZER, + .drm = NULL +}; diff --git a/gralloc_drm.c b/gralloc_drm.c deleted file mode 100644 index e74b423..0000000 --- a/gralloc_drm.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Copyright (C) 2010-2011 Chia-I Wu - * Copyright (C) 2010-2011 LunarG Inc. - * - * 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-DRM" - -#include -#include -#include -#include -#include -#include -#include - -#include "gralloc_drm.h" -#include "gralloc_drm_priv.h" - -#define unlikely(x) __builtin_expect(!!(x), 0) - -#define GRALLOC_DRM_DEVICE "/dev/dri/card0" - -static int32_t gralloc_drm_pid = 0; - -/* - * Return the pid of the process. - */ -static int gralloc_drm_get_pid(void) -{ - if (unlikely(!gralloc_drm_pid)) - android_atomic_write((int32_t) getpid(), &gralloc_drm_pid); - - return gralloc_drm_pid; -} - -/* - * Create the driver for a DRM fd. - */ -static struct gralloc_drm_drv_t * -init_drv_from_fd(int fd) -{ - struct gralloc_drm_drv_t *drv = NULL; - drmVersionPtr version; - - /* get the kernel module name */ - version = drmGetVersion(fd); - if (!version) { - ALOGE("invalid DRM fd"); - return NULL; - } - - if (version->name) { -#ifdef ENABLE_PIPE - drv = gralloc_drm_drv_create_for_pipe(fd, version->name); -#endif - -#ifdef ENABLE_INTEL - if (!drv && !strcmp(version->name, "i915")) - drv = gralloc_drm_drv_create_for_intel(fd); -#endif -#ifdef ENABLE_RADEON - if (!drv && !strcmp(version->name, "radeon")) - drv = gralloc_drm_drv_create_for_radeon(fd); -#endif -#ifdef ENABLE_NOUVEAU - if (!drv && !strcmp(version->name, "nouveau")) - drv = gralloc_drm_drv_create_for_nouveau(fd); -#endif - } - - if (!drv) { - ALOGE("unsupported driver: %s", (version->name) ? - version->name : "NULL"); - } - - drmFreeVersion(version); - - return drv; -} - -/* - * Create a DRM device object. - */ -struct gralloc_drm_t *gralloc_drm_create(void) -{ - struct gralloc_drm_t *drm; - int err; - - drm = calloc(1, sizeof(*drm)); - if (!drm) - return NULL; - - drm->fd = open(GRALLOC_DRM_DEVICE, O_RDWR); - if (drm->fd < 0) { - ALOGE("failed to open %s", GRALLOC_DRM_DEVICE); - return NULL; - } - - drm->drv = init_drv_from_fd(drm->fd); - if (!drm->drv) { - close(drm->fd); - free(drm); - return NULL; - } - - return drm; -} - -/* - * Destroy a DRM device object. - */ -void gralloc_drm_destroy(struct gralloc_drm_t *drm) -{ - if (drm->drv) - drm->drv->destroy(drm->drv); - close(drm->fd); - free(drm); -} - -/* - * Get the file descriptor of a DRM device object. - */ -int gralloc_drm_get_fd(struct gralloc_drm_t *drm) -{ - return drm->fd; -} - -/* - * Get the magic for authentication. - */ -int gralloc_drm_get_magic(struct gralloc_drm_t *drm, int32_t *magic) -{ - return drmGetMagic(drm->fd, (drm_magic_t *) magic); -} - -/* - * Authenticate a magic. - */ -int gralloc_drm_auth_magic(struct gralloc_drm_t *drm, int32_t magic) -{ - return drmAuthMagic(drm->fd, (drm_magic_t) magic); -} - -/* - * Set as the master of a DRM device. - */ -int gralloc_drm_set_master(struct gralloc_drm_t *drm) -{ - ALOGD("set master"); - drmSetMaster(drm->fd); - drm->first_post = 1; - - return 0; -} - -/* - * Drop from the master of a DRM device. - */ -void gralloc_drm_drop_master(struct gralloc_drm_t *drm) -{ - drmDropMaster(drm->fd); -} - -/* - * Validate a buffer handle and return the associated bo. - */ -static struct gralloc_drm_bo_t *validate_handle(buffer_handle_t _handle, - struct gralloc_drm_t *drm) -{ - struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); - - if (!handle) - return NULL; - - /* the buffer handle is passed to a new process */ - if (unlikely(handle->data_owner != gralloc_drm_pid)) { - struct gralloc_drm_bo_t *bo; - - /* check only */ - if (!drm) - return NULL; - - /* create the struct gralloc_drm_bo_t locally */ - if (handle->name) - bo = drm->drv->alloc(drm->drv, handle); - else /* an invalid handle */ - bo = NULL; - if (bo) { - bo->drm = drm; - bo->imported = 1; - bo->handle = handle; - bo->refcount = 1; - } - - handle->data_owner = gralloc_drm_get_pid(); - handle->data = bo; - } - - return handle->data; -} - -/* - * Register a buffer handle. - */ -int gralloc_drm_handle_register(buffer_handle_t handle, struct gralloc_drm_t *drm) -{ - return (validate_handle(handle, drm)) ? 0 : -EINVAL; -} - -/* - * Unregister a buffer handle. It is no-op for handles created locally. - */ -int gralloc_drm_handle_unregister(buffer_handle_t handle) -{ - struct gralloc_drm_bo_t *bo; - - bo = validate_handle(handle, NULL); - if (!bo) - return -EINVAL; - - if (bo->imported) - gralloc_drm_bo_decref(bo); - - return 0; -} - -/* - * Create a buffer handle. - */ -static struct gralloc_drm_handle_t *create_bo_handle(int width, - int height, int format, int usage) -{ - struct gralloc_drm_handle_t *handle; - - handle = calloc(1, sizeof(*handle)); - if (!handle) - return NULL; - - handle->base.version = sizeof(handle->base); - handle->base.numInts = GRALLOC_DRM_HANDLE_NUM_INTS; - handle->base.numFds = GRALLOC_DRM_HANDLE_NUM_FDS; - - handle->magic = GRALLOC_DRM_HANDLE_MAGIC; - handle->width = width; - handle->height = height; - handle->format = format; - handle->usage = usage; - - return handle; -} - -/* - * Create a bo. - */ -struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, - int width, int height, int format, int usage) -{ - struct gralloc_drm_bo_t *bo; - struct gralloc_drm_handle_t *handle; - - handle = create_bo_handle(width, height, format, usage); - if (!handle) - return NULL; - - bo = drm->drv->alloc(drm->drv, handle); - if (!bo) { - free(handle); - return NULL; - } - - bo->drm = drm; - bo->imported = 0; - bo->handle = handle; - bo->fb_id = 0; - bo->refcount = 1; - - handle->data_owner = gralloc_drm_get_pid(); - handle->data = bo; - - return bo; -} - -/* - * Destroy a bo. - */ -static void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) -{ - struct gralloc_drm_handle_t *handle = bo->handle; - int imported = bo->imported; - - /* gralloc still has a reference */ - if (bo->refcount) - return; - - bo->drm->drv->free(bo->drm->drv, bo); - if (imported) { - handle->data_owner = 0; - handle->data = 0; - } - else { - free(handle); - } -} - -/* - * Decrease refcount, if no refs anymore then destroy. - */ -void gralloc_drm_bo_decref(struct gralloc_drm_bo_t *bo) -{ - if (!--bo->refcount) - gralloc_drm_bo_destroy(bo); -} - -/* - * Return the bo of a registered handle. - */ -struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle) -{ - return validate_handle(handle, NULL); -} - -/* - * Get the buffer handle and stride of a bo. - */ -buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stride) -{ - if (stride) - *stride = bo->handle->stride; - return &bo->handle->base; -} - -int gralloc_drm_get_gem_handle(buffer_handle_t _handle) -{ - struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); - return (handle) ? handle->name : 0; -} - -/* - * Query YUV component offsets for a buffer handle - */ -void gralloc_drm_resolve_format(buffer_handle_t _handle, - uint32_t *pitches, uint32_t *offsets, uint32_t *handles) -{ - struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); - struct gralloc_drm_bo_t *bo = handle->data; - struct gralloc_drm_t *drm = bo->drm; - - /* if handle exists and driver implements resolve_format */ - if (handle && drm->drv->resolve_format) - drm->drv->resolve_format(drm->drv, bo, - pitches, offsets, handles); -} - -/* - * Lock a bo. XXX thread-safety? - */ -int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo, - int usage, int x, int y, int w, int h, - void **addr) -{ - if ((bo->handle->usage & usage) != usage) { - /* make FB special for testing software renderer with */ - - if (!(bo->handle->usage & GRALLOC_USAGE_HW_FB) - && !(bo->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" - ,bo->handle->usage,usage); - return -EINVAL; - } - } - - /* allow multiple locks with compatible usages */ - if (bo->lock_count && (bo->locked_for & usage) != usage) - return -EINVAL; - - usage |= bo->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 = bo->drm->drv->map(bo->drm->drv, bo, - x, y, w, h, write, addr); - if (err) - return err; - } - else { - /* kernel handles the synchronization here */ - } - - bo->lock_count++; - bo->locked_for |= usage; - - return 0; -} - -/* - * Unlock a bo. - */ -void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo) -{ - int mapped = bo->locked_for & - (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK); - - if (!bo->lock_count) - return; - - if (mapped) - bo->drm->drv->unmap(bo->drm->drv, bo); - - bo->lock_count--; - if (!bo->lock_count) - bo->locked_for = 0; -} diff --git a/gralloc_drm.cpp b/gralloc_drm.cpp new file mode 100644 index 0000000..8826f73 --- /dev/null +++ b/gralloc_drm.cpp @@ -0,0 +1,432 @@ +/* + * Copyright (C) 2010-2011 Chia-I Wu + * Copyright (C) 2010-2011 LunarG Inc. + * + * 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-DRM" + +#include +#include +#include +#include +#include +#include +#include + +#include "gralloc_drm.h" +#include "gralloc_drm_priv.h" + +#define unlikely(x) __builtin_expect(!!(x), 0) + +#define GRALLOC_DRM_DEVICE "/dev/dri/card0" + +static int32_t gralloc_drm_pid = 0; + +/* + * Return the pid of the process. + */ +static int gralloc_drm_get_pid(void) +{ + if (unlikely(!gralloc_drm_pid)) + android_atomic_write((int32_t) getpid(), &gralloc_drm_pid); + + return gralloc_drm_pid; +} + +/* + * Create the driver for a DRM fd. + */ +static struct gralloc_drm_drv_t * +init_drv_from_fd(int fd) +{ + struct gralloc_drm_drv_t *drv = NULL; + drmVersionPtr version; + + /* get the kernel module name */ + version = drmGetVersion(fd); + if (!version) { + ALOGE("invalid DRM fd"); + return NULL; + } + + if (version->name) { +#ifdef ENABLE_PIPE + drv = gralloc_drm_drv_create_for_pipe(fd, version->name); +#endif + +#ifdef ENABLE_INTEL + if (!drv && !strcmp(version->name, "i915")) + drv = gralloc_drm_drv_create_for_intel(fd); +#endif +#ifdef ENABLE_RADEON + if (!drv && !strcmp(version->name, "radeon")) + drv = gralloc_drm_drv_create_for_radeon(fd); +#endif +#ifdef ENABLE_NOUVEAU + if (!drv && !strcmp(version->name, "nouveau")) + drv = gralloc_drm_drv_create_for_nouveau(fd); +#endif + } + + if (!drv) { + ALOGE("unsupported driver: %s", (version->name) ? + version->name : "NULL"); + } + + drmFreeVersion(version); + + return drv; +} + +/* + * Create a DRM device object. + */ +struct gralloc_drm_t *gralloc_drm_create(void) +{ + struct gralloc_drm_t *drm; + int err; + + drm = new gralloc_drm_t; + if (!drm) + return NULL; + + drm->fd = open(GRALLOC_DRM_DEVICE, O_RDWR); + if (drm->fd < 0) { + ALOGE("failed to open %s", GRALLOC_DRM_DEVICE); + return NULL; + } + + drm->drv = init_drv_from_fd(drm->fd); + if (!drm->drv) { + close(drm->fd); + delete drm; + return NULL; + } + + return drm; +} + +/* + * Destroy a DRM device object. + */ +void gralloc_drm_destroy(struct gralloc_drm_t *drm) +{ + if (drm->drv) + drm->drv->destroy(drm->drv); + close(drm->fd); + delete drm; +} + +/* + * Get the file descriptor of a DRM device object. + */ +int gralloc_drm_get_fd(struct gralloc_drm_t *drm) +{ + return drm->fd; +} + +/* + * Get the magic for authentication. + */ +int gralloc_drm_get_magic(struct gralloc_drm_t *drm, int32_t *magic) +{ + return drmGetMagic(drm->fd, (drm_magic_t *) magic); +} + +/* + * Authenticate a magic. + */ +int gralloc_drm_auth_magic(struct gralloc_drm_t *drm, int32_t magic) +{ + return drmAuthMagic(drm->fd, (drm_magic_t) magic); +} + +/* + * Set as the master of a DRM device. + */ +int gralloc_drm_set_master(struct gralloc_drm_t *drm) +{ + ALOGD("set master"); + drmSetMaster(drm->fd); + drm->first_post = 1; + + return 0; +} + +/* + * Drop from the master of a DRM device. + */ +void gralloc_drm_drop_master(struct gralloc_drm_t *drm) +{ + drmDropMaster(drm->fd); +} + +/* + * Validate a buffer handle and return the associated bo. + */ +static struct gralloc_drm_bo_t *validate_handle(buffer_handle_t _handle, + struct gralloc_drm_t *drm) +{ + struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); + + if (!handle) + return NULL; + + /* the buffer handle is passed to a new process */ + if (unlikely(handle->data_owner != gralloc_drm_pid)) { + struct gralloc_drm_bo_t *bo; + + /* check only */ + if (!drm) + return NULL; + + /* create the struct gralloc_drm_bo_t locally */ + if (handle->name) + bo = drm->drv->alloc(drm->drv, handle); + else /* an invalid handle */ + bo = NULL; + if (bo) { + bo->drm = drm; + bo->imported = 1; + bo->handle = handle; + bo->refcount = 1; + } + + handle->data_owner = gralloc_drm_get_pid(); + handle->data = bo; + } + + return handle->data; +} + +/* + * Register a buffer handle. + */ +int gralloc_drm_handle_register(buffer_handle_t handle, struct gralloc_drm_t *drm) +{ + return (validate_handle(handle, drm)) ? 0 : -EINVAL; +} + +/* + * Unregister a buffer handle. It is no-op for handles created locally. + */ +int gralloc_drm_handle_unregister(buffer_handle_t handle) +{ + struct gralloc_drm_bo_t *bo; + + bo = validate_handle(handle, NULL); + if (!bo) + return -EINVAL; + + if (bo->imported) + gralloc_drm_bo_decref(bo); + + return 0; +} + +/* + * Create a buffer handle. + */ +static struct gralloc_drm_handle_t *create_bo_handle(int width, + int height, int format, int usage) +{ + struct gralloc_drm_handle_t *handle; + + handle = new gralloc_drm_handle_t; + if (!handle) + return NULL; + + handle->base.version = sizeof(handle->base); + handle->base.numInts = GRALLOC_DRM_HANDLE_NUM_INTS; + handle->base.numFds = GRALLOC_DRM_HANDLE_NUM_FDS; + + handle->magic = GRALLOC_DRM_HANDLE_MAGIC; + handle->width = width; + handle->height = height; + handle->format = format; + handle->usage = usage; + + return handle; +} + +/* + * Create a bo. + */ +struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, + int width, int height, int format, int usage) +{ + struct gralloc_drm_bo_t *bo; + struct gralloc_drm_handle_t *handle; + + handle = create_bo_handle(width, height, format, usage); + if (!handle) + return NULL; + + bo = drm->drv->alloc(drm->drv, handle); + if (!bo) { + delete handle; + return NULL; + } + + bo->drm = drm; + bo->imported = 0; + bo->handle = handle; + bo->fb_id = 0; + bo->refcount = 1; + + handle->data_owner = gralloc_drm_get_pid(); + handle->data = bo; + + return bo; +} + +/* + * Destroy a bo. + */ +static void gralloc_drm_bo_destroy(struct gralloc_drm_bo_t *bo) +{ + struct gralloc_drm_handle_t *handle = bo->handle; + int imported = bo->imported; + + /* gralloc still has a reference */ + if (bo->refcount) + return; + + bo->drm->drv->free(bo->drm->drv, bo); + if (imported) { + handle->data_owner = 0; + handle->data = 0; + } + else { + delete handle; + } +} + +/* + * Decrease refcount, if no refs anymore then destroy. + */ +void gralloc_drm_bo_decref(struct gralloc_drm_bo_t *bo) +{ + if (!--bo->refcount) + gralloc_drm_bo_destroy(bo); +} + +/* + * Return the bo of a registered handle. + */ +struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle) +{ + return validate_handle(handle, NULL); +} + +/* + * Get the buffer handle and stride of a bo. + */ +buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stride) +{ + if (stride) + *stride = bo->handle->stride; + return &bo->handle->base; +} + +int gralloc_drm_get_gem_handle(buffer_handle_t _handle) +{ + struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); + return (handle) ? handle->name : 0; +} + +/* + * Query YUV component offsets for a buffer handle + */ +void gralloc_drm_resolve_format(buffer_handle_t _handle, + uint32_t *pitches, uint32_t *offsets, uint32_t *handles) +{ + struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); + struct gralloc_drm_bo_t *bo = handle->data; + struct gralloc_drm_t *drm = bo->drm; + + /* if handle exists and driver implements resolve_format */ + if (handle && drm->drv->resolve_format) + drm->drv->resolve_format(drm->drv, bo, + pitches, offsets, handles); +} + +/* + * Lock a bo. XXX thread-safety? + */ +int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo, + int usage, int x, int y, int w, int h, + void **addr) +{ + if ((bo->handle->usage & usage) != usage) { + /* make FB special for testing software renderer with */ + + if (!(bo->handle->usage & GRALLOC_USAGE_HW_FB) + && !(bo->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" + ,bo->handle->usage,usage); + return -EINVAL; + } + } + + /* allow multiple locks with compatible usages */ + if (bo->lock_count && (bo->locked_for & usage) != usage) + return -EINVAL; + + usage |= bo->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 = bo->drm->drv->map(bo->drm->drv, bo, + x, y, w, h, write, addr); + if (err) + return err; + } + else { + /* kernel handles the synchronization here */ + } + + bo->lock_count++; + bo->locked_for |= usage; + + return 0; +} + +/* + * Unlock a bo. + */ +void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo) +{ + int mapped = bo->locked_for & + (GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_SW_READ_MASK); + + if (!bo->lock_count) + return; + + if (mapped) + bo->drm->drv->unmap(bo->drm->drv, bo); + + bo->lock_count--; + if (!bo->lock_count) + bo->locked_for = 0; +} -- cgit v1.2.3