1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #define LOG_TAG "QCameraHWI_Mem" 31 32 // System dependencies 33 #include <fcntl.h> 34 #define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h> 35 #include MMAN_H 36 #include "gralloc_priv.h" 37 38 // Display dependencies 39 #include "qdMetaData.h" 40 41 // Camera dependencies 42 #include "QCamera3HWI.h" 43 #include "QCamera3Mem.h" 44 #include "QCameraTrace.h" 45 46 extern "C" { 47 #include "mm_camera_dbg.h" 48 #include "mm_camera_interface.h" 49 } 50 51 using namespace android; 52 53 namespace qcamera { 54 55 // QCaemra2Memory base class 56 57 /*=========================================================================== 58 * FUNCTION : QCamera3Memory 59 * 60 * DESCRIPTION: default constructor of QCamera3Memory 61 * 62 * PARAMETERS : none 63 * 64 * RETURN : None 65 *==========================================================================*/ 66 QCamera3Memory::QCamera3Memory() 67 { 68 mBufferCount = 0; 69 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 70 mMemInfo[i].fd = -1; 71 mMemInfo[i].handle = 0; 72 mMemInfo[i].size = 0; 73 mCurrentFrameNumbers[i] = -1; 74 } 75 main_ion_fd = open("/dev/ion", O_RDONLY); 76 } 77 78 /*=========================================================================== 79 * FUNCTION : ~QCamera3Memory 80 * 81 * DESCRIPTION: deconstructor of QCamera3Memory 82 * 83 * PARAMETERS : none 84 * 85 * RETURN : None 86 *==========================================================================*/ 87 QCamera3Memory::~QCamera3Memory() 88 { 89 close(main_ion_fd); 90 } 91 92 /*=========================================================================== 93 * FUNCTION : cacheOpsInternal 94 * 95 * DESCRIPTION: ion related memory cache operations 96 * 97 * PARAMETERS : 98 * @index : index of the buffer 99 * @cmd : cache ops command 100 * @vaddr : ptr to the virtual address 101 * 102 * RETURN : int32_t type of status 103 * NO_ERROR -- success 104 * none-zero failure code 105 *==========================================================================*/ 106 int QCamera3Memory::cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr) 107 { 108 Mutex::Autolock lock(mLock); 109 110 struct ion_flush_data cache_inv_data; 111 struct ion_custom_data custom_data; 112 int ret = OK; 113 114 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 115 LOGE("index %d out of bound [0, %d)", 116 index, MM_CAMERA_MAX_NUM_FRAMES); 117 return BAD_INDEX; 118 } 119 120 if (0 == mMemInfo[index].handle) { 121 LOGE("Buffer at %d not registered", index); 122 return BAD_INDEX; 123 } 124 125 memset(&cache_inv_data, 0, sizeof(cache_inv_data)); 126 memset(&custom_data, 0, sizeof(custom_data)); 127 cache_inv_data.vaddr = vaddr; 128 cache_inv_data.fd = mMemInfo[index].fd; 129 cache_inv_data.handle = mMemInfo[index].handle; 130 cache_inv_data.length = (unsigned int)mMemInfo[index].size; 131 custom_data.cmd = cmd; 132 custom_data.arg = (unsigned long)&cache_inv_data; 133 134 LOGD("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d", 135 cache_inv_data.vaddr, cache_inv_data.fd, 136 (unsigned long)cache_inv_data.handle, cache_inv_data.length, 137 main_ion_fd); 138 ret = ioctl(main_ion_fd, ION_IOC_CUSTOM, &custom_data); 139 if (ret < 0) 140 LOGE("Cache Invalidate failed: %s\n", strerror(errno)); 141 142 return ret; 143 } 144 145 /*=========================================================================== 146 * FUNCTION : getFd 147 * 148 * DESCRIPTION: return file descriptor of the indexed buffer 149 * 150 * PARAMETERS : 151 * @index : index of the buffer 152 * 153 * RETURN : file descriptor 154 *==========================================================================*/ 155 int QCamera3Memory::getFd(uint32_t index) 156 { 157 Mutex::Autolock lock(mLock); 158 159 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 160 return BAD_INDEX; 161 } 162 163 if (0 == mMemInfo[index].handle) { 164 return BAD_INDEX; 165 } 166 167 return mMemInfo[index].fd; 168 } 169 170 /*=========================================================================== 171 * FUNCTION : getSize 172 * 173 * DESCRIPTION: return buffer size of the indexed buffer 174 * 175 * PARAMETERS : 176 * @index : index of the buffer 177 * 178 * RETURN : buffer size 179 *==========================================================================*/ 180 ssize_t QCamera3Memory::getSize(uint32_t index) 181 { 182 Mutex::Autolock lock(mLock); 183 184 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 185 return BAD_INDEX; 186 } 187 188 if (0 == mMemInfo[index].handle) { 189 return BAD_INDEX; 190 } 191 192 return (ssize_t)mMemInfo[index].size; 193 } 194 195 /*=========================================================================== 196 * FUNCTION : getCnt 197 * 198 * DESCRIPTION: query number of buffers allocated 199 * 200 * PARAMETERS : none 201 * 202 * RETURN : number of buffers allocated 203 *==========================================================================*/ 204 uint32_t QCamera3Memory::getCnt() 205 { 206 Mutex::Autolock lock(mLock); 207 208 return mBufferCount; 209 } 210 211 /*=========================================================================== 212 * FUNCTION : getBufDef 213 * 214 * DESCRIPTION: query detailed buffer information 215 * 216 * PARAMETERS : 217 * @offset : [input] frame buffer offset 218 * @bufDef : [output] reference to struct to store buffer definition 219 * @index : [input] index of the buffer 220 * 221 * RETURN : int32_t type of status 222 * NO_ERROR -- success 223 * none-zero failure code 224 *==========================================================================*/ 225 int32_t QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset, 226 mm_camera_buf_def_t &bufDef, uint32_t index) 227 { 228 Mutex::Autolock lock(mLock); 229 230 if (!mBufferCount) { 231 LOGE("Memory not allocated"); 232 return NO_INIT; 233 } 234 235 bufDef.fd = mMemInfo[index].fd; 236 bufDef.frame_len = mMemInfo[index].size; 237 bufDef.mem_info = (void *)this; 238 bufDef.buffer = getPtrLocked(index); 239 bufDef.planes_buf.num_planes = (int8_t)offset.num_planes; 240 bufDef.buf_idx = (uint8_t)index; 241 242 /* Plane 0 needs to be set separately. Set other planes in a loop */ 243 bufDef.planes_buf.planes[0].length = offset.mp[0].len; 244 bufDef.planes_buf.planes[0].m.userptr = (long unsigned int)mMemInfo[index].fd; 245 bufDef.planes_buf.planes[0].data_offset = offset.mp[0].offset; 246 bufDef.planes_buf.planes[0].reserved[0] = 0; 247 for (int i = 1; i < bufDef.planes_buf.num_planes; i++) { 248 bufDef.planes_buf.planes[i].length = offset.mp[i].len; 249 bufDef.planes_buf.planes[i].m.userptr = (long unsigned int)mMemInfo[i].fd; 250 bufDef.planes_buf.planes[i].data_offset = offset.mp[i].offset; 251 bufDef.planes_buf.planes[i].reserved[0] = 252 bufDef.planes_buf.planes[i-1].reserved[0] + 253 bufDef.planes_buf.planes[i-1].length; 254 } 255 256 return NO_ERROR; 257 } 258 259 /*=========================================================================== 260 * FUNCTION : QCamera3HeapMemory 261 * 262 * DESCRIPTION: constructor of QCamera3HeapMemory for ion memory used internally in HAL 263 * 264 * PARAMETERS : none 265 * 266 * RETURN : none 267 *==========================================================================*/ 268 QCamera3HeapMemory::QCamera3HeapMemory(uint32_t maxCnt) 269 : QCamera3Memory() 270 { 271 mMaxCnt = MIN(maxCnt, MM_CAMERA_MAX_NUM_FRAMES); 272 for (uint32_t i = 0; i < mMaxCnt; i ++) 273 mPtr[i] = NULL; 274 } 275 276 /*=========================================================================== 277 * FUNCTION : ~QCamera3HeapMemory 278 * 279 * DESCRIPTION: deconstructor of QCamera3HeapMemory 280 * 281 * PARAMETERS : none 282 * 283 * RETURN : none 284 *==========================================================================*/ 285 QCamera3HeapMemory::~QCamera3HeapMemory() 286 { 287 } 288 289 /*=========================================================================== 290 * FUNCTION : allocOneBuffer 291 * 292 * DESCRIPTION: impl of allocating one buffers of certain size 293 * 294 * PARAMETERS : 295 * @memInfo : [output] reference to struct to store additional memory allocation info 296 * @heap : [input] heap id to indicate where the buffers will be allocated from 297 * @size : [input] lenght of the buffer to be allocated 298 * 299 * RETURN : int32_t type of status 300 * NO_ERROR -- success 301 * none-zero failure code 302 *==========================================================================*/ 303 int QCamera3HeapMemory::allocOneBuffer(QCamera3MemInfo &memInfo, 304 unsigned int heap_id, size_t size) 305 { 306 int rc = OK; 307 struct ion_handle_data handle_data; 308 struct ion_allocation_data allocData; 309 struct ion_fd_data ion_info_fd; 310 311 if (main_ion_fd < 0) { 312 LOGE("Ion dev open failed: %s\n", strerror(errno)); 313 goto ION_OPEN_FAILED; 314 } 315 316 memset(&allocData, 0, sizeof(allocData)); 317 allocData.len = size; 318 /* to make it page size aligned */ 319 allocData.len = (allocData.len + 4095U) & (~4095U); 320 allocData.align = 4096; 321 allocData.flags = ION_FLAG_CACHED; 322 allocData.heap_id_mask = heap_id; 323 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &allocData); 324 if (rc < 0) { 325 LOGE("ION allocation for len %d failed: %s\n", allocData.len, 326 strerror(errno)); 327 goto ION_ALLOC_FAILED; 328 } 329 330 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 331 ion_info_fd.handle = allocData.handle; 332 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd); 333 if (rc < 0) { 334 LOGE("ION map failed %s\n", strerror(errno)); 335 goto ION_MAP_FAILED; 336 } 337 338 memInfo.fd = ion_info_fd.fd; 339 memInfo.handle = ion_info_fd.handle; 340 memInfo.size = allocData.len; 341 return OK; 342 343 ION_MAP_FAILED: 344 memset(&handle_data, 0, sizeof(handle_data)); 345 handle_data.handle = ion_info_fd.handle; 346 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 347 ION_ALLOC_FAILED: 348 ION_OPEN_FAILED: 349 return NO_MEMORY; 350 } 351 352 /*=========================================================================== 353 * FUNCTION : deallocOneBuffer 354 * 355 * DESCRIPTION: impl of deallocating one buffers 356 * 357 * PARAMETERS : 358 * @memInfo : reference to struct that stores additional memory allocation info 359 * 360 * RETURN : none 361 *==========================================================================*/ 362 void QCamera3HeapMemory::deallocOneBuffer(QCamera3MemInfo &memInfo) 363 { 364 struct ion_handle_data handle_data; 365 366 if (memInfo.fd >= 0) { 367 close(memInfo.fd); 368 memInfo.fd = -1; 369 } 370 371 if (main_ion_fd >= 0) { 372 memset(&handle_data, 0, sizeof(handle_data)); 373 handle_data.handle = memInfo.handle; 374 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data); 375 } 376 memInfo.handle = 0; 377 memInfo.size = 0; 378 } 379 380 /*=========================================================================== 381 * FUNCTION : getPtrLocked 382 * 383 * DESCRIPTION: Return buffer pointer. 384 * 385 * PARAMETERS : 386 * @index : index of the buffer 387 * 388 * RETURN : buffer ptr 389 *==========================================================================*/ 390 void *QCamera3HeapMemory::getPtrLocked(uint32_t index) 391 { 392 if (index >= mBufferCount) { 393 LOGE("index out of bound"); 394 return (void *)BAD_INDEX; 395 } 396 return mPtr[index]; 397 } 398 399 /*=========================================================================== 400 * FUNCTION : markFrameNumber 401 * 402 * DESCRIPTION: We use this function from the request call path to mark the 403 * buffers with the frame number they are intended for this info 404 * is used later when giving out callback & it is duty of PP to 405 * ensure that data for that particular frameNumber/Request is 406 * written to this buffer. 407 * PARAMETERS : 408 * @index : index of the buffer 409 * @frame# : Frame number from the framework 410 * 411 * RETURN : int32_t type of status 412 * NO_ERROR -- success 413 * none-zero failure code 414 *==========================================================================*/ 415 int32_t QCamera3HeapMemory::markFrameNumber(uint32_t index, uint32_t frameNumber) 416 { 417 Mutex::Autolock lock(mLock); 418 419 if (index >= mBufferCount) { 420 LOGE("Index %d out of bounds, current buffer count is %d", 421 index, mBufferCount); 422 return BAD_INDEX; 423 } 424 425 if (0 == mMemInfo[index].handle) { 426 LOGE("Buffer at %d not allocated", index); 427 return BAD_INDEX; 428 } 429 430 mCurrentFrameNumbers[index] = (int32_t)frameNumber; 431 432 return NO_ERROR; 433 } 434 435 436 /*=========================================================================== 437 * FUNCTION : getFrameNumber 438 * 439 * DESCRIPTION: We use this to fetch the frameNumber for the request with which 440 * this buffer was given to HAL 441 * 442 * 443 * PARAMETERS : 444 * @index : index of the buffer 445 * 446 * RETURN : int32_t frameNumber 447 * positive/zero -- success 448 * negative failure 449 *==========================================================================*/ 450 int32_t QCamera3HeapMemory::getFrameNumber(uint32_t index) 451 { 452 Mutex::Autolock lock(mLock); 453 454 if (index >= mBufferCount) { 455 LOGE("Index %d out of bounds, current buffer count is %d", 456 index, mBufferCount); 457 return -1; 458 } 459 460 if (0 == mMemInfo[index].handle) { 461 LOGE("Buffer at %d not registered", index); 462 return -1; 463 } 464 465 return mCurrentFrameNumbers[index]; 466 } 467 468 469 /*=========================================================================== 470 * FUNCTION : getOldestFrameNumber 471 * 472 * DESCRIPTION: We use this to fetch the oldest frame number expected per FIFO 473 * 474 * 475 * PARAMETERS : 476 * 477 * 478 * RETURN : int32_t frameNumber 479 * negative failure 480 *==========================================================================*/ 481 int32_t QCamera3HeapMemory::getOldestFrameNumber(uint32_t &bufIndex) 482 { 483 Mutex::Autolock lock(mLock); 484 485 int32_t oldest = INT_MAX; 486 bool empty = true; 487 488 for (uint32_t index = 0; 489 index < mBufferCount; index++) { 490 if (mMemInfo[index].handle) { 491 if ((empty) || (!empty && oldest > mCurrentFrameNumbers[index] 492 && mCurrentFrameNumbers[index] != -1)) { 493 oldest = mCurrentFrameNumbers[index]; 494 bufIndex = index; 495 } 496 empty = false; 497 } 498 } 499 if (empty) 500 return -1; 501 else 502 return oldest; 503 } 504 505 506 /*=========================================================================== 507 * FUNCTION : getBufferIndex 508 * 509 * DESCRIPTION: We use this to fetch the buffer index for the request with 510 * a particular frame number 511 * 512 * 513 * PARAMETERS : 514 * @frameNumber : frame number of the buffer 515 * 516 * RETURN : int32_t buffer index 517 * negative failure 518 *==========================================================================*/ 519 int32_t QCamera3HeapMemory::getBufferIndex(uint32_t frameNumber) 520 { 521 Mutex::Autolock lock(mLock); 522 523 for (uint32_t index = 0; 524 index < mBufferCount; index++) { 525 if (mMemInfo[index].handle && 526 mCurrentFrameNumbers[index] == (int32_t)frameNumber) 527 return (int32_t)index; 528 } 529 return -1; 530 } 531 532 /*=========================================================================== 533 * FUNCTION : getPtr 534 * 535 * DESCRIPTION: Return buffer pointer 536 * 537 * PARAMETERS : 538 * @index : index of the buffer 539 * 540 * RETURN : buffer ptr 541 *==========================================================================*/ 542 void *QCamera3HeapMemory::getPtr(uint32_t index) 543 { 544 return getPtrLocked(index); 545 } 546 547 /*=========================================================================== 548 * FUNCTION : allocate 549 * 550 * DESCRIPTION: allocate requested number of buffers of certain size 551 * 552 * PARAMETERS : 553 * @size : lenght of the buffer to be allocated 554 * 555 * RETURN : int32_t type of status 556 * NO_ERROR -- success 557 * none-zero failure code 558 *==========================================================================*/ 559 int QCamera3HeapMemory::allocate(size_t size) 560 { 561 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 562 uint32_t i; 563 int rc = NO_ERROR; 564 565 //Note that now we allow incremental allocation. In other words, we allow 566 //multiple alloc being called as long as the sum of count does not exceed 567 //mMaxCnt. 568 if (mBufferCount > 0) { 569 LOGE("There is already buffer allocated."); 570 return BAD_INDEX; 571 } 572 573 for (i = 0; i < mMaxCnt; i ++) { 574 rc = allocOneBuffer(mMemInfo[i], heap_id_mask, size); 575 if (rc < 0) { 576 LOGE("AllocateIonMemory failed"); 577 goto ALLOC_FAILED; 578 } 579 580 void *vaddr = mmap(NULL, 581 mMemInfo[i].size, 582 PROT_READ | PROT_WRITE, 583 MAP_SHARED, 584 mMemInfo[i].fd, 0); 585 if (vaddr == MAP_FAILED) { 586 deallocOneBuffer(mMemInfo[i]); 587 LOGE("mmap failed for buffer %d", i); 588 goto ALLOC_FAILED; 589 } else 590 mPtr[i] = vaddr; 591 } 592 if (rc == 0) 593 mBufferCount = mMaxCnt; 594 595 return OK; 596 597 ALLOC_FAILED: 598 for (uint32_t j = 0; j < i; j++) { 599 munmap(mPtr[j], mMemInfo[j].size); 600 mPtr[j] = NULL; 601 deallocOneBuffer(mMemInfo[j]); 602 } 603 return NO_MEMORY; 604 } 605 606 /*=========================================================================== 607 * FUNCTION : allocateOne 608 * 609 * DESCRIPTION: allocate one buffer 610 * 611 * PARAMETERS : 612 * @size : lenght of the buffer to be allocated 613 * 614 * RETURN : int32_t type of status 615 * NO_ERROR -- success 616 * none-zero failure code 617 *==========================================================================*/ 618 int QCamera3HeapMemory::allocateOne(size_t size) 619 { 620 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 621 int rc = NO_ERROR; 622 623 //Note that now we allow incremental allocation. In other words, we allow 624 //multiple alloc being called as long as the sum of count does not exceed 625 //mMaxCnt. 626 if (mBufferCount + 1 > mMaxCnt) { 627 LOGE("Buffer count %d + 1 out of bound. Max is %d", 628 mBufferCount, mMaxCnt); 629 return BAD_INDEX; 630 } 631 632 rc = allocOneBuffer(mMemInfo[mBufferCount], heap_id_mask, size); 633 if (rc < 0) { 634 LOGE("AllocateIonMemory failed"); 635 return NO_MEMORY; 636 } 637 638 void *vaddr = mmap(NULL, 639 mMemInfo[mBufferCount].size, 640 PROT_READ | PROT_WRITE, 641 MAP_SHARED, 642 mMemInfo[mBufferCount].fd, 0); 643 if (vaddr == MAP_FAILED) { 644 deallocOneBuffer(mMemInfo[mBufferCount]); 645 LOGE("mmap failed for buffer"); 646 return NO_MEMORY; 647 } else 648 mPtr[mBufferCount] = vaddr; 649 650 if (rc == 0) 651 mBufferCount += 1; 652 653 return mBufferCount-1; 654 } 655 656 /*=========================================================================== 657 * FUNCTION : deallocate 658 * 659 * DESCRIPTION: deallocate buffers 660 * 661 * PARAMETERS : none 662 * 663 * RETURN : none 664 *==========================================================================*/ 665 void QCamera3HeapMemory::deallocate() 666 { 667 for (uint32_t i = 0; i < mBufferCount; i++) { 668 munmap(mPtr[i], mMemInfo[i].size); 669 mPtr[i] = NULL; 670 deallocOneBuffer(mMemInfo[i]); 671 mCurrentFrameNumbers[i] = -1; 672 } 673 mBufferCount = 0; 674 } 675 676 /*=========================================================================== 677 * FUNCTION : cacheOps 678 * 679 * DESCRIPTION: ion related memory cache operations 680 * 681 * PARAMETERS : 682 * @index : index of the buffer 683 * @cmd : cache ops command 684 * 685 * RETURN : int32_t type of status 686 * NO_ERROR -- success 687 * none-zero failure code 688 *==========================================================================*/ 689 int QCamera3HeapMemory::cacheOps(uint32_t index, unsigned int cmd) 690 { 691 if (index >= mBufferCount) 692 return BAD_INDEX; 693 return cacheOpsInternal(index, cmd, mPtr[index]); 694 } 695 696 /*=========================================================================== 697 * FUNCTION : getMatchBufIndex 698 * 699 * DESCRIPTION: query buffer index by object ptr 700 * 701 * PARAMETERS : 702 * @object : object ptr 703 * 704 * RETURN : buffer index if match found, 705 * -1 if failed 706 *==========================================================================*/ 707 int QCamera3HeapMemory::getMatchBufIndex(void * /*object*/) 708 { 709 710 /* 711 TODO for HEAP memory type, would there be an equivalent requirement? 712 713 int index = -1; 714 buffer_handle_t *key = (buffer_handle_t*) object; 715 if (!key) { 716 return BAD_VALUE; 717 } 718 for (int i = 0; i < mBufferCount; i++) { 719 if (mBufferHandle[i] == key) { 720 index = i; 721 break; 722 } 723 } 724 return index; 725 */ 726 LOGE("FATAL: Not supposed to come here"); 727 return -1; 728 } 729 730 /*=========================================================================== 731 * FUNCTION : QCamera3GrallocMemory 732 * 733 * DESCRIPTION: constructor of QCamera3GrallocMemory 734 * preview stream buffers are allocated from gralloc native_windoe 735 * 736 * PARAMETERS : 737 * @startIdx : start index of array after which we can register buffers in. 738 * 739 * RETURN : none 740 *==========================================================================*/ 741 QCamera3GrallocMemory::QCamera3GrallocMemory(uint32_t startIdx) 742 : QCamera3Memory(), mStartIdx(startIdx) 743 { 744 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) { 745 mBufferHandle[i] = NULL; 746 mPrivateHandle[i] = NULL; 747 } 748 } 749 750 /*=========================================================================== 751 * FUNCTION : ~QCamera3GrallocMemory 752 * 753 * DESCRIPTION: deconstructor of QCamera3GrallocMemory 754 * 755 * PARAMETERS : none 756 * 757 * RETURN : none 758 *==========================================================================*/ 759 QCamera3GrallocMemory::~QCamera3GrallocMemory() 760 { 761 } 762 763 /*=========================================================================== 764 * FUNCTION : registerBuffer 765 * 766 * DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t 767 * 768 * PARAMETERS : 769 * @buffers : buffer_handle_t pointer 770 * @type : cam_stream_type_t 771 * 772 * RETURN : int32_t type of status 773 * NO_ERROR -- success 774 * none-zero failure code 775 *==========================================================================*/ 776 int QCamera3GrallocMemory::registerBuffer(buffer_handle_t *buffer, 777 __unused cam_stream_type_t type) 778 { 779 status_t ret = NO_ERROR; 780 struct ion_fd_data ion_info_fd; 781 void *vaddr = NULL; 782 int32_t colorSpace = ITU_R_601_FR; 783 int32_t idx = -1; 784 785 LOGD("E"); 786 787 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 788 789 if (0 <= getMatchBufIndex((void *) buffer)) { 790 LOGL("Buffer already registered"); 791 return ALREADY_EXISTS; 792 } 793 794 Mutex::Autolock lock(mLock); 795 if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1 - mStartIdx)) { 796 LOGE("Number of buffers %d greater than what's supported %d", 797 mBufferCount, MM_CAMERA_MAX_NUM_FRAMES - mStartIdx); 798 return BAD_INDEX; 799 } 800 801 idx = getFreeIndexLocked(); 802 if (0 > idx) { 803 LOGE("No available memory slots"); 804 return BAD_INDEX; 805 } 806 807 mBufferHandle[idx] = buffer; 808 mPrivateHandle[idx] = (struct private_handle_t *)(*mBufferHandle[idx]); 809 810 setMetaData(mPrivateHandle[idx], UPDATE_COLOR_SPACE, &colorSpace); 811 812 if (main_ion_fd < 0) { 813 LOGE("failed: could not open ion device"); 814 ret = NO_MEMORY; 815 goto end; 816 } else { 817 ion_info_fd.fd = mPrivateHandle[idx]->fd; 818 if (ioctl(main_ion_fd, 819 ION_IOC_IMPORT, &ion_info_fd) < 0) { 820 LOGE("ION import failed\n"); 821 ret = NO_MEMORY; 822 goto end; 823 } 824 } 825 LOGD("idx = %d, fd = %d, size = %d, offset = %d", 826 idx, mPrivateHandle[idx]->fd, 827 mPrivateHandle[idx]->size, 828 mPrivateHandle[idx]->offset); 829 mMemInfo[idx].fd = mPrivateHandle[idx]->fd; 830 mMemInfo[idx].size = 831 ( /* FIXME: Should update ION interface */ size_t) 832 mPrivateHandle[idx]->size; 833 mMemInfo[idx].handle = ion_info_fd.handle; 834 835 vaddr = mmap(NULL, 836 mMemInfo[idx].size, 837 PROT_READ | PROT_WRITE, 838 MAP_SHARED, 839 mMemInfo[idx].fd, 0); 840 if (vaddr == MAP_FAILED) { 841 mMemInfo[idx].handle = 0; 842 ret = NO_MEMORY; 843 } else { 844 mPtr[idx] = vaddr; 845 mBufferCount++; 846 } 847 848 end: 849 LOGD("X "); 850 return ret; 851 } 852 /*=========================================================================== 853 * FUNCTION : unregisterBufferLocked 854 * 855 * DESCRIPTION: Unregister buffer. Please note that this method has to be 856 * called with 'mLock' acquired. 857 * 858 * PARAMETERS : 859 * @idx : unregister buffer at index 'idx' 860 * 861 * RETURN : int32_t type of status 862 * NO_ERROR -- success 863 * none-zero failure code 864 *==========================================================================*/ 865 int32_t QCamera3GrallocMemory::unregisterBufferLocked(size_t idx) 866 { 867 munmap(mPtr[idx], mMemInfo[idx].size); 868 mPtr[idx] = NULL; 869 870 struct ion_handle_data ion_handle; 871 memset(&ion_handle, 0, sizeof(ion_handle)); 872 ion_handle.handle = mMemInfo[idx].handle; 873 if (ioctl(main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 874 LOGE("ion free failed"); 875 } 876 memset(&mMemInfo[idx], 0, sizeof(struct QCamera3MemInfo)); 877 mBufferHandle[idx] = NULL; 878 mPrivateHandle[idx] = NULL; 879 mCurrentFrameNumbers[idx] = -1; 880 mBufferCount--; 881 882 return NO_ERROR; 883 } 884 885 /*=========================================================================== 886 * FUNCTION : unregisterBuffer 887 * 888 * DESCRIPTION: unregister buffer 889 * 890 * PARAMETERS : 891 * @idx : unregister buffer at index 'idx' 892 * 893 * RETURN : int32_t type of status 894 * NO_ERROR -- success 895 * none-zero failure code 896 *==========================================================================*/ 897 int32_t QCamera3GrallocMemory::unregisterBuffer(size_t idx) 898 { 899 int32_t rc = NO_ERROR; 900 Mutex::Autolock lock(mLock); 901 902 LOGD("E ", __FUNCTION__); 903 904 if (MM_CAMERA_MAX_NUM_FRAMES <= idx) { 905 LOGE("Buffer index %d greater than what is supported %d", 906 idx, MM_CAMERA_MAX_NUM_FRAMES); 907 return BAD_VALUE; 908 } 909 if (idx < mStartIdx) { 910 LOGE("buffer index %d less than starting index %d", 911 idx, mStartIdx); 912 return BAD_INDEX; 913 } 914 915 if (0 == mMemInfo[idx].handle) { 916 LOGE("Trying to unregister buffer at %d which still not registered", 917 idx); 918 return BAD_VALUE; 919 } 920 921 rc = unregisterBufferLocked(idx); 922 923 LOGD("X ",__FUNCTION__); 924 925 return rc; 926 } 927 928 /*=========================================================================== 929 * FUNCTION : unregisterBuffers 930 * 931 * DESCRIPTION: unregister buffers 932 * 933 * PARAMETERS : none 934 * 935 * RETURN : none 936 *==========================================================================*/ 937 void QCamera3GrallocMemory::unregisterBuffers() 938 { 939 int err = NO_ERROR; 940 Mutex::Autolock lock(mLock); 941 942 LOGD("E ", __FUNCTION__); 943 944 for (uint32_t cnt = mStartIdx; cnt < MM_CAMERA_MAX_NUM_FRAMES; cnt++) { 945 if (0 == mMemInfo[cnt].handle) { 946 continue; 947 } 948 err = unregisterBufferLocked(cnt); 949 if (NO_ERROR != err) { 950 LOGE("Error unregistering buffer %d error %d", 951 cnt, err); 952 } 953 } 954 mBufferCount = 0; 955 LOGD("X ",__FUNCTION__); 956 } 957 958 /*=========================================================================== 959 * FUNCTION : markFrameNumber 960 * 961 * DESCRIPTION: We use this function from the request call path to mark the 962 * buffers with the frame number they are intended for this info 963 * is used later when giving out callback & it is duty of PP to 964 * ensure that data for that particular frameNumber/Request is 965 * written to this buffer. 966 * PARAMETERS : 967 * @index : index of the buffer 968 * @frame# : Frame number from the framework 969 * 970 * RETURN : int32_t type of status 971 * NO_ERROR -- success 972 * none-zero failure code 973 *==========================================================================*/ 974 int32_t QCamera3GrallocMemory::markFrameNumber(uint32_t index, uint32_t frameNumber) 975 { 976 Mutex::Autolock lock(mLock); 977 978 if (index >= MM_CAMERA_MAX_NUM_FRAMES) { 979 LOGE("Index out of bounds"); 980 return BAD_INDEX; 981 } 982 if (index < mStartIdx) { 983 LOGE("buffer index %d less than starting index %d", 984 index, mStartIdx); 985 return BAD_INDEX; 986 } 987 988 if (0 == mMemInfo[index].handle) { 989 LOGE("Buffer at %d not registered", index); 990 return BAD_INDEX; 991 } 992 993 mCurrentFrameNumbers[index] = (int32_t)frameNumber; 994 995 return NO_ERROR; 996 } 997 998 /*=========================================================================== 999 * FUNCTION : getFrameNumber 1000 * 1001 * DESCRIPTION: We use this to fetch the frameNumber for the request with which 1002 * this buffer was given to HAL 1003 * 1004 * 1005 * PARAMETERS : 1006 * @index : index of the buffer 1007 * 1008 * RETURN : int32_t frameNumber 1009 * positive/zero -- success 1010 * negative failure 1011 *==========================================================================*/ 1012 int32_t QCamera3GrallocMemory::getFrameNumber(uint32_t index) 1013 { 1014 Mutex::Autolock lock(mLock); 1015 1016 if (index >= MM_CAMERA_MAX_NUM_FRAMES) { 1017 LOGE("Index out of bounds"); 1018 return -1; 1019 } 1020 if (index < mStartIdx) { 1021 LOGE("buffer index %d less than starting index %d", 1022 index, mStartIdx); 1023 return BAD_INDEX; 1024 } 1025 1026 if (0 == mMemInfo[index].handle) { 1027 LOGE("Buffer at %d not registered", index); 1028 return -1; 1029 } 1030 1031 return mCurrentFrameNumbers[index]; 1032 } 1033 1034 /*=========================================================================== 1035 * FUNCTION : getOldestFrameNumber 1036 * 1037 * DESCRIPTION: We use this to fetch the oldest frame number expected per FIFO 1038 * 1039 * 1040 * PARAMETERS : 1041 * 1042 * 1043 * RETURN : int32_t frameNumber 1044 * negative failure 1045 *==========================================================================*/ 1046 int32_t QCamera3GrallocMemory::getOldestFrameNumber(uint32_t &bufIndex) 1047 { 1048 int32_t oldest = INT_MAX; 1049 bool empty = true; 1050 for (uint32_t index = mStartIdx; 1051 index < MM_CAMERA_MAX_NUM_FRAMES; index++) { 1052 if (mMemInfo[index].handle) { 1053 if ((empty) || 1054 (!empty && oldest > mCurrentFrameNumbers[index] 1055 && mCurrentFrameNumbers[index] != -1)) { 1056 oldest = mCurrentFrameNumbers[index]; 1057 bufIndex = index; 1058 } 1059 empty = false; 1060 } 1061 } 1062 if (empty) 1063 return -1; 1064 else 1065 return oldest; 1066 } 1067 1068 1069 /*=========================================================================== 1070 * FUNCTION : getBufferIndex 1071 * 1072 * DESCRIPTION: We use this to fetch the buffer index for the request with 1073 * a particular frame number 1074 * 1075 * 1076 * PARAMETERS : 1077 * @frameNumber : frame number of the buffer 1078 * 1079 * RETURN : int32_t buffer index 1080 * negative failure 1081 *==========================================================================*/ 1082 int32_t QCamera3GrallocMemory::getBufferIndex(uint32_t frameNumber) 1083 { 1084 for (uint32_t index = mStartIdx; 1085 index < MM_CAMERA_MAX_NUM_FRAMES; index++) { 1086 if (mMemInfo[index].handle && 1087 mCurrentFrameNumbers[index] == (int32_t)frameNumber) 1088 return (int32_t)index; 1089 } 1090 return -1; 1091 } 1092 1093 /*=========================================================================== 1094 * FUNCTION : cacheOps 1095 * 1096 * DESCRIPTION: ion related memory cache operations 1097 * 1098 * PARAMETERS : 1099 * @index : index of the buffer 1100 * @cmd : cache ops command 1101 * 1102 * RETURN : int32_t type of status 1103 * NO_ERROR -- success 1104 * none-zero failure code 1105 *==========================================================================*/ 1106 int QCamera3GrallocMemory::cacheOps(uint32_t index, unsigned int cmd) 1107 { 1108 if (index >= MM_CAMERA_MAX_NUM_FRAMES) { 1109 LOGE("Index out of bounds"); 1110 return -1; 1111 } 1112 if (index < mStartIdx) { 1113 LOGE("buffer index %d less than starting index %d", 1114 index, mStartIdx); 1115 return BAD_INDEX; 1116 } 1117 1118 return cacheOpsInternal(index, cmd, mPtr[index]); 1119 } 1120 1121 /*=========================================================================== 1122 * FUNCTION : getMatchBufIndex 1123 * 1124 * DESCRIPTION: query buffer index by object ptr 1125 * 1126 * PARAMETERS : 1127 * @opaque : opaque ptr 1128 * 1129 * RETURN : buffer index if match found, 1130 * -1 if failed 1131 *==========================================================================*/ 1132 int QCamera3GrallocMemory::getMatchBufIndex(void *object) 1133 { 1134 Mutex::Autolock lock(mLock); 1135 1136 int index = -1; 1137 buffer_handle_t *key = (buffer_handle_t*) object; 1138 if (!key) { 1139 return BAD_VALUE; 1140 } 1141 for (uint32_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 1142 if (mBufferHandle[i] == key) { 1143 index = (int)i; 1144 break; 1145 } 1146 } 1147 1148 return index; 1149 } 1150 1151 /*=========================================================================== 1152 * FUNCTION : getFreeIndexLocked 1153 * 1154 * DESCRIPTION: Find free index slot. Note 'mLock' needs to be acquired 1155 * before calling this method. 1156 * 1157 * PARAMETERS : None 1158 * 1159 * RETURN : free buffer index if found, 1160 * -1 if failed 1161 *==========================================================================*/ 1162 int QCamera3GrallocMemory::getFreeIndexLocked() 1163 { 1164 int index = -1; 1165 1166 if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1)) { 1167 LOGE("Number of buffers %d greater than what's supported %d", 1168 mBufferCount, MM_CAMERA_MAX_NUM_FRAMES); 1169 return index; 1170 } 1171 1172 for (size_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 1173 if (0 == mMemInfo[i].handle) { 1174 index = i; 1175 break; 1176 } 1177 } 1178 1179 return index; 1180 } 1181 1182 /*=========================================================================== 1183 * FUNCTION : getPtrLocked 1184 * 1185 * DESCRIPTION: Return buffer pointer. Please note 'mLock' must be acquired 1186 * before calling this method. 1187 * 1188 * PARAMETERS : 1189 * @index : index of the buffer 1190 * 1191 * RETURN : buffer ptr 1192 *==========================================================================*/ 1193 void *QCamera3GrallocMemory::getPtrLocked(uint32_t index) 1194 { 1195 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 1196 LOGE("index %d out of bound [0, %d)", 1197 index, MM_CAMERA_MAX_NUM_FRAMES); 1198 return NULL; 1199 } 1200 if (index < mStartIdx) { 1201 LOGE("buffer index %d less than starting index %d", 1202 index, mStartIdx); 1203 return NULL; 1204 } 1205 1206 1207 if (0 == mMemInfo[index].handle) { 1208 LOGE("Buffer at %d not registered", index); 1209 return NULL; 1210 } 1211 1212 return mPtr[index]; 1213 } 1214 1215 /*=========================================================================== 1216 * FUNCTION : getPtr 1217 * 1218 * DESCRIPTION: Return buffer pointer. 1219 * 1220 * PARAMETERS : 1221 * @index : index of the buffer 1222 * 1223 * RETURN : buffer ptr 1224 *==========================================================================*/ 1225 void *QCamera3GrallocMemory::getPtr(uint32_t index) 1226 { 1227 Mutex::Autolock lock(mLock); 1228 return getPtrLocked(index); 1229 } 1230 1231 /*=========================================================================== 1232 * FUNCTION : getBufferHandle 1233 * 1234 * DESCRIPTION: return framework pointer 1235 * 1236 * PARAMETERS : 1237 * @index : index of the buffer 1238 * 1239 * RETURN : buffer ptr if match found 1240 NULL if failed 1241 *==========================================================================*/ 1242 void *QCamera3GrallocMemory::getBufferHandle(uint32_t index) 1243 { 1244 Mutex::Autolock lock(mLock); 1245 1246 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 1247 LOGE("index %d out of bound [0, %d)", 1248 index, MM_CAMERA_MAX_NUM_FRAMES); 1249 return NULL; 1250 } 1251 if (index < mStartIdx) { 1252 LOGE("buffer index %d less than starting index %d", 1253 index, mStartIdx); 1254 return NULL; 1255 } 1256 1257 if (0 == mMemInfo[index].handle) { 1258 LOGE("Buffer at %d not registered", index); 1259 return NULL; 1260 } 1261 1262 return mBufferHandle[index]; 1263 } 1264 }; //namespace qcamera 1265