1 /* 2 * Copyright (C) 2010 ARM Limited. All rights reserved. 3 * 4 * Copyright (C) 2008 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * You may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #include <errno.h> 20 #include <pthread.h> 21 #include <string.h> 22 //#include <sync/sync.h> 23 #include <android/sync.h> 24 25 #include <cutils/log.h> 26 #include <cutils/atomic.h> 27 #include <hardware/hardware.h> 28 #include <hardware/gralloc.h> 29 30 #include "gralloc_priv.h" 31 #include "alloc_device.h" 32 #include "framebuffer_device.h" 33 34 #if GRALLOC_ARM_UMP_MODULE 35 #include <ump/ump_ref_drv.h> 36 static int s_ump_is_open = 0; 37 #endif 38 39 #if GRALLOC_ARM_DMA_BUF_MODULE 40 #include <ion/ion.h> 41 #include <sys/mman.h> 42 #endif 43 44 static pthread_mutex_t s_map_lock = PTHREAD_MUTEX_INITIALIZER; 45 46 static int gralloc_device_open(const hw_module_t *module, const char *name, hw_device_t **device) 47 { 48 int status = -EINVAL; 49 50 if (!strncmp(name, GRALLOC_HARDWARE_GPU0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) 51 { 52 status = alloc_device_open(module, name, device); 53 } 54 else if (!strncmp(name, GRALLOC_HARDWARE_FB0, MALI_GRALLOC_HARDWARE_MAX_STR_LEN)) 55 { 56 status = framebuffer_device_open(module, name, device); 57 } 58 59 return status; 60 } 61 62 static int gralloc_register_buffer(gralloc_module_t const *module, buffer_handle_t handle) 63 { 64 MALI_IGNORE(module); 65 66 if (private_handle_t::validate(handle) < 0) 67 { 68 AERR("Registering invalid buffer %p, returning error", handle); 69 return -EINVAL; 70 } 71 72 // if this handle was created in this process, then we keep it as is. 73 private_handle_t *hnd = (private_handle_t *)handle; 74 75 int retval = -EINVAL; 76 77 pthread_mutex_lock(&s_map_lock); 78 79 #if GRALLOC_ARM_UMP_MODULE 80 81 if (!s_ump_is_open) 82 { 83 ump_result res = ump_open(); // MJOLL-4012: UMP implementation needs a ump_close() for each ump_open 84 85 if (res != UMP_OK) 86 { 87 pthread_mutex_unlock(&s_map_lock); 88 AERR("Failed to open UMP library with res=%d", res); 89 return retval; 90 } 91 92 s_ump_is_open = 1; 93 } 94 95 #endif 96 97 hnd->pid = getpid(); 98 99 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 100 { 101 AINF("Register buffer %p although it will be treated as a nop", handle); 102 retval = 0; 103 } 104 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) 105 { 106 #if GRALLOC_ARM_UMP_MODULE 107 hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); 108 109 if (UMP_INVALID_MEMORY_HANDLE != (ump_handle)hnd->ump_mem_handle) 110 { 111 hnd->base = ump_mapped_pointer_get((ump_handle)hnd->ump_mem_handle); 112 113 if (0 != hnd->base) 114 { 115 hnd->writeOwner = 0; 116 hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED); 117 118 pthread_mutex_unlock(&s_map_lock); 119 return 0; 120 } 121 else 122 { 123 AERR("Failed to map UMP handle 0x%x", hnd->ump_mem_handle); 124 } 125 126 ump_reference_release((ump_handle)hnd->ump_mem_handle); 127 } 128 else 129 { 130 AERR("Failed to create UMP handle 0x%x", hnd->ump_mem_handle); 131 } 132 133 #else 134 AERR("Gralloc does not support UMP. Unable to register UMP memory for handle %p", hnd); 135 #endif 136 } 137 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 138 { 139 #if GRALLOC_ARM_DMA_BUF_MODULE 140 unsigned char *mappedAddress; 141 size_t size = hnd->size; 142 hw_module_t *pmodule = NULL; 143 private_module_t *m = NULL; 144 145 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0) 146 { 147 m = reinterpret_cast<private_module_t *>(pmodule); 148 } 149 else 150 { 151 AERR("Could not get gralloc module for handle: %p", hnd); 152 retval = -errno; 153 goto cleanup; 154 } 155 156 /* the test condition is set to m->ion_client <= 0 here, because: 157 * 1) module structure are initialized to 0 if no initial value is applied 158 * 2) a second user process should get a ion fd greater than 0. 159 */ 160 if (m->ion_client <= 0) 161 { 162 /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ 163 m->ion_client = ion_open(); 164 165 if (m->ion_client < 0) 166 { 167 AERR("Could not open ion device for handle: %p", hnd); 168 retval = -errno; 169 goto cleanup; 170 } 171 } 172 173 mappedAddress = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, hnd->share_fd, 0); 174 175 if (MAP_FAILED == mappedAddress) 176 { 177 AERR("mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror(errno)); 178 retval = -errno; 179 goto cleanup; 180 } 181 182 hnd->base = mappedAddress + hnd->offset; 183 hnd->lockState &= ~(private_handle_t::LOCK_STATE_UNREGISTERED); 184 185 pthread_mutex_unlock(&s_map_lock); 186 return 0; 187 #endif 188 } 189 else 190 { 191 AERR("registering non-UMP buffer not supported. flags = %d", hnd->flags); 192 } 193 194 #if GRALLOC_ARM_DMA_BUF_MODULE 195 cleanup: 196 #endif 197 pthread_mutex_unlock(&s_map_lock); 198 return retval; 199 } 200 201 static void unmap_buffer(private_handle_t *hnd) 202 { 203 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) 204 { 205 #if GRALLOC_ARM_UMP_MODULE 206 ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); 207 ump_reference_release((ump_handle)hnd->ump_mem_handle); 208 hnd->ump_mem_handle = (int)UMP_INVALID_MEMORY_HANDLE; 209 #else 210 AERR("Can't unregister UMP buffer for handle %p. Not supported", hnd); 211 #endif 212 } 213 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 214 { 215 #if GRALLOC_ARM_DMA_BUF_MODULE 216 void *base = (void *)hnd->base; 217 size_t size = hnd->size; 218 219 if (munmap(base, size) < 0) 220 { 221 AERR("Could not munmap base:%p size:%lu '%s'", base, (unsigned long)size, strerror(errno)); 222 } 223 224 #else 225 AERR("Can't unregister DMA_BUF buffer for hnd %p. Not supported", hnd); 226 #endif 227 228 } 229 else 230 { 231 AERR("Unregistering unknown buffer is not supported. Flags = %d", hnd->flags); 232 } 233 234 hnd->base = 0; 235 hnd->lockState = 0; 236 hnd->writeOwner = 0; 237 } 238 239 static int gralloc_unregister_buffer(gralloc_module_t const *module, buffer_handle_t handle) 240 { 241 MALI_IGNORE(module); 242 243 if (private_handle_t::validate(handle) < 0) 244 { 245 AERR("unregistering invalid buffer %p, returning error", handle); 246 return -EINVAL; 247 } 248 249 private_handle_t *hnd = (private_handle_t *)handle; 250 251 AERR_IF(hnd->lockState & private_handle_t::LOCK_STATE_READ_MASK, "[unregister] handle %p still locked (state=%08x)", hnd, hnd->lockState); 252 253 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 254 { 255 AERR("Can't unregister buffer %p as it is a framebuffer", handle); 256 } 257 else if (hnd->pid == getpid()) // never unmap buffers that were not registered in this process 258 { 259 pthread_mutex_lock(&s_map_lock); 260 261 hnd->lockState &= ~(private_handle_t::LOCK_STATE_MAPPED); 262 263 /* if handle is still locked, the unmapping would not happen until unlocked*/ 264 if (!(hnd->lockState & private_handle_t::LOCK_STATE_WRITE)) 265 { 266 unmap_buffer(hnd); 267 } 268 269 hnd->lockState |= private_handle_t::LOCK_STATE_UNREGISTERED; 270 271 pthread_mutex_unlock(&s_map_lock); 272 } 273 else 274 { 275 AERR("Trying to unregister buffer %p from process %d that was not created in current process: %d", hnd, hnd->pid, getpid()); 276 } 277 278 return 0; 279 } 280 281 static int gralloc_lock(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr) 282 { 283 284 285 if (private_handle_t::validate(handle) < 0) 286 { 287 AERR("Locking invalid buffer %p, returning error", handle); 288 return -EINVAL; 289 } 290 291 private_handle_t *hnd = (private_handle_t *)handle; 292 293 if (hnd->format == HAL_PIXEL_FORMAT_YCbCr_420_888) 294 { 295 AERR("Buffer with format HAL_PIXEL_FORMAT_YCbCr_*_888 must be locked by lock_ycbcr()"); 296 return -EINVAL; 297 } 298 299 pthread_mutex_lock(&s_map_lock); 300 301 if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED) 302 { 303 AERR("Locking on an unregistered buffer %p, returning error", hnd); 304 pthread_mutex_unlock(&s_map_lock); 305 return -EINVAL; 306 } 307 308 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP || hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 309 { 310 hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; 311 } 312 313 hnd->lockState |= private_handle_t::LOCK_STATE_WRITE; 314 315 pthread_mutex_unlock(&s_map_lock); 316 317 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) 318 { 319 *vaddr = (void *)hnd->base; 320 } 321 322 MALI_IGNORE(module); 323 MALI_IGNORE(l); 324 MALI_IGNORE(t); 325 MALI_IGNORE(w); 326 MALI_IGNORE(h); 327 return 0; 328 } 329 330 static int gralloc_lock_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr) 331 { 332 int retval = 0; 333 int ystride, cstride; 334 335 if (private_handle_t::validate(handle) < 0) 336 { 337 AERR("Locking invalid buffer %p, returning error", handle); 338 return -EINVAL; 339 } 340 341 private_handle_t *hnd = (private_handle_t *)handle; 342 343 pthread_mutex_lock(&s_map_lock); 344 345 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP || hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 346 { 347 hnd->writeOwner = usage & GRALLOC_USAGE_SW_WRITE_MASK; 348 } 349 350 hnd->lockState |= private_handle_t::LOCK_STATE_WRITE; 351 352 pthread_mutex_unlock(&s_map_lock); 353 354 355 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) 356 { 357 switch (hnd->format) 358 { 359 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 360 ystride = cstride = GRALLOC_ALIGN(hnd->width, 16); 361 ycbcr->y = (void *)hnd->base; 362 ycbcr->cr = (void *)((unsigned char *)hnd->base + ystride * hnd->height); 363 ycbcr->cb = (void *)((unsigned char *)hnd->base + ystride * hnd->height + 1); 364 ycbcr->ystride = ystride; 365 ycbcr->cstride = cstride; 366 ycbcr->chroma_step = 2; 367 break; 368 369 case HAL_PIXEL_FORMAT_YV12: 370 /* Here to keep consistency with YV12 alignment, define the ystride according to image height. */ 371 ystride = GRALLOC_ALIGN(hnd->width, (hnd->height % 8 == 0) ? GRALLOC_ALIGN_BASE_16 : 372 ((hnd->height % 4 == 0) ? GRALLOC_ALIGN_BASE_64 : GRALLOC_ALIGN_BASE_128)); 373 cstride = GRALLOC_ALIGN(ystride / 2, 16); 374 ycbcr->y = (void *)hnd->base; 375 /* the ystride calc is assuming the height can at least be divided by 2 */ 376 ycbcr->cr = (void *)((unsigned char *)hnd->base + ystride * GRALLOC_ALIGN(hnd->height, 2)); 377 ycbcr->cb = (void *)((unsigned char *)hnd->base + ystride * GRALLOC_ALIGN(hnd->height, 2) + cstride * hnd->height / 2); 378 ycbcr->ystride = ystride; 379 ycbcr->cstride = cstride; 380 ycbcr->chroma_step = 1; 381 break; 382 383 #ifdef SUPPORT_LEGACY_FORMAT 384 385 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 386 ystride = cstride = GRALLOC_ALIGN(hnd->width, 16); 387 ycbcr->y = (void *)hnd->base; 388 ycbcr->cb = (void *)((unsigned char *)hnd->base + ystride * hnd->height); 389 ycbcr->cr = (void *)((unsigned char *)hnd->base + ystride * hnd->height + 1); 390 ycbcr->ystride = ystride; 391 ycbcr->cstride = cstride; 392 ycbcr->chroma_step = 2; 393 break; 394 #endif 395 396 default: 397 AERR("Can not lock buffer, invalid format: 0x%x", hnd->format); 398 retval = -EINVAL; 399 } 400 } 401 402 MALI_IGNORE(module); 403 MALI_IGNORE(l); 404 MALI_IGNORE(t); 405 MALI_IGNORE(w); 406 MALI_IGNORE(h); 407 return retval; 408 } 409 410 static int gralloc_unlock(gralloc_module_t const *module, buffer_handle_t handle) 411 { 412 MALI_IGNORE(module); 413 414 if (private_handle_t::validate(handle) < 0) 415 { 416 AERR("Unlocking invalid buffer %p, returning error", handle); 417 return -EINVAL; 418 } 419 420 private_handle_t *hnd = (private_handle_t *)handle; 421 422 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP && hnd->writeOwner) 423 { 424 #if GRALLOC_ARM_UMP_MODULE 425 ump_cpu_msync_now((ump_handle)hnd->ump_mem_handle, UMP_MSYNC_CLEAN_AND_INVALIDATE, (void *)hnd->base, hnd->size); 426 #else 427 AERR("Buffer %p is UMP type but it is not supported", hnd); 428 #endif 429 } 430 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION && hnd->writeOwner) 431 { 432 #if GRALLOC_ARM_DMA_BUF_MODULE 433 hw_module_t *pmodule = NULL; 434 private_module_t *m = NULL; 435 436 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0) 437 { 438 m = reinterpret_cast<private_module_t *>(pmodule); 439 //ion_sync_fd(m->ion_client, hnd->share_fd); 440 } 441 else 442 { 443 AERR("Couldnot get gralloc module for handle %p\n", handle); 444 } 445 446 #endif 447 } 448 449 pthread_mutex_lock(&s_map_lock); 450 451 hnd->lockState &= ~(private_handle_t::LOCK_STATE_WRITE); 452 453 /* if the handle has already been unregistered, unmap it here*/ 454 if (hnd->lockState & private_handle_t::LOCK_STATE_UNREGISTERED) 455 { 456 unmap_buffer(hnd); 457 } 458 459 pthread_mutex_unlock(&s_map_lock); 460 461 return 0; 462 } 463 464 #if defined(GRALLOC_MODULE_API_VERSION_0_3) 465 static int gralloc_lock_async (gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, void **vaddr, int fenceFD) 466 { 467 if (fenceFD >= 0) 468 { 469 sync_wait(fenceFD, -1); 470 close(fenceFD); 471 } 472 473 return gralloc_lock(module, handle, usage, l, t, w, h, vaddr); 474 } 475 476 static int gralloc_unlock_async(gralloc_module_t const *module, buffer_handle_t handle, int *fenceFD) 477 { 478 *fenceFD = -1; 479 480 if (gralloc_unlock(module, handle) < 0) 481 { 482 return -EINVAL; 483 } 484 485 return 0; 486 487 } 488 489 static int gralloc_lock_async_ycbcr(gralloc_module_t const *module, buffer_handle_t handle, int usage, int l, int t, int w, int h, struct android_ycbcr *ycbcr, int fenceFD) 490 { 491 if (fenceFD >= 0) 492 { 493 sync_wait(fenceFD, -1); 494 close(fenceFD); 495 } 496 497 return gralloc_lock_ycbcr(module, handle, usage, l, t, w, h, ycbcr); 498 } 499 #endif 500 501 // There is one global instance of the module 502 503 static struct hw_module_methods_t gralloc_module_methods = 504 { 505 .open = gralloc_device_open 506 }; 507 508 private_module_t::private_module_t() 509 { 510 #define INIT_ZERO(obj) (memset(&(obj),0,sizeof((obj)))) 511 512 base.common.tag = HARDWARE_MODULE_TAG; 513 #if defined(GRALLOC_MODULE_API_VERSION_0_3) 514 base.common.version_major = GRALLOC_MODULE_API_VERSION_0_3; 515 #else 516 base.common.version_major = GRALLOC_MODULE_API_VERSION_0_2; 517 #endif 518 base.common.version_minor = 0; 519 base.common.id = GRALLOC_HARDWARE_MODULE_ID; 520 base.common.name = "Graphics Memory Allocator Module"; 521 base.common.author = "ARM Ltd."; 522 base.common.methods = &gralloc_module_methods; 523 base.common.dso = NULL; 524 INIT_ZERO(base.common.reserved); 525 526 base.registerBuffer = gralloc_register_buffer; 527 base.unregisterBuffer = gralloc_unregister_buffer; 528 base.lock = gralloc_lock; 529 base.unlock = gralloc_unlock; 530 base.perform = NULL; 531 base.lock_ycbcr = gralloc_lock_ycbcr; 532 base.getTransportSize = NULL; 533 base.validateBufferSize = NULL; 534 #if defined(GRALLOC_MODULE_API_VERSION_0_3) 535 base.lockAsync = gralloc_lock_async; 536 base.unlockAsync = gralloc_unlock_async; 537 base.lockAsync_ycbcr = gralloc_lock_async_ycbcr; 538 #endif 539 INIT_ZERO(base.reserved_proc); 540 541 framebuffer = NULL; 542 flags = 0; 543 numBuffers = 0; 544 bufferMask = 0; 545 pthread_mutex_init(&(lock), NULL); 546 currentBuffer = NULL; 547 INIT_ZERO(info); 548 INIT_ZERO(finfo); 549 xdpi = 0.0f; 550 ydpi = 0.0f; 551 fps = 0.0f; 552 553 #undef INIT_ZERO 554 }; 555 556 /* 557 * HAL_MODULE_INFO_SYM will be initialized using the default constructor 558 * implemented above 559 */ 560 struct private_module_t HAL_MODULE_INFO_SYM; 561 562