summaryrefslogtreecommitdiff
path: root/gralloc/gralloc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gralloc/gralloc.cpp')
-rw-r--r--gralloc/gralloc.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/gralloc/gralloc.cpp b/gralloc/gralloc.cpp
new file mode 100644
index 0000000..2753ee9
--- /dev/null
+++ b/gralloc/gralloc.cpp
@@ -0,0 +1,259 @@
+/*
+ * 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 <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+
+#include <hardware/gralloc.h>
+#include <system/graphics.h>
+
+#include <gbm.h>
+
+#include "gralloc_drm.h"
+#include "gralloc_gbm_priv.h"
+
+struct gbm_module_t {
+ gralloc_module_t base;
+
+ pthread_mutex_t mutex;
+ struct gbm_device *gbm;
+};
+
+/*
+ * Initialize the DRM device object
+ */
+static int gbm_init(struct gbm_module_t *dmod)
+{
+ int err = 0;
+
+ pthread_mutex_lock(&dmod->mutex);
+ if (!dmod->gbm) {
+ dmod->gbm = gbm_dev_create();
+ if (!dmod->gbm)
+ err = -EINVAL;
+ }
+ pthread_mutex_unlock(&dmod->mutex);
+
+ return err;
+}
+
+static int gbm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
+ va_list args;
+ int err;
+ uint32_t uop = static_cast<uint32_t>(op);
+
+ err = gbm_init(dmod);
+ if (err)
+ return err;
+
+ va_start(args, op);
+ switch (uop) {
+ case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
+ {
+ int *fd = va_arg(args, int *);
+ *fd = gbm_device_get_fd(dmod->gbm);
+ err = 0;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ va_end(args);
+
+ return err;
+}
+
+static int gbm_mod_register_buffer(const gralloc_module_t *mod,
+ buffer_handle_t handle)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
+ int err;
+
+ err = gbm_init(dmod);
+ if (err)
+ return err;
+
+ pthread_mutex_lock(&dmod->mutex);
+ err = gralloc_gbm_handle_register(handle, dmod->gbm);
+ pthread_mutex_unlock(&dmod->mutex);
+
+ return err;
+}
+
+static int gbm_mod_unregister_buffer(const gralloc_module_t *mod,
+ buffer_handle_t handle)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
+ int err;
+
+ pthread_mutex_lock(&dmod->mutex);
+ err = gralloc_gbm_handle_unregister(handle);
+ pthread_mutex_unlock(&dmod->mutex);
+
+ return err;
+}
+
+static int gbm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
+ int usage, int x, int y, int w, int h, void **ptr)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
+ int err;
+
+ pthread_mutex_lock(&dmod->mutex);
+
+ err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, ptr);
+ ALOGV("buffer %p lock usage = %08x", handle, usage);
+
+ pthread_mutex_unlock(&dmod->mutex);
+ return err;
+}
+
+static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
+ int err;
+
+ pthread_mutex_lock(&dmod->mutex);
+ err = gralloc_gbm_bo_unlock(handle);
+ pthread_mutex_unlock(&dmod->mutex);
+
+ return err;
+}
+
+static int gbm_mod_close_gpu0(struct hw_device_t *dev)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module;
+ struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
+
+ gbm_dev_destroy(dmod->gbm);
+ delete alloc;
+
+ return 0;
+}
+
+static int gbm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
+
+ pthread_mutex_lock(&dmod->mutex);
+ gbm_free(handle);
+ native_handle_close(handle);
+ delete handle;
+
+ pthread_mutex_unlock(&dmod->mutex);
+ return 0;
+}
+
+static int gbm_mod_alloc_gpu0(alloc_device_t *dev,
+ int w, int h, int format, int usage,
+ buffer_handle_t *handle, int *stride)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) dev->common.module;
+ int err = 0;
+
+ pthread_mutex_lock(&dmod->mutex);
+
+ *handle = gralloc_gbm_bo_create(dmod->gbm, w, h, format, usage, stride);
+ if (!*handle)
+ err = -errno;
+
+ ALOGV("buffer %p usage = %08x", *handle, usage);
+ pthread_mutex_unlock(&dmod->mutex);
+ return err;
+}
+
+static int gbm_mod_open_gpu0(struct gbm_module_t *dmod, hw_device_t **dev)
+{
+ struct alloc_device_t *alloc;
+ int err;
+
+ err = gbm_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 = gbm_mod_close_gpu0;
+
+ alloc->alloc = gbm_mod_alloc_gpu0;
+ alloc->free = gbm_mod_free_gpu0;
+
+ *dev = &alloc->common;
+
+ return 0;
+}
+
+static int gbm_mod_open(const struct hw_module_t *mod,
+ const char *name, struct hw_device_t **dev)
+{
+ struct gbm_module_t *dmod = (struct gbm_module_t *) mod;
+ int err;
+
+ if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
+ err = gbm_mod_open_gpu0(dmod, dev);
+ else
+ err = -EINVAL;
+
+ return err;
+}
+
+static struct hw_module_methods_t gbm_mod_methods = {
+ .open = gbm_mod_open
+};
+
+struct gbm_module_t HAL_MODULE_INFO_SYM = {
+ .base = {
+ .common = {
+ .tag = HARDWARE_MODULE_TAG,
+ .version_major = 1,
+ .version_minor = 0,
+ .id = GRALLOC_HARDWARE_MODULE_ID,
+ .name = "GBM Memory Allocator",
+ .author = "Rob Herring - Linaro",
+ .methods = &gbm_mod_methods
+ },
+ .registerBuffer = gbm_mod_register_buffer,
+ .unregisterBuffer = gbm_mod_unregister_buffer,
+ .lock = gbm_mod_lock,
+ .unlock = gbm_mod_unlock,
+ .perform = gbm_mod_perform
+ },
+
+ .mutex = PTHREAD_MUTEX_INITIALIZER,
+ .gbm = NULL,
+};