Home | History | Annotate | Download | only in drm_gralloc
      1 /*
      2  * Copyright (C) 2010-2011 Chia-I Wu <olvaffe (at) gmail.com>
      3  * Copyright (C) 2010-2011 LunarG Inc.
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the "Software"),
      7  * to deal in the Software without restriction, including without limitation
      8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      9  * and/or sell copies of the Software, and to permit persons to whom the
     10  * Software is furnished to do so, subject to the following conditions:
     11  *
     12  * The above copyright notice and this permission notice shall be included
     13  * in all copies or substantial portions of the Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  */
     23 
     24 #define LOG_TAG "GRALLOC-MOD"
     25 
     26 #include <cutils/log.h>
     27 #include <stdlib.h>
     28 #include <stdarg.h>
     29 #include <pthread.h>
     30 #include <errno.h>
     31 
     32 #include "gralloc_drm.h"
     33 #include "gralloc_drm_priv.h"
     34 
     35 /*
     36  * Initialize the DRM device object
     37  */
     38 static int drm_init(struct drm_module_t *dmod)
     39 {
     40 	int err = 0;
     41 
     42 	pthread_mutex_lock(&dmod->mutex);
     43 	if (!dmod->drm) {
     44 		dmod->drm = gralloc_drm_create();
     45 		if (!dmod->drm)
     46 			err = -EINVAL;
     47 	}
     48 	pthread_mutex_unlock(&dmod->mutex);
     49 
     50 	return err;
     51 }
     52 
     53 static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...)
     54 {
     55 	struct drm_module_t *dmod = (struct drm_module_t *) mod;
     56 	va_list args;
     57 	int err;
     58 
     59 	err = drm_init(dmod);
     60 	if (err)
     61 		return err;
     62 
     63 	va_start(args, op);
     64 	switch (op) {
     65 	case GRALLOC_MODULE_PERFORM_GET_DRM_FD:
     66 		{
     67 			int *fd = va_arg(args, int *);
     68 			*fd = gralloc_drm_get_fd(dmod->drm);
     69 			err = 0;
     70 		}
     71 		break;
     72 	default:
     73 		err = -EINVAL;
     74 		break;
     75 	}
     76 	va_end(args);
     77 
     78 	return err;
     79 }
     80 
     81 static int drm_mod_register_buffer(const gralloc_module_t *mod,
     82 		buffer_handle_t handle)
     83 {
     84 	struct drm_module_t *dmod = (struct drm_module_t *) mod;
     85 	int err;
     86 
     87 	err = drm_init(dmod);
     88 	if (err)
     89 		return err;
     90 
     91 	return gralloc_drm_handle_register(handle, dmod->drm);
     92 }
     93 
     94 static int drm_mod_unregister_buffer(const gralloc_module_t *mod,
     95 		buffer_handle_t handle)
     96 {
     97 	return gralloc_drm_handle_unregister(handle);
     98 }
     99 
    100 static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle,
    101 		int usage, int x, int y, int w, int h, void **ptr)
    102 {
    103 	struct gralloc_drm_bo_t *bo;
    104 	int err;
    105 
    106 	bo = gralloc_drm_bo_from_handle(handle);
    107 	if (!bo)
    108 		return -EINVAL;
    109 
    110 	return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr);
    111 }
    112 
    113 static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
    114 {
    115 	struct drm_module_t *dmod = (struct drm_module_t *) mod;
    116 	struct gralloc_drm_bo_t *bo;
    117 
    118 	bo = gralloc_drm_bo_from_handle(handle);
    119 	if (!bo)
    120 		return -EINVAL;
    121 
    122 	gralloc_drm_bo_unlock(bo);
    123 
    124 	return 0;
    125 }
    126 
    127 static int drm_mod_close_gpu0(struct hw_device_t *dev)
    128 {
    129 	struct drm_module_t *dmod = (struct drm_module_t *)dev->module;
    130 	struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
    131 
    132 	gralloc_drm_destroy(dmod->drm);
    133 	delete alloc;
    134 
    135 	return 0;
    136 }
    137 
    138 static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
    139 {
    140 	struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
    141 	struct gralloc_drm_bo_t *bo;
    142 
    143 	bo = gralloc_drm_bo_from_handle(handle);
    144 	if (!bo)
    145 		return -EINVAL;
    146 
    147 	gralloc_drm_bo_decref(bo);
    148 
    149 	return 0;
    150 }
    151 
    152 static int drm_mod_alloc_gpu0(alloc_device_t *dev,
    153 		int w, int h, int format, int usage,
    154 		buffer_handle_t *handle, int *stride)
    155 {
    156 	struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
    157 	struct gralloc_drm_bo_t *bo;
    158 	int size, bpp, err;
    159 
    160 	bpp = gralloc_drm_get_bpp(format);
    161 	if (!bpp)
    162 		return -EINVAL;
    163 
    164 	bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage);
    165 	if (!bo)
    166 		return -ENOMEM;
    167 
    168 	*handle = gralloc_drm_bo_get_handle(bo, stride);
    169 	/* in pixels */
    170 	*stride /= bpp;
    171 
    172 	return 0;
    173 }
    174 
    175 static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev)
    176 {
    177 	struct alloc_device_t *alloc;
    178 	int err;
    179 
    180 	err = drm_init(dmod);
    181 	if (err)
    182 		return err;
    183 
    184 	alloc = new alloc_device_t;
    185 	if (!alloc)
    186 		return -EINVAL;
    187 
    188 	alloc->common.tag = HARDWARE_DEVICE_TAG;
    189 	alloc->common.version = 0;
    190 	alloc->common.module = &dmod->base.common;
    191 	alloc->common.close = drm_mod_close_gpu0;
    192 
    193 	alloc->alloc = drm_mod_alloc_gpu0;
    194 	alloc->free = drm_mod_free_gpu0;
    195 
    196 	*dev = &alloc->common;
    197 
    198 	return 0;
    199 }
    200 
    201 static int drm_mod_open(const struct hw_module_t *mod,
    202 		const char *name, struct hw_device_t **dev)
    203 {
    204 	struct drm_module_t *dmod = (struct drm_module_t *) mod;
    205 	int err;
    206 
    207 	if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
    208 		err = drm_mod_open_gpu0(dmod, dev);
    209 	else
    210 		err = -EINVAL;
    211 
    212 	return err;
    213 }
    214 
    215 static struct hw_module_methods_t drm_mod_methods = {
    216 	.open = drm_mod_open
    217 };
    218 
    219 struct drm_module_t HAL_MODULE_INFO_SYM = {
    220 	.base = {
    221 		.common = {
    222 			.tag = HARDWARE_MODULE_TAG,
    223 			.version_major = 1,
    224 			.version_minor = 0,
    225 			.id = GRALLOC_HARDWARE_MODULE_ID,
    226 			.name = "DRM Memory Allocator",
    227 			.author = "Chia-I Wu",
    228 			.methods = &drm_mod_methods
    229 		},
    230 		.registerBuffer = drm_mod_register_buffer,
    231 		.unregisterBuffer = drm_mod_unregister_buffer,
    232 		.lock = drm_mod_lock,
    233 		.unlock = drm_mod_unlock,
    234 		.perform = drm_mod_perform
    235 	},
    236 
    237 	.mutex = PTHREAD_MUTEX_INITIALIZER,
    238 	.drm = NULL
    239 };
    240