1/* 2 * Copyright (C) 2010-2011 Chia-I Wu <olvaffe@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 */ 38static 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 53static 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 81static 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 94static 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 100static 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 113static 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 127static 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 138static 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 152static 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 175static 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 201static 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 215static struct hw_module_methods_t drm_mod_methods = { 216 .open = drm_mod_open 217}; 218 219struct 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