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 #define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4) 48 #define ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28) 49 #define ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26) 50 #define ION_EXYNOS_MFC_INPUT_MASK (1 << 25) 51 #define ION_HEAP_SYSTEM_ID 0 52 #define ION_HEAP_EXYNOS_CONTIG_ID 4 53 #define ION_HEAP_CHUNK_ID 6 54 #define MB_1 (1024*1024) 55 56 57 /*****************************************************************************/ 58 59 struct gralloc_context_t { 60 alloc_device_t device; 61 /* our private data here */ 62 }; 63 64 static int gralloc_alloc_buffer(alloc_device_t* dev, 65 size_t size, int usage, buffer_handle_t* pHandle); 66 67 /*****************************************************************************/ 68 69 int fb_device_open(const hw_module_t* module, const char* name, 70 hw_device_t** device); 71 72 static int gralloc_device_open(const hw_module_t* module, const char* name, 73 hw_device_t** device); 74 75 extern int gralloc_lock(gralloc_module_t const* module, 76 buffer_handle_t handle, int usage, 77 int l, int t, int w, int h, 78 void** vaddr); 79 80 extern int gralloc_unlock(gralloc_module_t const* module, 81 buffer_handle_t handle); 82 83 extern int gralloc_register_buffer(gralloc_module_t const* module, 84 buffer_handle_t handle); 85 86 extern int gralloc_unregister_buffer(gralloc_module_t const* module, 87 buffer_handle_t handle); 88 89 /*****************************************************************************/ 90 91 static struct hw_module_methods_t gralloc_module_methods = { 92 open: gralloc_device_open 93 }; 94 95 struct private_module_t HAL_MODULE_INFO_SYM = { 96 base: { 97 common: { 98 tag: HARDWARE_MODULE_TAG, 99 version_major: 1, 100 version_minor: 0, 101 id: GRALLOC_HARDWARE_MODULE_ID, 102 name: "Graphics Memory Allocator Module", 103 author: "The Android Open Source Project", 104 methods: &gralloc_module_methods 105 }, 106 registerBuffer: gralloc_register_buffer, 107 unregisterBuffer: gralloc_unregister_buffer, 108 lock: gralloc_lock, 109 unlock: gralloc_unlock, 110 }, 111 framebuffer: 0, 112 flags: 0, 113 numBuffers: 0, 114 bufferMask: 0, 115 lock: PTHREAD_MUTEX_INITIALIZER, 116 currentBuffer: 0, 117 ionfd: -1, 118 }; 119 120 /*****************************************************************************/ 121 122 static unsigned int _select_heap(int usage) 123 { 124 unsigned int heap_mask; 125 126 if (usage & GRALLOC_USAGE_PROTECTED) 127 heap_mask = (1 << ION_HEAP_EXYNOS_CONTIG_ID); 128 else 129 heap_mask = (1 << ION_HEAP_SYSTEM_ID) | (1 << ION_HEAP_CHUNK_ID); 130 131 return heap_mask; 132 } 133 134 static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage, 135 unsigned int ion_flags, private_handle_t **hnd, int *stride) 136 { 137 size_t size, bpr, alignment = 0; 138 int bpp = 0, vstride, fd, err; 139 unsigned int heap_mask = _select_heap(usage); 140 141 switch (format) { 142 case HAL_PIXEL_FORMAT_RGBA_8888: 143 case HAL_PIXEL_FORMAT_RGBX_8888: 144 case HAL_PIXEL_FORMAT_BGRA_8888: 145 bpp = 4; 146 break; 147 case HAL_PIXEL_FORMAT_RGB_888: 148 bpp = 3; 149 break; 150 case HAL_PIXEL_FORMAT_RGB_565: 151 case HAL_PIXEL_FORMAT_RGBA_5551: 152 case HAL_PIXEL_FORMAT_RGBA_4444: 153 case HAL_PIXEL_FORMAT_RAW_SENSOR: 154 bpp = 2; 155 break; 156 case HAL_PIXEL_FORMAT_BLOB: 157 *stride = w; 158 vstride = h; 159 size = w * h; 160 break; 161 default: 162 return -EINVAL; 163 } 164 165 if (format != HAL_PIXEL_FORMAT_BLOB) { 166 bpr = ALIGN(w*bpp, 64); 167 vstride = ALIGN(h, 16); 168 if (vstride < h + 2) 169 size = bpr * (h + 2); 170 else 171 size = bpr * vstride; 172 *stride = bpr / bpp; 173 size = ALIGN(size, PAGE_SIZE); 174 } 175 176 if (usage & GRALLOC_USAGE_PROTECTED) { 177 alignment = MB_1; 178 ion_flags |= ION_EXYNOS_FIMD_VIDEO_MASK; 179 } 180 181 err = ion_alloc_fd(ionfd, size, alignment, heap_mask, ion_flags, 182 &fd); 183 *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride, 184 vstride); 185 186 return err; 187 } 188 189 static int gralloc_alloc_framework_yuv(int ionfd, int w, int h, int format, 190 int usage, unsigned int ion_flags, 191 private_handle_t **hnd, int *stride) 192 { 193 size_t size; 194 int err, fd; 195 unsigned int heap_mask = _select_heap(usage); 196 197 switch (format) { 198 case HAL_PIXEL_FORMAT_YV12: 199 *stride = ALIGN(w, 16); 200 size = (*stride * h) + (ALIGN(*stride / 2, 16) * h); 201 break; 202 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 203 *stride = w; 204 size = *stride * h * 3 / 2; 205 break; 206 default: 207 ALOGE("invalid yuv format %d\n", format); 208 return -EINVAL; 209 } 210 211 err = ion_alloc_fd(ionfd, size, 0, heap_mask, ion_flags, &fd); 212 if (err) 213 return err; 214 215 *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride, h); 216 return err; 217 } 218 219 static int gralloc_alloc_yuv(int ionfd, int w, int h, int format, 220 int usage, unsigned int ion_flags, 221 private_handle_t **hnd, int *stride) 222 { 223 size_t luma_size, chroma_size; 224 int err, planes, fd, fd1, fd2 = 0; 225 size_t luma_vstride; 226 unsigned int heap_mask = _select_heap(usage); 227 228 *stride = ALIGN(w, 16); 229 230 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 231 ALOGV("HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED : usage(%x), flags(%x)\n", usage, ion_flags); 232 if ((usage & GRALLOC_USAGE_HW_CAMERA_ZSL) == GRALLOC_USAGE_HW_CAMERA_ZSL) { 233 format = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV 234 } else if (usage & GRALLOC_USAGE_HW_TEXTURE) { 235 format = HAL_PIXEL_FORMAT_EXYNOS_YV12; 236 } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) { 237 format = HAL_PIXEL_FORMAT_YCbCr_420_SP; // NV12M 238 } 239 } 240 switch (format) { 241 case HAL_PIXEL_FORMAT_EXYNOS_YV12: 242 { 243 *stride = ALIGN(w, 32); 244 luma_vstride = ALIGN(h, 16); 245 luma_size = luma_vstride * *stride; 246 chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16); 247 planes = 3; 248 break; 249 } 250 case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP: 251 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 252 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 253 { 254 size_t chroma_vstride = ALIGN(h / 2, 32); 255 luma_vstride = ALIGN(h, 32); 256 luma_size = luma_vstride * *stride; 257 chroma_size = chroma_vstride * *stride; 258 planes = 2; 259 break; 260 } 261 case HAL_PIXEL_FORMAT_YV12: 262 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 263 return gralloc_alloc_framework_yuv(ionfd, w, h, format, usage, 264 ion_flags, hnd, stride); 265 case HAL_PIXEL_FORMAT_YCbCr_422_I: 266 { 267 luma_vstride = h; 268 luma_size = luma_vstride * *stride * 2; 269 chroma_size = 0; 270 planes = 1; 271 break; 272 } 273 default: 274 ALOGE("invalid yuv format %d\n", format); 275 return -EINVAL; 276 } 277 278 if (usage & GRALLOC_USAGE_PROTECTED) 279 ion_flags |= ION_EXYNOS_MFC_OUTPUT_MASK; 280 281 err = ion_alloc_fd(ionfd, luma_size, 0, heap_mask, ion_flags, &fd); 282 if (err) 283 return err; 284 if (planes == 1) { 285 *hnd = new private_handle_t(fd, luma_size, usage, w, h, 286 format, *stride, luma_vstride); 287 } else { 288 err = ion_alloc_fd(ionfd, chroma_size, 0, heap_mask, ion_flags, &fd1); 289 if (err) 290 goto err1; 291 if (planes == 3) { 292 err = ion_alloc_fd(ionfd, chroma_size, 0, heap_mask, ion_flags, &fd2); 293 if (err) 294 goto err2; 295 296 *hnd = new private_handle_t(fd, fd1, fd2, luma_size, usage, w, h, 297 format, *stride, luma_vstride); 298 } else { 299 *hnd = new private_handle_t(fd, fd1, luma_size, usage, w, h, format, 300 *stride, luma_vstride); 301 } 302 } 303 // Set chroma & gamut fields 304 if (!err && *hnd) { 305 if (usage & GRALLOC_USAGE_PRIVATE_CHROMA) { 306 (*hnd)->chroma = HAL_PIXEL_CHROMA_BT601_8; 307 (*hnd)->gamut = HAL_PIXEL_GAMUT_NARROW_8; 308 } else { 309 (*hnd)->chroma = HAL_PIXEL_CHROMA_BT709_8; 310 (*hnd)->gamut = HAL_PIXEL_GAMUT_WIDE_8; 311 } 312 } 313 return err; 314 315 err2: 316 close(fd1); 317 err1: 318 close(fd); 319 return err; 320 } 321 322 static int gralloc_alloc(alloc_device_t* dev, 323 int w, int h, int format, int usage, 324 buffer_handle_t* pHandle, int* pStride) 325 { 326 int stride; 327 int err; 328 unsigned int ion_flags = 0; 329 private_handle_t *hnd = NULL; 330 331 if (!pHandle || !pStride) 332 return -EINVAL; 333 334 if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN ) 335 ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC; 336 337 private_module_t* m = reinterpret_cast<private_module_t*> 338 (dev->common.module); 339 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*> 340 (dev->common.module); 341 342 err = gralloc_alloc_rgb(m->ionfd, w, h, format, usage, ion_flags, &hnd, 343 &stride); 344 if (err) 345 err = gralloc_alloc_yuv(m->ionfd, w, h, format, usage, ion_flags, 346 &hnd, &stride); 347 if (err) 348 return err; 349 350 if (err != 0) 351 goto err; 352 353 *pHandle = hnd; 354 *pStride = stride; 355 return 0; 356 err: 357 if (!hnd) 358 return err; 359 close(hnd->fd); 360 if (hnd->fd1 >= 0) 361 close(hnd->fd1); 362 if (hnd->fd2 >= 0) 363 close(hnd->fd2); 364 return err; 365 } 366 367 static int gralloc_free(alloc_device_t* dev, 368 buffer_handle_t handle) 369 { 370 if (private_handle_t::validate(handle) < 0) 371 return -EINVAL; 372 373 private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle); 374 gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>( 375 dev->common.module); 376 if (hnd->base) 377 grallocUnmap(module, const_cast<private_handle_t*>(hnd)); 378 379 close(hnd->fd); 380 if (hnd->fd1 >= 0) 381 close(hnd->fd1); 382 if (hnd->fd2 >= 0) 383 close(hnd->fd2); 384 385 delete hnd; 386 return 0; 387 } 388 389 /*****************************************************************************/ 390 391 static int gralloc_close(struct hw_device_t *dev) 392 { 393 gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev); 394 if (ctx) { 395 /* TODO: keep a list of all buffer_handle_t created, and free them 396 * all here. 397 */ 398 free(ctx); 399 } 400 return 0; 401 } 402 403 int gralloc_device_open(const hw_module_t* module, const char* name, 404 hw_device_t** device) 405 { 406 int status = -EINVAL; 407 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { 408 gralloc_context_t *dev; 409 dev = (gralloc_context_t*)malloc(sizeof(*dev)); 410 411 /* initialize our state here */ 412 memset(dev, 0, sizeof(*dev)); 413 414 /* initialize the procs */ 415 dev->device.common.tag = HARDWARE_DEVICE_TAG; 416 dev->device.common.version = 0; 417 dev->device.common.module = const_cast<hw_module_t*>(module); 418 dev->device.common.close = gralloc_close; 419 420 dev->device.alloc = gralloc_alloc; 421 dev->device.free = gralloc_free; 422 423 private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module); 424 p->ionfd = ion_open(); 425 426 *device = &dev->device.common; 427 status = 0; 428 } else { 429 status = fb_device_open(module, name, device); 430 } 431 return status; 432 } 433