gralloc.cpp revision da3d871233c291dd2c472c4a7f6bfe35e7c06fc9
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define 18# include <asm/page.h> 19#else 20# include <sys/user.h> 21#endif 22#include <limits.h> 23#include <unistd.h> 24#include <fcntl.h> 25#include <errno.h> 26#include <pthread.h> 27#include <stdlib.h> 28#include <string.h> 29 30#include <sys/mman.h> 31#include <sys/stat.h> 32#include <sys/types.h> 33#include <sys/ioctl.h> 34 35#include <ion/ion.h> 36#include <linux/ion.h> 37#include <cutils/log.h> 38#include <cutils/atomic.h> 39 40#include <hardware/hardware.h> 41#include <hardware/gralloc.h> 42 43#include "gralloc_priv.h" 44#include "exynos_format.h" 45#include "gr.h" 46 47/*****************************************************************************/ 48 49struct gralloc_context_t { 50 alloc_device_t device; 51 /* our private data here */ 52}; 53 54static int gralloc_alloc_buffer(alloc_device_t* dev, 55 size_t size, int usage, buffer_handle_t* pHandle); 56 57/*****************************************************************************/ 58 59int fb_device_open(const hw_module_t* module, const char* name, 60 hw_device_t** device); 61 62static int gralloc_device_open(const hw_module_t* module, const char* name, 63 hw_device_t** device); 64 65extern int gralloc_lock(gralloc_module_t const* module, 66 buffer_handle_t handle, int usage, 67 int l, int t, int w, int h, 68 void** vaddr); 69 70extern int gralloc_unlock(gralloc_module_t const* module, 71 buffer_handle_t handle); 72 73extern int gralloc_register_buffer(gralloc_module_t const* module, 74 buffer_handle_t handle); 75 76extern int gralloc_unregister_buffer(gralloc_module_t const* module, 77 buffer_handle_t handle); 78 79/*****************************************************************************/ 80 81static struct hw_module_methods_t gralloc_module_methods = { 82open: gralloc_device_open 83}; 84 85struct private_module_t HAL_MODULE_INFO_SYM = { 86base: { 87common: { 88tag: HARDWARE_MODULE_TAG, 89 version_major: 1, 90 version_minor: 0, 91 id: GRALLOC_HARDWARE_MODULE_ID, 92 name: "Graphics Memory Allocator Module", 93 author: "The Android Open Source Project", 94 methods: &gralloc_module_methods 95 }, 96registerBuffer: gralloc_register_buffer, 97 unregisterBuffer: gralloc_unregister_buffer, 98 lock: gralloc_lock, 99 unlock: gralloc_unlock, 100 }, 101framebuffer: 0, 102 flags: 0, 103 numBuffers: 0, 104 bufferMask: 0, 105 lock: PTHREAD_MUTEX_INITIALIZER, 106 currentBuffer: 0, 107 ionfd: -1, 108}; 109 110/*****************************************************************************/ 111 112#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1)) 113 114static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage, 115 unsigned int ion_flags, private_handle_t **hnd, int *stride) 116{ 117 size_t size, bpr; 118 int bpp = 0, vstride, fd, err; 119 switch (format) { 120 case HAL_PIXEL_FORMAT_RGBA_8888: 121 case HAL_PIXEL_FORMAT_RGBX_8888: 122 case HAL_PIXEL_FORMAT_BGRA_8888: 123 bpp = 4; 124 break; 125 case HAL_PIXEL_FORMAT_RGB_888: 126 bpp = 3; 127 break; 128 case HAL_PIXEL_FORMAT_RGB_565: 129 case HAL_PIXEL_FORMAT_RGBA_5551: 130 case HAL_PIXEL_FORMAT_RGBA_4444: 131 case HAL_PIXEL_FORMAT_RAW_SENSOR: 132 bpp = 2; 133 break; 134 case HAL_PIXEL_FORMAT_BLOB: 135 bpp = 1; 136 break; 137 default: 138 return -EINVAL; 139 } 140 bpr = ALIGN(w*bpp, 16); 141 vstride = ALIGN(h, 16); 142 size = bpr * vstride; 143 *stride = bpr / bpp; 144 size = ALIGN(size, PAGE_SIZE); 145 146 err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM, ion_flags, 147 &fd); 148 *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride, 149 vstride); 150 151 return err; 152} 153 154static int gralloc_alloc_yuv(int ionfd, int w, int h, int format, int usage, 155 unsigned int ion_flags, private_handle_t **hnd, int *stride) 156{ 157 size_t luma_size, chroma_size; 158 int err, planes, fd, fd1, fd2 = 0; 159 size_t luma_vstride; 160 *stride = ALIGN(w, 16); 161 162 switch (format) { 163 ALOGE("invalid yuv format %d\n", format); 164 case HAL_PIXEL_FORMAT_YV12: 165 { 166 luma_vstride = ALIGN(h, 16); 167 luma_size = luma_vstride * *stride; 168 chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16); 169 planes = 3; 170 break; 171 } 172 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 173 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 174 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 175 { 176 size_t chroma_vstride = ALIGN(h / 2, 32); 177 luma_vstride = ALIGN(h, 32); 178 luma_size = luma_vstride * *stride; 179 chroma_size = chroma_vstride * *stride; 180 planes = 2; 181 break; 182 } 183 default: 184 ALOGE("invalid yuv format %d\n", format); 185 return -EINVAL; 186 } 187 188 err = ion_alloc_fd(ionfd, luma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM, 189 ion_flags, &fd); 190 if (err) 191 return err; 192 err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM, 193 ion_flags, 194 &fd1); 195 if (err) 196 goto err1; 197 if (planes == 3) { 198 err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM, 199 ion_flags, &fd2); 200 if (err) 201 goto err2; 202 } 203 204 *hnd = new private_handle_t(fd, fd1, fd2, luma_size, usage, w, h, format, 205 *stride, luma_vstride); 206 return err; 207 208err2: 209 close(fd1); 210err1: 211 close(fd); 212 return err; 213} 214 215static int gralloc_alloc(alloc_device_t* dev, 216 int w, int h, int format, int usage, 217 buffer_handle_t* pHandle, int* pStride) 218{ 219 int stride; 220 int err; 221 unsigned int ion_flags = 0; 222 private_handle_t *hnd; 223 224 if (!pHandle || !pStride) 225 return -EINVAL; 226 227 if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN ) 228 ion_flags = ION_FLAG_CACHED; 229 230 private_module_t* m = reinterpret_cast<private_module_t*> 231 (dev->common.module); 232 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*> 233 (dev->common.module); 234 235 err = gralloc_alloc_rgb(m->ionfd, w, h, format, usage, ion_flags, &hnd, 236 &stride); 237 if (err) 238 err = gralloc_alloc_yuv(m->ionfd, w, h, format, usage, ion_flags, 239 &hnd, &stride); 240 if (err) 241 return err; 242 243 err = grallocMap(module, hnd); 244 245 if (err != 0) 246 goto err; 247 248 *pHandle = hnd; 249 *pStride = stride; 250 return 0; 251err: 252 close(hnd->fd); 253 if (hnd->fd1 > 0) 254 close(hnd->fd1); 255 if (hnd->fd2 > 0) 256 close(hnd->fd2); 257 return err; 258} 259 260static int gralloc_free(alloc_device_t* dev, 261 buffer_handle_t handle) 262{ 263 if (private_handle_t::validate(handle) < 0) 264 return -EINVAL; 265 266 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle); 267 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>( 268 dev->common.module); 269 270 grallocUnmap(module, const_cast<private_handle_t*>(hnd)); 271 close(hnd->fd); 272 if (hnd->fd1 > 0) 273 close(hnd->fd1); 274 if (hnd->fd2 > 0) 275 close(hnd->fd2); 276 277 delete hnd; 278 return 0; 279} 280 281/*****************************************************************************/ 282 283static int gralloc_close(struct hw_device_t *dev) 284{ 285 gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev); 286 if (ctx) { 287 /* TODO: keep a list of all buffer_handle_t created, and free them 288 * all here. 289 */ 290 free(ctx); 291 } 292 return 0; 293} 294 295int gralloc_device_open(const hw_module_t* module, const char* name, 296 hw_device_t** device) 297{ 298 int status = -EINVAL; 299 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { 300 gralloc_context_t *dev; 301 dev = (gralloc_context_t*)malloc(sizeof(*dev)); 302 303 /* initialize our state here */ 304 memset(dev, 0, sizeof(*dev)); 305 306 /* initialize the procs */ 307 dev->device.common.tag = HARDWARE_DEVICE_TAG; 308 dev->device.common.version = 0; 309 dev->device.common.module = const_cast<hw_module_t*>(module); 310 dev->device.common.close = gralloc_close; 311 312 dev->device.alloc = gralloc_alloc; 313 dev->device.free = gralloc_free; 314 315 private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module); 316 p->ionfd = ion_open(); 317 318 *device = &dev->device.common; 319 status = 0; 320 } else { 321 status = fb_device_open(module, name, device); 322 } 323 return status; 324} 325