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