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 <string.h> 20 #include <errno.h> 21 #include <pthread.h> 22 23 #include <cutils/log.h> 24 #include <cutils/atomic.h> 25 #include <hardware/hardware.h> 26 #include <hardware/gralloc.h> 27 28 #include <sys/ioctl.h> 29 30 #include "alloc_device.h" 31 #include "gralloc_priv.h" 32 #include "gralloc_helper.h" 33 #include "framebuffer_device.h" 34 35 #if GRALLOC_ARM_UMP_MODULE 36 #include <ump/ump.h> 37 #include <ump/ump_ref_drv.h> 38 #endif 39 40 #if GRALLOC_ARM_DMA_BUF_MODULE 41 #include <linux/ion.h> 42 #include <ion/ion.h> 43 #endif 44 45 #define GRALLOC_ALIGN( value, base ) (((value) + ((base) - 1)) & ~((base) - 1)) 46 47 48 #if GRALLOC_SIMULATE_FAILURES 49 #include <cutils/properties.h> 50 51 /* system property keys for controlling simulated UMP allocation failures */ 52 #define PROP_MALI_TEST_GRALLOC_FAIL_FIRST "mali.test.gralloc.fail_first" 53 #define PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL "mali.test.gralloc.fail_interval" 54 55 static int __ump_alloc_should_fail() 56 { 57 58 static unsigned int call_count = 0; 59 unsigned int first_fail = 0; 60 int fail_period = 0; 61 int fail = 0; 62 63 ++call_count; 64 65 /* read the system properties that control failure simulation */ 66 { 67 char prop_value[PROPERTY_VALUE_MAX]; 68 69 if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_FIRST, prop_value, "0") > 0) 70 { 71 sscanf(prop_value, "%11u", &first_fail); 72 } 73 74 if (property_get(PROP_MALI_TEST_GRALLOC_FAIL_INTERVAL, prop_value, "0") > 0) 75 { 76 sscanf(prop_value, "%11u", &fail_period); 77 } 78 } 79 80 /* failure simulation is enabled by setting the first_fail property to non-zero */ 81 if (first_fail > 0) 82 { 83 LOGI("iteration %u (fail=%u, period=%u)\n", call_count, first_fail, fail_period); 84 85 fail = (call_count == first_fail) || 86 (call_count > first_fail && fail_period > 0 && 0 == (call_count - first_fail) % fail_period); 87 88 if (fail) 89 { 90 AERR("failed ump_ref_drv_allocate on iteration #%d\n", call_count); 91 } 92 } 93 94 return fail; 95 } 96 #endif 97 98 99 static int gralloc_alloc_buffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) 100 { 101 #if GRALLOC_ARM_DMA_BUF_MODULE 102 { 103 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 104 ion_user_handle_t ion_hnd; 105 unsigned char *cpu_ptr; 106 int shared_fd; 107 int ret; 108 109 ret = ion_alloc(m->ion_client, size, 0, ION_HEAP_SYSTEM_MASK, 0, &(ion_hnd)); 110 111 if (ret != 0) 112 { 113 AERR("Failed to ion_alloc from ion_client:%d", m->ion_client); 114 return -1; 115 } 116 117 ret = ion_share(m->ion_client, ion_hnd, &shared_fd); 118 119 if (ret != 0) 120 { 121 AERR("ion_share( %d ) failed", m->ion_client); 122 123 if (0 != ion_free(m->ion_client, ion_hnd)) 124 { 125 AERR("ion_free( %d ) failed", m->ion_client); 126 } 127 128 return -1; 129 } 130 131 cpu_ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_fd, 0); 132 133 if (MAP_FAILED == cpu_ptr) 134 { 135 AERR("ion_map( %d ) failed", m->ion_client); 136 137 if (0 != ion_free(m->ion_client, ion_hnd)) 138 { 139 AERR("ion_free( %d ) failed", m->ion_client); 140 } 141 142 close(shared_fd); 143 return -1; 144 } 145 146 private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_ION, usage, size, cpu_ptr, private_handle_t::LOCK_STATE_MAPPED); 147 148 if (NULL != hnd) 149 { 150 hnd->share_fd = shared_fd; 151 hnd->ion_hnd = ion_hnd; 152 *pHandle = hnd; 153 return 0; 154 } 155 else 156 { 157 AERR("Gralloc out of mem for ion_client:%d", m->ion_client); 158 } 159 160 close(shared_fd); 161 ret = munmap(cpu_ptr, size); 162 163 if (0 != ret) 164 { 165 AERR("munmap failed for base:%p size: %lu", cpu_ptr, (unsigned long)size); 166 } 167 168 ret = ion_free(m->ion_client, ion_hnd); 169 170 if (0 != ret) 171 { 172 AERR("ion_free( %d ) failed", m->ion_client); 173 } 174 175 return -1; 176 } 177 #endif 178 179 #if GRALLOC_ARM_UMP_MODULE 180 MALI_IGNORE(dev); 181 { 182 ump_handle ump_mem_handle; 183 void *cpu_ptr; 184 ump_secure_id ump_id; 185 ump_alloc_constraints constraints; 186 187 size = round_up_to_page_size(size); 188 189 if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) 190 { 191 constraints = UMP_REF_DRV_CONSTRAINT_USE_CACHE; 192 } 193 else 194 { 195 constraints = UMP_REF_DRV_CONSTRAINT_NONE; 196 } 197 198 #ifdef GRALLOC_SIMULATE_FAILURES 199 200 /* if the failure condition matches, fail this iteration */ 201 if (__ump_alloc_should_fail()) 202 { 203 ump_mem_handle = UMP_INVALID_MEMORY_HANDLE; 204 } 205 else 206 #endif 207 { 208 ump_mem_handle = ump_ref_drv_allocate(size, constraints); 209 210 if (UMP_INVALID_MEMORY_HANDLE != ump_mem_handle) 211 { 212 cpu_ptr = ump_mapped_pointer_get(ump_mem_handle); 213 214 if (NULL != cpu_ptr) 215 { 216 ump_id = ump_secure_id_get(ump_mem_handle); 217 218 if (UMP_INVALID_SECURE_ID != ump_id) 219 { 220 private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_USES_UMP, usage, size, cpu_ptr, 221 private_handle_t::LOCK_STATE_MAPPED, ump_id, ump_mem_handle); 222 223 if (NULL != hnd) 224 { 225 *pHandle = hnd; 226 return 0; 227 } 228 else 229 { 230 AERR("gralloc_alloc_buffer() failed to allocate handle. ump_handle = %p, ump_id = %d", ump_mem_handle, ump_id); 231 } 232 } 233 else 234 { 235 AERR("gralloc_alloc_buffer() failed to retrieve valid secure id. ump_handle = %p", ump_mem_handle); 236 } 237 238 ump_mapped_pointer_release(ump_mem_handle); 239 } 240 else 241 { 242 AERR("gralloc_alloc_buffer() failed to map UMP memory. ump_handle = %p", ump_mem_handle); 243 } 244 245 ump_reference_release(ump_mem_handle); 246 } 247 else 248 { 249 AERR("gralloc_alloc_buffer() failed to allocate UMP memory. size:%d constraints: %d", size, constraints); 250 } 251 } 252 253 return -1; 254 } 255 #endif 256 257 } 258 259 static int gralloc_alloc_framebuffer_locked(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) 260 { 261 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 262 263 // allocate the framebuffer 264 if (m->framebuffer == NULL) 265 { 266 // initialize the framebuffer, the framebuffer is mapped once and forever. 267 int err = init_frame_buffer_locked(m); 268 269 if (err < 0) 270 { 271 return err; 272 } 273 } 274 275 const uint32_t bufferMask = m->bufferMask; 276 const uint32_t numBuffers = m->numBuffers; 277 const size_t bufferSize = m->finfo.line_length * m->info.yres; 278 279 if (numBuffers == 1) 280 { 281 // If we have only one buffer, we never use page-flipping. Instead, 282 // we return a regular buffer which will be memcpy'ed to the main 283 // screen when post is called. 284 int newUsage = (usage & ~GRALLOC_USAGE_HW_FB) | GRALLOC_USAGE_HW_2D; 285 AERR("fallback to single buffering. Virtual Y-res too small %d", m->info.yres); 286 return gralloc_alloc_buffer(dev, bufferSize, newUsage, pHandle); 287 } 288 289 if (bufferMask >= ((1LU << numBuffers) - 1)) 290 { 291 // We ran out of buffers. 292 return -ENOMEM; 293 } 294 295 void *vaddr = m->framebuffer->base; 296 297 // find a free slot 298 for (uint32_t i = 0 ; i < numBuffers ; i++) 299 { 300 if ((bufferMask & (1LU << i)) == 0) 301 { 302 m->bufferMask |= (1LU << i); 303 break; 304 } 305 306 vaddr = (void *)((uintptr_t)vaddr + bufferSize); 307 } 308 309 // The entire framebuffer memory is already mapped, now create a buffer object for parts of this memory 310 private_handle_t *hnd = new private_handle_t(private_handle_t::PRIV_FLAGS_FRAMEBUFFER, usage, size, vaddr, 311 0, dup(m->framebuffer->fd), (uintptr_t)vaddr - (uintptr_t) m->framebuffer->base); 312 #if GRALLOC_ARM_UMP_MODULE 313 hnd->ump_id = m->framebuffer->ump_id; 314 315 /* create a backing ump memory handle if the framebuffer is exposed as a secure ID */ 316 if ((int)UMP_INVALID_SECURE_ID != hnd->ump_id) 317 { 318 hnd->ump_mem_handle = (int)ump_handle_create_from_secure_id(hnd->ump_id); 319 320 if ((int)UMP_INVALID_MEMORY_HANDLE == hnd->ump_mem_handle) 321 { 322 AINF("warning: unable to create UMP handle from secure ID %i\n", hnd->ump_id); 323 } 324 } 325 326 #endif 327 328 #if GRALLOC_ARM_DMA_BUF_MODULE 329 { 330 #ifdef FBIOGET_DMABUF 331 struct fb_dmabuf_export fb_dma_buf; 332 333 if (ioctl(m->framebuffer->fd, FBIOGET_DMABUF, &fb_dma_buf) == 0) 334 { 335 AINF("framebuffer accessed with dma buf (fd 0x%x)\n", (int)fb_dma_buf.fd); 336 hnd->share_fd = fb_dma_buf.fd; 337 } 338 339 #endif 340 } 341 #endif 342 343 *pHandle = hnd; 344 345 return 0; 346 } 347 348 static int gralloc_alloc_framebuffer(alloc_device_t *dev, size_t size, int usage, buffer_handle_t *pHandle) 349 { 350 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 351 pthread_mutex_lock(&m->lock); 352 int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle); 353 pthread_mutex_unlock(&m->lock); 354 return err; 355 } 356 357 static int alloc_device_alloc(alloc_device_t *dev, int w, int h, int format, int usage, buffer_handle_t *pHandle, int *pStride) 358 { 359 if (!pHandle || !pStride) 360 { 361 return -EINVAL; 362 } 363 364 size_t size; 365 size_t stride; 366 367 if (format == HAL_PIXEL_FORMAT_YCrCb_420_SP || format == HAL_PIXEL_FORMAT_YV12 368 /* HAL_PIXEL_FORMAT_YCbCr_420_SP, HAL_PIXEL_FORMAT_YCbCr_420_P, HAL_PIXEL_FORMAT_YCbCr_422_I are not defined in Android. 369 * To enable Mali DDK EGLImage support for those formats, firstly, you have to add them in Android system/core/include/system/graphics.h. 370 * Then, define SUPPORT_LEGACY_FORMAT in the same header file(Mali DDK will also check this definition). 371 */ 372 #ifdef SUPPORT_LEGACY_FORMAT 373 || format == HAL_PIXEL_FORMAT_YCbCr_420_SP || format == HAL_PIXEL_FORMAT_YCbCr_420_P || format == HAL_PIXEL_FORMAT_YCbCr_422_I 374 #endif 375 ) 376 { 377 switch (format) 378 { 379 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 380 stride = GRALLOC_ALIGN(w, 16); 381 size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16)); 382 break; 383 384 case HAL_PIXEL_FORMAT_YV12: 385 #ifdef SUPPORT_LEGACY_FORMAT 386 case HAL_PIXEL_FORMAT_YCbCr_420_P: 387 #endif 388 stride = GRALLOC_ALIGN(w, 16); 389 size = GRALLOC_ALIGN(h, 2) * (stride + GRALLOC_ALIGN(stride / 2, 16)); 390 391 break; 392 #ifdef SUPPORT_LEGACY_FORMAT 393 394 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 395 stride = GRALLOC_ALIGN(w, 16); 396 size = GRALLOC_ALIGN(h, 16) * (stride + GRALLOC_ALIGN(stride / 2, 16)); 397 break; 398 399 case HAL_PIXEL_FORMAT_YCbCr_422_I: 400 stride = GRALLOC_ALIGN(w, 16); 401 size = h * stride * 2; 402 403 break; 404 #endif 405 406 default: 407 return -EINVAL; 408 } 409 } 410 else 411 { 412 int bpp = 0; 413 414 switch (format) 415 { 416 case HAL_PIXEL_FORMAT_RGBA_8888: 417 case HAL_PIXEL_FORMAT_RGBX_8888: 418 case HAL_PIXEL_FORMAT_BGRA_8888: 419 bpp = 4; 420 break; 421 422 case HAL_PIXEL_FORMAT_RGB_888: 423 bpp = 3; 424 break; 425 426 case HAL_PIXEL_FORMAT_RGB_565: 427 #if PLATFORM_SDK_VERSION < 19 428 case HAL_PIXEL_FORMAT_RGBA_5551: 429 case HAL_PIXEL_FORMAT_RGBA_4444: 430 #endif 431 bpp = 2; 432 break; 433 434 default: 435 return -EINVAL; 436 } 437 438 size_t bpr = GRALLOC_ALIGN(w * bpp, 64); 439 size = bpr * h; 440 stride = bpr / bpp; 441 } 442 443 int err; 444 445 #ifndef MALI_600 446 447 if (usage & GRALLOC_USAGE_HW_FB) 448 { 449 err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); 450 } 451 else 452 #endif 453 454 { 455 err = gralloc_alloc_buffer(dev, size, usage, pHandle); 456 } 457 458 if (err < 0) 459 { 460 return err; 461 } 462 463 /* match the framebuffer format */ 464 if (usage & GRALLOC_USAGE_HW_FB) 465 { 466 #ifdef GRALLOC_16_BITS 467 format = HAL_PIXEL_FORMAT_RGB_565; 468 #else 469 format = HAL_PIXEL_FORMAT_BGRA_8888; 470 #endif 471 } 472 473 private_handle_t *hnd = (private_handle_t *)*pHandle; 474 int private_usage = usage & (GRALLOC_USAGE_PRIVATE_0 | 475 GRALLOC_USAGE_PRIVATE_1); 476 477 switch (private_usage) 478 { 479 case 0: 480 hnd->yuv_info = MALI_YUV_BT601_NARROW; 481 break; 482 483 case GRALLOC_USAGE_PRIVATE_1: 484 hnd->yuv_info = MALI_YUV_BT601_WIDE; 485 break; 486 487 case GRALLOC_USAGE_PRIVATE_0: 488 hnd->yuv_info = MALI_YUV_BT709_NARROW; 489 break; 490 491 case (GRALLOC_USAGE_PRIVATE_0 | GRALLOC_USAGE_PRIVATE_1): 492 hnd->yuv_info = MALI_YUV_BT709_WIDE; 493 break; 494 } 495 496 hnd->width = w; 497 hnd->height = h; 498 hnd->format = format; 499 hnd->stride = stride; 500 501 *pStride = stride; 502 return 0; 503 } 504 505 static int alloc_device_free(alloc_device_t *dev, buffer_handle_t handle) 506 { 507 if (private_handle_t::validate(handle) < 0) 508 { 509 return -EINVAL; 510 } 511 512 private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(handle); 513 514 if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) 515 { 516 // free this buffer 517 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 518 const size_t bufferSize = m->finfo.line_length * m->info.yres; 519 int index = ((uintptr_t)hnd->base - (uintptr_t)m->framebuffer->base) / bufferSize; 520 m->bufferMask &= ~(1 << index); 521 close(hnd->fd); 522 523 #if GRALLOC_ARM_UMP_MODULE 524 525 if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle) 526 { 527 ump_reference_release((ump_handle)hnd->ump_mem_handle); 528 } 529 530 #endif 531 } 532 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_UMP) 533 { 534 #if GRALLOC_ARM_UMP_MODULE 535 536 /* Buffer might be unregistered so we need to check for invalid ump handle*/ 537 if ((int)UMP_INVALID_MEMORY_HANDLE != hnd->ump_mem_handle) 538 { 539 ump_mapped_pointer_release((ump_handle)hnd->ump_mem_handle); 540 ump_reference_release((ump_handle)hnd->ump_mem_handle); 541 } 542 543 #else 544 AERR("Can't free ump memory for handle:0x%p. Not supported.", hnd); 545 #endif 546 } 547 else if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 548 { 549 #if GRALLOC_ARM_DMA_BUF_MODULE 550 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 551 552 /* Buffer might be unregistered so we need to check for invalid ump handle*/ 553 if (0 != hnd->base) 554 { 555 if (0 != munmap((void *)hnd->base, hnd->size)) 556 { 557 AERR("Failed to munmap handle 0x%p", hnd); 558 } 559 } 560 561 close(hnd->share_fd); 562 563 if (0 != ion_free(m->ion_client, hnd->ion_hnd)) 564 { 565 AERR("Failed to ion_free( ion_client: %d ion_hnd: %p )", m->ion_client, (void *)(uintptr_t)hnd->ion_hnd); 566 } 567 568 memset((void *)hnd, 0, sizeof(*hnd)); 569 #else 570 AERR("Can't free dma_buf memory for handle:0x%x. Not supported.", (unsigned int)hnd); 571 #endif 572 573 } 574 575 delete hnd; 576 577 return 0; 578 } 579 580 static int alloc_device_close(struct hw_device_t *device) 581 { 582 alloc_device_t *dev = reinterpret_cast<alloc_device_t *>(device); 583 584 if (dev) 585 { 586 #if GRALLOC_ARM_DMA_BUF_MODULE 587 private_module_t *m = reinterpret_cast<private_module_t *>(device); 588 589 if (0 != ion_close(m->ion_client)) 590 { 591 AERR("Failed to close ion_client: %d", m->ion_client); 592 } 593 594 close(m->ion_client); 595 #endif 596 delete dev; 597 #if GRALLOC_ARM_UMP_MODULE 598 ump_close(); // Our UMP memory refs will be released automatically here... 599 #endif 600 } 601 602 return 0; 603 } 604 605 int alloc_device_open(hw_module_t const *module, const char *name, hw_device_t **device) 606 { 607 MALI_IGNORE(name); 608 alloc_device_t *dev; 609 610 dev = new alloc_device_t; 611 612 if (NULL == dev) 613 { 614 return -1; 615 } 616 617 #if GRALLOC_ARM_UMP_MODULE 618 ump_result ump_res = ump_open(); 619 620 if (UMP_OK != ump_res) 621 { 622 AERR("UMP open failed with %d", ump_res); 623 delete dev; 624 return -1; 625 } 626 627 #endif 628 629 /* initialize our state here */ 630 memset(dev, 0, sizeof(*dev)); 631 632 /* initialize the procs */ 633 dev->common.tag = HARDWARE_DEVICE_TAG; 634 dev->common.version = 0; 635 dev->common.module = const_cast<hw_module_t *>(module); 636 dev->common.close = alloc_device_close; 637 dev->alloc = alloc_device_alloc; 638 dev->free = alloc_device_free; 639 640 #if GRALLOC_ARM_DMA_BUF_MODULE 641 private_module_t *m = reinterpret_cast<private_module_t *>(dev->common.module); 642 m->ion_client = ion_open(); 643 644 if (m->ion_client < 0) 645 { 646 AERR("ion_open failed with %s", strerror(errno)); 647 delete dev; 648 return -1; 649 } 650 651 #endif 652 653 *device = &dev->common; 654 655 return 0; 656 } 657