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 static_cast<int>(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_lock_ycbcr(const gralloc_module_t *mod, buffer_handle_t bhandle,
    114 		int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr)
    115 {
    116 	struct gralloc_drm_handle_t *handle;
    117 	struct gralloc_drm_bo_t *bo;
    118 	void *ptr;
    119 	int err;
    120 
    121 	bo = gralloc_drm_bo_from_handle(bhandle);
    122 	if (!bo)
    123 		return -EINVAL;
    124 	handle = bo->handle;
    125 
    126 	switch(handle->format) {
    127 	case HAL_PIXEL_FORMAT_YCbCr_420_888:
    128 		break;
    129 	default:
    130 		return -EINVAL;
    131 	}
    132 
    133 	err = gralloc_drm_bo_lock(bo, usage, x, y, w, h, &ptr);
    134 	if (err)
    135 		return err;
    136 
    137 	switch(handle->format) {
    138 	case HAL_PIXEL_FORMAT_YCbCr_420_888:
    139 		ycbcr->y = ptr;
    140 		ycbcr->cb = (uint8_t *)ptr + handle->stride * handle->height;
    141 		ycbcr->cr = (uint8_t *)ycbcr->cb + 1;
    142 		ycbcr->ystride = handle->stride;
    143 		ycbcr->cstride = handle->stride;
    144 		ycbcr->chroma_step = 2;
    145 		break;
    146 	default:
    147 		break;
    148 	}
    149 
    150 	return 0;
    151 }
    152 
    153 static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle)
    154 {
    155 	struct drm_module_t *dmod = (struct drm_module_t *) mod;
    156 	struct gralloc_drm_bo_t *bo;
    157 
    158 	bo = gralloc_drm_bo_from_handle(handle);
    159 	if (!bo)
    160 		return -EINVAL;
    161 
    162 	gralloc_drm_bo_unlock(bo);
    163 
    164 	return 0;
    165 }
    166 
    167 static int drm_mod_close_gpu0(struct hw_device_t *dev)
    168 {
    169 	struct drm_module_t *dmod = (struct drm_module_t *)dev->module;
    170 	struct alloc_device_t *alloc = (struct alloc_device_t *) dev;
    171 
    172 	gralloc_drm_destroy(dmod->drm);
    173 	delete alloc;
    174 
    175 	return 0;
    176 }
    177 
    178 static int drm_mod_free_gpu0(alloc_device_t *dev, buffer_handle_t handle)
    179 {
    180 	struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
    181 	struct gralloc_drm_bo_t *bo;
    182 
    183 	bo = gralloc_drm_bo_from_handle(handle);
    184 	if (!bo)
    185 		return -EINVAL;
    186 
    187 	gralloc_drm_bo_decref(bo);
    188 
    189 	return 0;
    190 }
    191 
    192 static int drm_mod_alloc_gpu0(alloc_device_t *dev,
    193 		int w, int h, int format, int usage,
    194 		buffer_handle_t *handle, int *stride)
    195 {
    196 	struct drm_module_t *dmod = (struct drm_module_t *) dev->common.module;
    197 	struct gralloc_drm_bo_t *bo;
    198 	int size, bpp, err;
    199 
    200 	bpp = gralloc_drm_get_bpp(format);
    201 	if (!bpp)
    202 		return -EINVAL;
    203 
    204 	bo = gralloc_drm_bo_create(dmod->drm, w, h, format, usage);
    205 	if (!bo)
    206 		return -ENOMEM;
    207 
    208 	*handle = gralloc_drm_bo_get_handle(bo, stride);
    209 	/* in pixels */
    210 	*stride /= bpp;
    211 
    212 	return 0;
    213 }
    214 
    215 static int drm_mod_open_gpu0(struct drm_module_t *dmod, hw_device_t **dev)
    216 {
    217 	struct alloc_device_t *alloc;
    218 	int err;
    219 
    220 	err = drm_init(dmod);
    221 	if (err)
    222 		return err;
    223 
    224 	alloc = new alloc_device_t;
    225 	if (!alloc)
    226 		return -EINVAL;
    227 
    228 	alloc->common.tag = HARDWARE_DEVICE_TAG;
    229 	alloc->common.version = 0;
    230 	alloc->common.module = &dmod->base.common;
    231 	alloc->common.close = drm_mod_close_gpu0;
    232 
    233 	alloc->alloc = drm_mod_alloc_gpu0;
    234 	alloc->free = drm_mod_free_gpu0;
    235 
    236 	*dev = &alloc->common;
    237 
    238 	return 0;
    239 }
    240 
    241 static int drm_mod_open(const struct hw_module_t *mod,
    242 		const char *name, struct hw_device_t **dev)
    243 {
    244 	struct drm_module_t *dmod = (struct drm_module_t *) mod;
    245 	int err;
    246 
    247 	if (strcmp(name, GRALLOC_HARDWARE_GPU0) == 0)
    248 		err = drm_mod_open_gpu0(dmod, dev);
    249 	else
    250 		err = -EINVAL;
    251 
    252 	return err;
    253 }
    254 
    255 static struct hw_module_methods_t drm_mod_methods = {
    256 	.open = drm_mod_open
    257 };
    258 
    259 struct drm_module_t HAL_MODULE_INFO_SYM = {
    260 	.base = {
    261 		.common = {
    262 			.tag = HARDWARE_MODULE_TAG,
    263 			.version_major = 1,
    264 			.version_minor = 0,
    265 			.id = GRALLOC_HARDWARE_MODULE_ID,
    266 			.name = "DRM Memory Allocator",
    267 			.author = "Chia-I Wu",
    268 			.methods = &drm_mod_methods
    269 		},
    270 		.registerBuffer = drm_mod_register_buffer,
    271 		.unregisterBuffer = drm_mod_unregister_buffer,
    272 		.lock = drm_mod_lock,
    273 		.unlock = drm_mod_unlock,
    274 		.perform = drm_mod_perform,
    275 		.lock_ycbcr = drm_mod_lock_ycbcr,
    276 	},
    277 
    278 	.mutex = PTHREAD_MUTEX_INITIALIZER,
    279 	.drm = NULL
    280 };
    281