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 (void *)BAD_INDEX; 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 * FUNCTION : getFrameNumber 442 * 443 * DESCRIPTION: We use this to fetch the frameNumber for the request with which 444 * this buffer was given to HAL 445 * 446 * 447 * PARAMETERS : 448 * @index : index of the buffer 449 * 450 * RETURN : int32_t frameNumber 451 * positive/zero -- success 452 * negative failure 453 *==========================================================================*/ 454int32_t QCamera3HeapMemory::getFrameNumber(uint32_t index) 455{ 456 Mutex::Autolock lock(mLock); 457 458 if (index >= mBufferCount) { 459 LOGE("Index %d out of bounds, current buffer count is %d", 460 index, mBufferCount); 461 return -1; 462 } 463 464 if (0 == mMemInfo[index].handle) { 465 LOGE("Buffer at %d not registered", index); 466 return -1; 467 } 468 469 return mCurrentFrameNumbers[index]; 470} 471 472/*=========================================================================== 473 * FUNCTION : getBufferIndex 474 * 475 * DESCRIPTION: We use this to fetch the buffer index for the request with 476 * a particular frame number 477 * 478 * 479 * PARAMETERS : 480 * @frameNumber : frame number of the buffer 481 * 482 * RETURN : int32_t buffer index 483 * negative failure 484 *==========================================================================*/ 485int32_t QCamera3HeapMemory::getBufferIndex(uint32_t frameNumber) 486{ 487 Mutex::Autolock lock(mLock); 488 489 for (uint32_t index = 0; 490 index < mBufferCount; index++) { 491 if (mMemInfo[index].handle && 492 mCurrentFrameNumbers[index] == (int32_t)frameNumber) 493 return (int32_t)index; 494 } 495 return -1; 496} 497 498/*=========================================================================== 499 * FUNCTION : getPtr 500 * 501 * DESCRIPTION: Return buffer pointer 502 * 503 * PARAMETERS : 504 * @index : index of the buffer 505 * 506 * RETURN : buffer ptr 507 *==========================================================================*/ 508void *QCamera3HeapMemory::getPtr(uint32_t index) 509{ 510 return getPtrLocked(index); 511} 512 513/*=========================================================================== 514 * FUNCTION : allocate 515 * 516 * DESCRIPTION: allocate requested number of buffers of certain size 517 * 518 * PARAMETERS : 519 * @size : lenght of the buffer to be allocated 520 * 521 * RETURN : int32_t type of status 522 * NO_ERROR -- success 523 * none-zero failure code 524 *==========================================================================*/ 525int QCamera3HeapMemory::allocate(size_t size) 526{ 527 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 528 uint32_t i; 529 int rc = NO_ERROR; 530 531 //Note that now we allow incremental allocation. In other words, we allow 532 //multiple alloc being called as long as the sum of count does not exceed 533 //mMaxCnt. 534 if (mBufferCount > 0) { 535 LOGE("There is already buffer allocated."); 536 return BAD_INDEX; 537 } 538 539 for (i = 0; i < mMaxCnt; i ++) { 540 rc = allocOneBuffer(mMemInfo[i], heap_id_mask, size); 541 if (rc < 0) { 542 LOGE("AllocateIonMemory failed"); 543 goto ALLOC_FAILED; 544 } 545 546 void *vaddr = mmap(NULL, 547 mMemInfo[i].size, 548 PROT_READ | PROT_WRITE, 549 MAP_SHARED, 550 mMemInfo[i].fd, 0); 551 if (vaddr == MAP_FAILED) { 552 deallocOneBuffer(mMemInfo[i]); 553 LOGE("mmap failed for buffer %d", i); 554 goto ALLOC_FAILED; 555 } else 556 mPtr[i] = vaddr; 557 } 558 if (rc == 0) 559 mBufferCount = mMaxCnt; 560 561 return OK; 562 563ALLOC_FAILED: 564 for (uint32_t j = 0; j < i; j++) { 565 munmap(mPtr[j], mMemInfo[j].size); 566 mPtr[j] = NULL; 567 deallocOneBuffer(mMemInfo[j]); 568 } 569 return NO_MEMORY; 570} 571 572/*=========================================================================== 573 * FUNCTION : allocateOne 574 * 575 * DESCRIPTION: allocate one buffer 576 * 577 * PARAMETERS : 578 * @size : lenght of the buffer to be allocated 579 * 580 * RETURN : int32_t type of status 581 * NO_ERROR -- success 582 * none-zero failure code 583 *==========================================================================*/ 584int QCamera3HeapMemory::allocateOne(size_t size) 585{ 586 unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID; 587 int rc = NO_ERROR; 588 589 //Note that now we allow incremental allocation. In other words, we allow 590 //multiple alloc being called as long as the sum of count does not exceed 591 //mMaxCnt. 592 if (mBufferCount + 1 > mMaxCnt) { 593 LOGE("Buffer count %d + 1 out of bound. Max is %d", 594 mBufferCount, mMaxCnt); 595 return BAD_INDEX; 596 } 597 598 rc = allocOneBuffer(mMemInfo[mBufferCount], heap_id_mask, size); 599 if (rc < 0) { 600 LOGE("AllocateIonMemory failed"); 601 return NO_MEMORY; 602 } 603 604 void *vaddr = mmap(NULL, 605 mMemInfo[mBufferCount].size, 606 PROT_READ | PROT_WRITE, 607 MAP_SHARED, 608 mMemInfo[mBufferCount].fd, 0); 609 if (vaddr == MAP_FAILED) { 610 deallocOneBuffer(mMemInfo[mBufferCount]); 611 LOGE("mmap failed for buffer"); 612 return NO_MEMORY; 613 } else 614 mPtr[mBufferCount] = vaddr; 615 616 if (rc == 0) 617 mBufferCount += 1; 618 619 return mBufferCount-1; 620} 621 622/*=========================================================================== 623 * FUNCTION : deallocate 624 * 625 * DESCRIPTION: deallocate buffers 626 * 627 * PARAMETERS : none 628 * 629 * RETURN : none 630 *==========================================================================*/ 631void QCamera3HeapMemory::deallocate() 632{ 633 for (uint32_t i = 0; i < mBufferCount; i++) { 634 munmap(mPtr[i], mMemInfo[i].size); 635 mPtr[i] = NULL; 636 deallocOneBuffer(mMemInfo[i]); 637 mCurrentFrameNumbers[i] = -1; 638 } 639 mBufferCount = 0; 640} 641 642/*=========================================================================== 643 * FUNCTION : cacheOps 644 * 645 * DESCRIPTION: ion related memory cache operations 646 * 647 * PARAMETERS : 648 * @index : index of the buffer 649 * @cmd : cache ops command 650 * 651 * RETURN : int32_t type of status 652 * NO_ERROR -- success 653 * none-zero failure code 654 *==========================================================================*/ 655int QCamera3HeapMemory::cacheOps(uint32_t index, unsigned int cmd) 656{ 657 if (index >= mBufferCount) 658 return BAD_INDEX; 659 return cacheOpsInternal(index, cmd, mPtr[index]); 660} 661 662/*=========================================================================== 663 * FUNCTION : getMatchBufIndex 664 * 665 * DESCRIPTION: query buffer index by object ptr 666 * 667 * PARAMETERS : 668 * @object : object ptr 669 * 670 * RETURN : buffer index if match found, 671 * -1 if failed 672 *==========================================================================*/ 673int QCamera3HeapMemory::getMatchBufIndex(void * /*object*/) 674{ 675 676/* 677 TODO for HEAP memory type, would there be an equivalent requirement? 678 679 int index = -1; 680 buffer_handle_t *key = (buffer_handle_t*) object; 681 if (!key) { 682 return BAD_VALUE; 683 } 684 for (int i = 0; i < mBufferCount; i++) { 685 if (mBufferHandle[i] == key) { 686 index = i; 687 break; 688 } 689 } 690 return index; 691*/ 692 LOGE("FATAL: Not supposed to come here"); 693 return -1; 694} 695 696/*=========================================================================== 697 * FUNCTION : QCamera3GrallocMemory 698 * 699 * DESCRIPTION: constructor of QCamera3GrallocMemory 700 * preview stream buffers are allocated from gralloc native_windoe 701 * 702 * PARAMETERS : 703 * @startIdx : start index of array after which we can register buffers in. 704 * 705 * RETURN : none 706 *==========================================================================*/ 707QCamera3GrallocMemory::QCamera3GrallocMemory(uint32_t startIdx) 708 : QCamera3Memory(), mStartIdx(startIdx) 709{ 710 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) { 711 mBufferHandle[i] = NULL; 712 mPrivateHandle[i] = NULL; 713 } 714} 715 716/*=========================================================================== 717 * FUNCTION : ~QCamera3GrallocMemory 718 * 719 * DESCRIPTION: deconstructor of QCamera3GrallocMemory 720 * 721 * PARAMETERS : none 722 * 723 * RETURN : none 724 *==========================================================================*/ 725QCamera3GrallocMemory::~QCamera3GrallocMemory() 726{ 727} 728 729/*=========================================================================== 730 * FUNCTION : registerBuffer 731 * 732 * DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t 733 * 734 * PARAMETERS : 735 * @buffers : buffer_handle_t pointer 736 * @type : cam_stream_type_t 737 * 738 * RETURN : int32_t type of status 739 * NO_ERROR -- success 740 * none-zero failure code 741 *==========================================================================*/ 742int QCamera3GrallocMemory::registerBuffer(buffer_handle_t *buffer, 743 __unused cam_stream_type_t type) 744{ 745 status_t ret = NO_ERROR; 746 struct ion_fd_data ion_info_fd; 747 void *vaddr = NULL; 748 int32_t colorSpace = ITU_R_601_FR; 749 int32_t idx = -1; 750 751 LOGD("E"); 752 753 memset(&ion_info_fd, 0, sizeof(ion_info_fd)); 754 755 if (0 <= getMatchBufIndex((void *) buffer)) { 756 LOGL("Buffer already registered"); 757 return ALREADY_EXISTS; 758 } 759 760 Mutex::Autolock lock(mLock); 761 if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1 - mStartIdx)) { 762 LOGE("Number of buffers %d greater than what's supported %d", 763 mBufferCount, MM_CAMERA_MAX_NUM_FRAMES - mStartIdx); 764 return BAD_INDEX; 765 } 766 767 idx = getFreeIndexLocked(); 768 if (0 > idx) { 769 LOGE("No available memory slots"); 770 return BAD_INDEX; 771 } 772 773 mBufferHandle[idx] = buffer; 774 mPrivateHandle[idx] = (struct private_handle_t *)(*mBufferHandle[idx]); 775 776 setMetaData(mPrivateHandle[idx], UPDATE_COLOR_SPACE, &colorSpace); 777 778 mMemInfo[idx].main_ion_fd = open("/dev/ion", O_RDONLY); 779 if (mMemInfo[idx].main_ion_fd < 0) { 780 LOGE("failed: could not open ion device"); 781 ret = NO_MEMORY; 782 goto end; 783 } else { 784 ion_info_fd.fd = mPrivateHandle[idx]->fd; 785 if (ioctl(mMemInfo[idx].main_ion_fd, 786 ION_IOC_IMPORT, &ion_info_fd) < 0) { 787 LOGE("ION import failed\n"); 788 close(mMemInfo[idx].main_ion_fd); 789 ret = NO_MEMORY; 790 goto end; 791 } 792 } 793 LOGD("idx = %d, fd = %d, size = %d, offset = %d", 794 idx, mPrivateHandle[idx]->fd, 795 mPrivateHandle[idx]->size, 796 mPrivateHandle[idx]->offset); 797 mMemInfo[idx].fd = mPrivateHandle[idx]->fd; 798 mMemInfo[idx].size = 799 ( /* FIXME: Should update ION interface */ size_t) 800 mPrivateHandle[idx]->size; 801 mMemInfo[idx].handle = ion_info_fd.handle; 802 803 vaddr = mmap(NULL, 804 mMemInfo[idx].size, 805 PROT_READ | PROT_WRITE, 806 MAP_SHARED, 807 mMemInfo[idx].fd, 0); 808 if (vaddr == MAP_FAILED) { 809 mMemInfo[idx].handle = 0; 810 ret = NO_MEMORY; 811 } else { 812 mPtr[idx] = vaddr; 813 mBufferCount++; 814 } 815 816end: 817 LOGD("X "); 818 return ret; 819} 820/*=========================================================================== 821 * FUNCTION : unregisterBufferLocked 822 * 823 * DESCRIPTION: Unregister buffer. Please note that this method has to be 824 * called with 'mLock' acquired. 825 * 826 * PARAMETERS : 827 * @idx : unregister buffer at index 'idx' 828 * 829 * RETURN : int32_t type of status 830 * NO_ERROR -- success 831 * none-zero failure code 832 *==========================================================================*/ 833int32_t QCamera3GrallocMemory::unregisterBufferLocked(size_t idx) 834{ 835 munmap(mPtr[idx], mMemInfo[idx].size); 836 mPtr[idx] = NULL; 837 838 struct ion_handle_data ion_handle; 839 memset(&ion_handle, 0, sizeof(ion_handle)); 840 ion_handle.handle = mMemInfo[idx].handle; 841 if (ioctl(mMemInfo[idx].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) { 842 LOGE("ion free failed"); 843 } 844 close(mMemInfo[idx].main_ion_fd); 845 memset(&mMemInfo[idx], 0, sizeof(struct QCamera3MemInfo)); 846 mMemInfo[idx].main_ion_fd = -1; 847 mBufferHandle[idx] = NULL; 848 mPrivateHandle[idx] = NULL; 849 mCurrentFrameNumbers[idx] = -1; 850 mBufferCount--; 851 852 return NO_ERROR; 853} 854 855/*=========================================================================== 856 * FUNCTION : unregisterBuffer 857 * 858 * DESCRIPTION: unregister buffer 859 * 860 * PARAMETERS : 861 * @idx : unregister buffer at index 'idx' 862 * 863 * RETURN : int32_t type of status 864 * NO_ERROR -- success 865 * none-zero failure code 866 *==========================================================================*/ 867int32_t QCamera3GrallocMemory::unregisterBuffer(size_t idx) 868{ 869 int32_t rc = NO_ERROR; 870 Mutex::Autolock lock(mLock); 871 872 LOGD("E ", __FUNCTION__); 873 874 if (MM_CAMERA_MAX_NUM_FRAMES <= idx) { 875 LOGE("Buffer index %d greater than what is supported %d", 876 idx, MM_CAMERA_MAX_NUM_FRAMES); 877 return BAD_VALUE; 878 } 879 if (idx < mStartIdx) { 880 LOGE("buffer index %d less than starting index %d", 881 idx, mStartIdx); 882 return BAD_INDEX; 883 } 884 885 if (0 == mMemInfo[idx].handle) { 886 LOGE("Trying to unregister buffer at %d which still not registered", 887 idx); 888 return BAD_VALUE; 889 } 890 891 rc = unregisterBufferLocked(idx); 892 893 LOGD("X ",__FUNCTION__); 894 895 return rc; 896} 897 898/*=========================================================================== 899 * FUNCTION : unregisterBuffers 900 * 901 * DESCRIPTION: unregister buffers 902 * 903 * PARAMETERS : none 904 * 905 * RETURN : none 906 *==========================================================================*/ 907void QCamera3GrallocMemory::unregisterBuffers() 908{ 909 int err = NO_ERROR; 910 Mutex::Autolock lock(mLock); 911 912 LOGD("E ", __FUNCTION__); 913 914 for (uint32_t cnt = mStartIdx; cnt < MM_CAMERA_MAX_NUM_FRAMES; cnt++) { 915 if (0 == mMemInfo[cnt].handle) { 916 continue; 917 } 918 err = unregisterBufferLocked(cnt); 919 if (NO_ERROR != err) { 920 LOGE("Error unregistering buffer %d error %d", 921 cnt, err); 922 } 923 } 924 mBufferCount = 0; 925 LOGD("X ",__FUNCTION__); 926} 927 928/*=========================================================================== 929 * FUNCTION : markFrameNumber 930 * 931 * DESCRIPTION: We use this function from the request call path to mark the 932 * buffers with the frame number they are intended for this info 933 * is used later when giving out callback & it is duty of PP to 934 * ensure that data for that particular frameNumber/Request is 935 * written to this buffer. 936 * PARAMETERS : 937 * @index : index of the buffer 938 * @frame# : Frame number from the framework 939 * 940 * RETURN : int32_t type of status 941 * NO_ERROR -- success 942 * none-zero failure code 943 *==========================================================================*/ 944int32_t QCamera3GrallocMemory::markFrameNumber(uint32_t index, uint32_t frameNumber) 945{ 946 Mutex::Autolock lock(mLock); 947 948 if (index >= MM_CAMERA_MAX_NUM_FRAMES) { 949 LOGE("Index out of bounds"); 950 return BAD_INDEX; 951 } 952 if (index < mStartIdx) { 953 LOGE("buffer index %d less than starting index %d", 954 index, mStartIdx); 955 return BAD_INDEX; 956 } 957 958 if (0 == mMemInfo[index].handle) { 959 LOGE("Buffer at %d not registered", index); 960 return BAD_INDEX; 961 } 962 963 mCurrentFrameNumbers[index] = (int32_t)frameNumber; 964 965 return NO_ERROR; 966} 967 968/*=========================================================================== 969 * FUNCTION : getFrameNumber 970 * 971 * DESCRIPTION: We use this to fetch the frameNumber for the request with which 972 * this buffer was given to HAL 973 * 974 * 975 * PARAMETERS : 976 * @index : index of the buffer 977 * 978 * RETURN : int32_t frameNumber 979 * positive/zero -- success 980 * negative failure 981 *==========================================================================*/ 982int32_t QCamera3GrallocMemory::getFrameNumber(uint32_t index) 983{ 984 Mutex::Autolock lock(mLock); 985 986 if (index >= MM_CAMERA_MAX_NUM_FRAMES) { 987 LOGE("Index out of bounds"); 988 return -1; 989 } 990 if (index < mStartIdx) { 991 LOGE("buffer index %d less than starting index %d", 992 index, mStartIdx); 993 return BAD_INDEX; 994 } 995 996 if (0 == mMemInfo[index].handle) { 997 LOGE("Buffer at %d not registered", index); 998 return -1; 999 } 1000 1001 return mCurrentFrameNumbers[index]; 1002} 1003 1004/*=========================================================================== 1005 * FUNCTION : getBufferIndex 1006 * 1007 * DESCRIPTION: We use this to fetch the buffer index for the request with 1008 * a particular frame number 1009 * 1010 * 1011 * PARAMETERS : 1012 * @frameNumber : frame number of the buffer 1013 * 1014 * RETURN : int32_t buffer index 1015 * negative failure 1016 *==========================================================================*/ 1017int32_t QCamera3GrallocMemory::getBufferIndex(uint32_t frameNumber) 1018{ 1019 for (uint32_t index = mStartIdx; 1020 index < MM_CAMERA_MAX_NUM_FRAMES; index++) { 1021 if (mMemInfo[index].handle && 1022 mCurrentFrameNumbers[index] == (int32_t)frameNumber) 1023 return (int32_t)index; 1024 } 1025 return -1; 1026} 1027 1028/*=========================================================================== 1029 * FUNCTION : cacheOps 1030 * 1031 * DESCRIPTION: ion related memory cache operations 1032 * 1033 * PARAMETERS : 1034 * @index : index of the buffer 1035 * @cmd : cache ops command 1036 * 1037 * RETURN : int32_t type of status 1038 * NO_ERROR -- success 1039 * none-zero failure code 1040 *==========================================================================*/ 1041int QCamera3GrallocMemory::cacheOps(uint32_t index, unsigned int cmd) 1042{ 1043 if (index >= MM_CAMERA_MAX_NUM_FRAMES) { 1044 LOGE("Index out of bounds"); 1045 return -1; 1046 } 1047 if (index < mStartIdx) { 1048 LOGE("buffer index %d less than starting index %d", 1049 index, mStartIdx); 1050 return BAD_INDEX; 1051 } 1052 1053 return cacheOpsInternal(index, cmd, mPtr[index]); 1054} 1055 1056/*=========================================================================== 1057 * FUNCTION : getMatchBufIndex 1058 * 1059 * DESCRIPTION: query buffer index by object ptr 1060 * 1061 * PARAMETERS : 1062 * @opaque : opaque ptr 1063 * 1064 * RETURN : buffer index if match found, 1065 * -1 if failed 1066 *==========================================================================*/ 1067int QCamera3GrallocMemory::getMatchBufIndex(void *object) 1068{ 1069 Mutex::Autolock lock(mLock); 1070 1071 int index = -1; 1072 buffer_handle_t *key = (buffer_handle_t*) object; 1073 if (!key) { 1074 return BAD_VALUE; 1075 } 1076 for (uint32_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 1077 if (mBufferHandle[i] == key) { 1078 index = (int)i; 1079 break; 1080 } 1081 } 1082 1083 return index; 1084} 1085 1086/*=========================================================================== 1087 * FUNCTION : getFreeIndexLocked 1088 * 1089 * DESCRIPTION: Find free index slot. Note 'mLock' needs to be acquired 1090 * before calling this method. 1091 * 1092 * PARAMETERS : None 1093 * 1094 * RETURN : free buffer index if found, 1095 * -1 if failed 1096 *==========================================================================*/ 1097int QCamera3GrallocMemory::getFreeIndexLocked() 1098{ 1099 int index = -1; 1100 1101 if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1)) { 1102 LOGE("Number of buffers %d greater than what's supported %d", 1103 mBufferCount, MM_CAMERA_MAX_NUM_FRAMES); 1104 return index; 1105 } 1106 1107 for (size_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) { 1108 if (0 == mMemInfo[i].handle) { 1109 index = i; 1110 break; 1111 } 1112 } 1113 1114 return index; 1115} 1116 1117/*=========================================================================== 1118 * FUNCTION : getPtrLocked 1119 * 1120 * DESCRIPTION: Return buffer pointer. Please note 'mLock' must be acquired 1121 * before calling this method. 1122 * 1123 * PARAMETERS : 1124 * @index : index of the buffer 1125 * 1126 * RETURN : buffer ptr 1127 *==========================================================================*/ 1128void *QCamera3GrallocMemory::getPtrLocked(uint32_t index) 1129{ 1130 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 1131 LOGE("index %d out of bound [0, %d)", 1132 index, MM_CAMERA_MAX_NUM_FRAMES); 1133 return NULL; 1134 } 1135 if (index < mStartIdx) { 1136 LOGE("buffer index %d less than starting index %d", 1137 index, mStartIdx); 1138 return NULL; 1139 } 1140 1141 1142 if (0 == mMemInfo[index].handle) { 1143 LOGE("Buffer at %d not registered", index); 1144 return NULL; 1145 } 1146 1147 return mPtr[index]; 1148} 1149 1150/*=========================================================================== 1151 * FUNCTION : getPtr 1152 * 1153 * DESCRIPTION: Return buffer pointer. 1154 * 1155 * PARAMETERS : 1156 * @index : index of the buffer 1157 * 1158 * RETURN : buffer ptr 1159 *==========================================================================*/ 1160void *QCamera3GrallocMemory::getPtr(uint32_t index) 1161{ 1162 Mutex::Autolock lock(mLock); 1163 return getPtrLocked(index); 1164} 1165 1166/*=========================================================================== 1167 * FUNCTION : getBufferHandle 1168 * 1169 * DESCRIPTION: return framework pointer 1170 * 1171 * PARAMETERS : 1172 * @index : index of the buffer 1173 * 1174 * RETURN : buffer ptr if match found 1175 NULL if failed 1176 *==========================================================================*/ 1177void *QCamera3GrallocMemory::getBufferHandle(uint32_t index) 1178{ 1179 Mutex::Autolock lock(mLock); 1180 1181 if (MM_CAMERA_MAX_NUM_FRAMES <= index) { 1182 LOGE("index %d out of bound [0, %d)", 1183 index, MM_CAMERA_MAX_NUM_FRAMES); 1184 return NULL; 1185 } 1186 if (index < mStartIdx) { 1187 LOGE("buffer index %d less than starting index %d", 1188 index, mStartIdx); 1189 return NULL; 1190 } 1191 1192 if (0 == mMemInfo[index].handle) { 1193 LOGE("Buffer at %d not registered", index); 1194 return NULL; 1195 } 1196 1197 return mBufferHandle[index]; 1198} 1199}; //namespace qcamera 1200