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