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