Home | History | Annotate | Download | only in HAL3
      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