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