Home | History | Annotate | Download | only in HAL3
      1 /* Copyright (c) 2012-2013, 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 "QCamera3HWI_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 "QCamera3Mem.h"
     39 
     40 extern "C" {
     41 #include <mm_camera_interface.h>
     42 }
     43 
     44 using namespace android;
     45 
     46 namespace qcamera {
     47 
     48 // QCaemra2Memory base class
     49 
     50 /*===========================================================================
     51  * FUNCTION   : QCamera3Memory
     52  *
     53  * DESCRIPTION: default constructor of QCamera3Memory
     54  *
     55  * PARAMETERS : none
     56  *
     57  * RETURN     : None
     58  *==========================================================================*/
     59 QCamera3Memory::QCamera3Memory()
     60 {
     61     mBufferCount = 0;
     62     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
     63         mMemInfo[i].fd = 0;
     64         mMemInfo[i].main_ion_fd = 0;
     65         mMemInfo[i].handle = NULL;
     66         mMemInfo[i].size = 0;
     67     }
     68 }
     69 
     70 /*===========================================================================
     71  * FUNCTION   : ~QCamera3Memory
     72  *
     73  * DESCRIPTION: deconstructor of QCamera3Memory
     74  *
     75  * PARAMETERS : none
     76  *
     77  * RETURN     : None
     78  *==========================================================================*/
     79 QCamera3Memory::~QCamera3Memory()
     80 {
     81 }
     82 
     83 /*===========================================================================
     84  * FUNCTION   : cacheOpsInternal
     85  *
     86  * DESCRIPTION: ion related memory cache operations
     87  *
     88  * PARAMETERS :
     89  *   @index   : index of the buffer
     90  *   @cmd     : cache ops command
     91  *   @vaddr   : ptr to the virtual address
     92  *
     93  * RETURN     : int32_t type of status
     94  *              NO_ERROR  -- success
     95  *              none-zero failure code
     96  *==========================================================================*/
     97 int QCamera3Memory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr)
     98 {
     99     struct ion_flush_data cache_inv_data;
    100     struct ion_custom_data custom_data;
    101     int ret = OK;
    102 
    103     if (index >= mBufferCount) {
    104         ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount);
    105         return BAD_INDEX;
    106     }
    107 
    108     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
    109     memset(&custom_data, 0, sizeof(custom_data));
    110     cache_inv_data.vaddr = vaddr;
    111     cache_inv_data.fd = mMemInfo[index].fd;
    112     cache_inv_data.handle = mMemInfo[index].handle;
    113     cache_inv_data.length = mMemInfo[index].size;
    114     custom_data.cmd = cmd;
    115     custom_data.arg = (unsigned long)&cache_inv_data;
    116 
    117     ALOGV("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
    118          __func__, cache_inv_data.vaddr, cache_inv_data.fd,
    119          cache_inv_data.handle, cache_inv_data.length,
    120          mMemInfo[index].main_ion_fd);
    121     ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
    122     if (ret < 0)
    123         ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
    124 
    125     return ret;
    126 }
    127 
    128 /*===========================================================================
    129  * FUNCTION   : getFd
    130  *
    131  * DESCRIPTION: return file descriptor of the indexed buffer
    132  *
    133  * PARAMETERS :
    134  *   @index   : index of the buffer
    135  *
    136  * RETURN     : file descriptor
    137  *==========================================================================*/
    138 int QCamera3Memory::getFd(int index) const
    139 {
    140     if (index >= mBufferCount)
    141         return BAD_INDEX;
    142 
    143     return mMemInfo[index].fd;
    144 }
    145 
    146 /*===========================================================================
    147  * FUNCTION   : getSize
    148  *
    149  * DESCRIPTION: return buffer size of the indexed buffer
    150  *
    151  * PARAMETERS :
    152  *   @index   : index of the buffer
    153  *
    154  * RETURN     : buffer size
    155  *==========================================================================*/
    156 int QCamera3Memory::getSize(int index) const
    157 {
    158     if (index >= mBufferCount)
    159         return BAD_INDEX;
    160 
    161     return (int)mMemInfo[index].size;
    162 }
    163 
    164 /*===========================================================================
    165  * FUNCTION   : getCnt
    166  *
    167  * DESCRIPTION: query number of buffers allocated
    168  *
    169  * PARAMETERS : none
    170  *
    171  * RETURN     : number of buffers allocated
    172  *==========================================================================*/
    173 int QCamera3Memory::getCnt() const
    174 {
    175     return mBufferCount;
    176 }
    177 
    178 /*===========================================================================
    179  * FUNCTION   : getBufDef
    180  *
    181  * DESCRIPTION: query detailed buffer information
    182  *
    183  * PARAMETERS :
    184  *   @offset  : [input] frame buffer offset
    185  *   @bufDef  : [output] reference to struct to store buffer definition
    186  *   @index   : [input] index of the buffer
    187  *
    188  * RETURN     : none
    189  *==========================================================================*/
    190 void QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
    191         mm_camera_buf_def_t &bufDef, int index) const
    192 {
    193     if (!mBufferCount) {
    194         ALOGE("Memory not allocated");
    195         return;
    196     }
    197     bufDef.fd = mMemInfo[index].fd;
    198     bufDef.frame_len = mMemInfo[index].size;
    199     bufDef.mem_info = (void *)this;
    200     bufDef.num_planes = offset.num_planes;
    201     bufDef.buffer = getPtr(index);
    202     bufDef.buf_idx = index;
    203 
    204     /* Plane 0 needs to be set separately. Set other planes in a loop */
    205     bufDef.planes[0].length = offset.mp[0].len;
    206     bufDef.planes[0].m.userptr = mMemInfo[index].fd;
    207     bufDef.planes[0].data_offset = offset.mp[0].offset;
    208     bufDef.planes[0].reserved[0] = 0;
    209     for (int i = 1; i < bufDef.num_planes; i++) {
    210          bufDef.planes[i].length = offset.mp[i].len;
    211          bufDef.planes[i].m.userptr = mMemInfo[i].fd;
    212          bufDef.planes[i].data_offset = offset.mp[i].offset;
    213          bufDef.planes[i].reserved[0] =
    214                  bufDef.planes[i-1].reserved[0] +
    215                  bufDef.planes[i-1].length;
    216     }
    217 }
    218 
    219 /*===========================================================================
    220  * FUNCTION   : QCamera3HeapMemory
    221  *
    222  * DESCRIPTION: constructor of QCamera3HeapMemory for ion memory used internally in HAL
    223  *
    224  * PARAMETERS : none
    225  *
    226  * RETURN     : none
    227  *==========================================================================*/
    228 QCamera3HeapMemory::QCamera3HeapMemory()
    229     : QCamera3Memory()
    230 {
    231     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
    232         mPtr[i] = NULL;
    233 }
    234 
    235 /*===========================================================================
    236  * FUNCTION   : ~QCamera3HeapMemory
    237  *
    238  * DESCRIPTION: deconstructor of QCamera3HeapMemory
    239  *
    240  * PARAMETERS : none
    241  *
    242  * RETURN     : none
    243  *==========================================================================*/
    244 QCamera3HeapMemory::~QCamera3HeapMemory()
    245 {
    246 }
    247 
    248 /*===========================================================================
    249  * FUNCTION   : alloc
    250  *
    251  * DESCRIPTION: allocate requested number of buffers of certain size
    252  *
    253  * PARAMETERS :
    254  *   @count   : number of buffers to be allocated
    255  *   @size    : lenght of the buffer to be allocated
    256  *   @heap_id : heap id to indicate where the buffers will be allocated from
    257  *
    258  * RETURN     : int32_t type of status
    259  *              NO_ERROR  -- success
    260  *              none-zero failure code
    261  *==========================================================================*/
    262 int QCamera3HeapMemory::alloc(int count, int size, int heap_id)
    263 {
    264     int rc = OK;
    265     if (count > MM_CAMERA_MAX_NUM_FRAMES) {
    266         ALOGE("Buffer count %d out of bound. Max is %d", count, MM_CAMERA_MAX_NUM_FRAMES);
    267         return BAD_INDEX;
    268     }
    269     if (mBufferCount) {
    270         ALOGE("Allocating a already allocated heap memory");
    271         return INVALID_OPERATION;
    272     }
    273 
    274     for (int i = 0; i < count; i ++) {
    275         rc = allocOneBuffer(mMemInfo[i], heap_id, size);
    276         if (rc < 0) {
    277             ALOGE("AllocateIonMemory failed");
    278             for (int j = i-1; j >= 0; j--)
    279                 deallocOneBuffer(mMemInfo[j]);
    280             break;
    281         }
    282     }
    283     return rc;
    284 }
    285 
    286 /*===========================================================================
    287  * FUNCTION   : dealloc
    288  *
    289  * DESCRIPTION: deallocate buffers
    290  *
    291  * PARAMETERS : none
    292  *
    293  * RETURN     : none
    294  *==========================================================================*/
    295 void QCamera3HeapMemory::dealloc()
    296 {
    297     for (int i = 0; i < mBufferCount; i++)
    298         deallocOneBuffer(mMemInfo[i]);
    299 }
    300 
    301 /*===========================================================================
    302  * FUNCTION   : allocOneBuffer
    303  *
    304  * DESCRIPTION: impl of allocating one buffers of certain size
    305  *
    306  * PARAMETERS :
    307  *   @memInfo : [output] reference to struct to store additional memory allocation info
    308  *   @heap    : [input] heap id to indicate where the buffers will be allocated from
    309  *   @size    : [input] lenght of the buffer to be allocated
    310  *
    311  * RETURN     : int32_t type of status
    312  *              NO_ERROR  -- success
    313  *              none-zero failure code
    314  *==========================================================================*/
    315 int QCamera3HeapMemory::allocOneBuffer(QCamera3MemInfo &memInfo, int heap_id, int size)
    316 {
    317     int rc = OK;
    318     struct ion_handle_data handle_data;
    319     struct ion_allocation_data alloc;
    320     struct ion_fd_data ion_info_fd;
    321     int main_ion_fd = 0;
    322 
    323     main_ion_fd = open("/dev/ion", O_RDONLY);
    324     if (main_ion_fd <= 0) {
    325         ALOGE("Ion dev open failed: %s\n", strerror(errno));
    326         goto ION_OPEN_FAILED;
    327     }
    328 
    329     memset(&alloc, 0, sizeof(alloc));
    330     alloc.len = size;
    331     /* to make it page size aligned */
    332     alloc.len = (alloc.len + 4095) & (~4095);
    333     alloc.align = 4096;
    334     alloc.flags = ION_FLAG_CACHED;
    335     alloc.heap_mask = heap_id;
    336     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
    337     if (rc < 0) {
    338         ALOGE("ION allocation for len %d failed: %s\n", alloc.len,
    339             strerror(errno));
    340         goto ION_ALLOC_FAILED;
    341     }
    342 
    343     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    344     ion_info_fd.handle = alloc.handle;
    345     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
    346     if (rc < 0) {
    347         ALOGE("ION map failed %s\n", strerror(errno));
    348         goto ION_MAP_FAILED;
    349     }
    350 
    351     memInfo.main_ion_fd = main_ion_fd;
    352     memInfo.fd = ion_info_fd.fd;
    353     memInfo.handle = ion_info_fd.handle;
    354     memInfo.size = alloc.len;
    355     return OK;
    356 
    357 ION_MAP_FAILED:
    358     memset(&handle_data, 0, sizeof(handle_data));
    359     handle_data.handle = ion_info_fd.handle;
    360     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
    361 ION_ALLOC_FAILED:
    362     close(main_ion_fd);
    363 ION_OPEN_FAILED:
    364     return NO_MEMORY;
    365 }
    366 
    367 /*===========================================================================
    368  * FUNCTION   : deallocOneBuffer
    369  *
    370  * DESCRIPTION: impl of deallocating one buffers
    371  *
    372  * PARAMETERS :
    373  *   @memInfo : reference to struct that stores additional memory allocation info
    374  *
    375  * RETURN     : none
    376  *==========================================================================*/
    377 void QCamera3HeapMemory::deallocOneBuffer(QCamera3MemInfo &memInfo)
    378 {
    379     struct ion_handle_data handle_data;
    380 
    381     if (memInfo.fd > 0) {
    382         close(memInfo.fd);
    383         memInfo.fd = 0;
    384     }
    385 
    386     if (memInfo.main_ion_fd > 0) {
    387         memset(&handle_data, 0, sizeof(handle_data));
    388         handle_data.handle = memInfo.handle;
    389         ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
    390         close(memInfo.main_ion_fd);
    391         memInfo.main_ion_fd = 0;
    392     }
    393     memInfo.handle = NULL;
    394     memInfo.size = 0;
    395 }
    396 
    397 /*===========================================================================
    398  * FUNCTION   : getPtr
    399  *
    400  * DESCRIPTION: return buffer pointer
    401  *
    402  * PARAMETERS :
    403  *   @index   : index of the buffer
    404  *
    405  * RETURN     : buffer ptr
    406  *==========================================================================*/
    407 void *QCamera3HeapMemory::getPtr(int index) const
    408 {
    409     if (index >= mBufferCount) {
    410         ALOGE("index out of bound");
    411         return (void *)BAD_INDEX;
    412     }
    413     return mPtr[index];
    414 }
    415 
    416 /*===========================================================================
    417  * FUNCTION   : allocate
    418  *
    419  * DESCRIPTION: allocate requested number of buffers of certain size
    420  *
    421  * PARAMETERS :
    422  *   @count   : number of buffers to be allocated
    423  *   @size    : lenght of the buffer to be allocated
    424  *   @queueAll: whether to queue all allocated buffers at the beginning
    425  *
    426  * RETURN     : int32_t type of status
    427  *              NO_ERROR  -- success
    428  *              none-zero failure code
    429  *==========================================================================*/
    430 int QCamera3HeapMemory::allocate(int count, int size, bool queueAll)
    431 {
    432     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
    433     int rc = alloc(count, size, heap_mask);
    434     if (rc < 0)
    435         return rc;
    436 
    437     for (int i = 0; i < count; i ++) {
    438         void *vaddr = mmap(NULL,
    439                     mMemInfo[i].size,
    440                     PROT_READ | PROT_WRITE,
    441                     MAP_SHARED,
    442                     mMemInfo[i].fd, 0);
    443         if (vaddr == MAP_FAILED) {
    444             for (int j = i-1; j >= 0; j --) {
    445                 munmap(mPtr[i], mMemInfo[i].size);
    446                 rc = NO_MEMORY;
    447                 break;
    448             }
    449         } else
    450             mPtr[i] = vaddr;
    451     }
    452     if (rc == 0)
    453         mBufferCount = count;
    454 
    455     mQueueAll = queueAll;
    456     return OK;
    457 }
    458 
    459 /*===========================================================================
    460  * FUNCTION   : deallocate
    461  *
    462  * DESCRIPTION: deallocate buffers
    463  *
    464  * PARAMETERS : none
    465  *
    466  * RETURN     : none
    467  *==========================================================================*/
    468 void QCamera3HeapMemory::deallocate()
    469 {
    470     for (int i = 0; i < mBufferCount; i++) {
    471         munmap(mPtr[i], mMemInfo[i].size);
    472         mPtr[i] = NULL;
    473     }
    474     dealloc();
    475     mBufferCount = 0;
    476 }
    477 
    478 /*===========================================================================
    479  * FUNCTION   : cacheOps
    480  *
    481  * DESCRIPTION: ion related memory cache operations
    482  *
    483  * PARAMETERS :
    484  *   @index   : index of the buffer
    485  *   @cmd     : cache ops command
    486  *
    487  * RETURN     : int32_t type of status
    488  *              NO_ERROR  -- success
    489  *              none-zero failure code
    490  *==========================================================================*/
    491 int QCamera3HeapMemory::cacheOps(int index, unsigned int cmd)
    492 {
    493     if (index >= mBufferCount)
    494         return BAD_INDEX;
    495     return cacheOpsInternal(index, cmd, mPtr[index]);
    496 }
    497 
    498 /*===========================================================================
    499  * FUNCTION   : getRegFlags
    500  *
    501  * DESCRIPTION: query initial reg flags
    502  *
    503  * PARAMETERS :
    504  *   @regFlags: initial reg flags of the allocated buffers
    505  *
    506  * RETURN     : int32_t type of status
    507  *              NO_ERROR  -- success
    508  *              none-zero failure code
    509  *==========================================================================*/
    510 int QCamera3HeapMemory::getRegFlags(uint8_t * regFlags) const
    511 {
    512     int i;
    513     for (i = 0; i < mBufferCount; i ++)
    514         regFlags[i] = (mQueueAll ? 1 : 0);
    515     return NO_ERROR;
    516 }
    517 
    518 /*===========================================================================
    519  * FUNCTION   : getMatchBufIndex
    520  *
    521  * DESCRIPTION: query buffer index by object ptr
    522  *
    523  * PARAMETERS :
    524  *   @object  : object ptr
    525  *
    526  * RETURN     : buffer index if match found,
    527  *              -1 if failed
    528  *==========================================================================*/
    529 int QCamera3HeapMemory::getMatchBufIndex(void * /*object*/)
    530 {
    531 
    532 /*
    533     TODO for HEAP memory type, would there be an equivalent requirement?
    534 
    535     int index = -1;
    536     buffer_handle_t *key = (buffer_handle_t*) object;
    537     if (!key) {
    538         return BAD_VALUE;
    539     }
    540     for (int i = 0; i < mBufferCount; i++) {
    541         if (mBufferHandle[i] == key) {
    542             index = i;
    543             break;
    544         }
    545     }
    546     return index;
    547 */
    548     ALOGE("%s: FATAL: Not supposed to come here", __func__);
    549     return -1;
    550 }
    551 
    552 /*===========================================================================
    553  * FUNCTION   : QCamera3GrallocMemory
    554  *
    555  * DESCRIPTION: constructor of QCamera3GrallocMemory
    556  *              preview stream buffers are allocated from gralloc native_windoe
    557  *
    558  * PARAMETERS :
    559  *   @getMemory : camera memory request ops table
    560  *
    561  * RETURN     : none
    562  *==========================================================================*/
    563 QCamera3GrallocMemory::QCamera3GrallocMemory()
    564         : QCamera3Memory()
    565 {
    566     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
    567         mBufferHandle[i] = NULL;
    568         mPrivateHandle[i] = NULL;
    569         mCurrentFrameNumbers[i] = -1;
    570     }
    571 }
    572 
    573 /*===========================================================================
    574  * FUNCTION   : ~QCamera3GrallocMemory
    575  *
    576  * DESCRIPTION: deconstructor of QCamera3GrallocMemory
    577  *
    578  * PARAMETERS : none
    579  *
    580  * RETURN     : none
    581  *==========================================================================*/
    582 QCamera3GrallocMemory::~QCamera3GrallocMemory()
    583 {
    584 }
    585 
    586 /*===========================================================================
    587  * FUNCTION   : registerBuffers
    588  *
    589  * DESCRIPTION: register frameworks-allocated gralloc buffer_handle_t
    590  *
    591  * PARAMETERS :
    592  *   @num_buffer : number of buffers to be registered
    593  *   @buffers    : array of buffer_handle_t pointers
    594  *
    595  * RETURN     : int32_t type of status
    596  *              NO_ERROR  -- success
    597  *              none-zero failure code
    598  *==========================================================================*/
    599 int QCamera3GrallocMemory::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
    600 {
    601     status_t ret = NO_ERROR;
    602     struct ion_fd_data ion_info_fd;
    603     ALOGV(" %s : E ", __FUNCTION__);
    604 
    605     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
    606 
    607 
    608     if (num_buffers > MM_CAMERA_MAX_NUM_FRAMES) {
    609         ALOGE("%s: Number of buffers %d greater than what's supported %d",
    610             __func__, num_buffers, MM_CAMERA_MAX_NUM_FRAMES);
    611         return -EINVAL;
    612     }
    613 
    614     for (size_t cnt = 0; cnt < num_buffers; cnt++) {
    615         if (buffers[cnt] == NULL) {
    616             ALOGE("%s: Invalid buffers[%d].", __func__, cnt);
    617             return -EINVAL;
    618         }
    619         mBufferHandle[cnt] = buffers[cnt];
    620         mPrivateHandle[cnt] =
    621             (struct private_handle_t *)(*mBufferHandle[cnt]);
    622         mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
    623         if (mMemInfo[cnt].main_ion_fd < 0) {
    624             ALOGE("%s: failed: could not open ion device", __func__);
    625             for(size_t i = 0; i < cnt; i++) {
    626                 struct ion_handle_data ion_handle;
    627                 memset(&ion_handle, 0, sizeof(ion_handle));
    628                 ion_handle.handle = mMemInfo[i].handle;
    629                 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
    630                     ALOGE("%s: ion free failed", __func__);
    631                 }
    632                 close(mMemInfo[i].main_ion_fd);
    633                 ALOGV("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
    634                 mBufferHandle[i] = NULL;
    635             }
    636             memset(&mMemInfo, 0, sizeof(mMemInfo));
    637             ret = -ENOMEM;
    638             goto end;
    639         } else {
    640             ion_info_fd.fd = mPrivateHandle[cnt]->fd;
    641             if (ioctl(mMemInfo[cnt].main_ion_fd,
    642                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
    643                 ALOGE("%s: ION import failed\n", __func__);
    644                 for(size_t i = 0; i < cnt; i++) {
    645                     struct ion_handle_data ion_handle;
    646                     memset(&ion_handle, 0, sizeof(ion_handle));
    647                     ion_handle.handle = mMemInfo[i].handle;
    648                     if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
    649                         ALOGE("ion free failed");
    650                     }
    651                     close(mMemInfo[i].main_ion_fd);
    652                     mBufferHandle[i] = NULL;
    653                 }
    654                 close(mMemInfo[cnt].main_ion_fd);
    655                 memset(&mMemInfo, 0, sizeof(mMemInfo));
    656                 ret = -ENOMEM;
    657                 goto end;
    658             }
    659         }
    660         ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d",
    661               __func__, cnt, mPrivateHandle[cnt]->fd,
    662               mPrivateHandle[cnt]->size,
    663               mPrivateHandle[cnt]->offset);
    664         mMemInfo[cnt].fd =
    665             mPrivateHandle[cnt]->fd;
    666         mMemInfo[cnt].size =
    667             mPrivateHandle[cnt]->size;
    668         mMemInfo[cnt].handle = ion_info_fd.handle;
    669 
    670         void *vaddr = mmap(NULL,
    671                     mMemInfo[cnt].size,
    672                     PROT_READ | PROT_WRITE,
    673                     MAP_SHARED,
    674                     mMemInfo[cnt].fd, 0);
    675         if (vaddr == MAP_FAILED) {
    676             for (int j = cnt-1; j >= 0; j --) {
    677                 munmap(mPtr[cnt], mMemInfo[cnt].size);
    678                 ret = -ENOMEM;
    679                 break;
    680             }
    681         } else
    682             mPtr[cnt] = vaddr;
    683     }
    684     mBufferCount = num_buffers;
    685 
    686 end:
    687     ALOGV(" %s : X ",__func__);
    688     return ret;
    689 }
    690 
    691 /*===========================================================================
    692  * FUNCTION   : unregisterBuffers
    693  *
    694  * DESCRIPTION: unregister buffers
    695  *
    696  * PARAMETERS : none
    697  *
    698  * RETURN     : none
    699  *==========================================================================*/
    700 void QCamera3GrallocMemory::unregisterBuffers()
    701 {
    702     ALOGV("%s: E ", __FUNCTION__);
    703 
    704     for (int cnt = 0; cnt < mBufferCount; cnt++) {
    705         munmap(mPtr[cnt], mMemInfo[cnt].size);
    706         mPtr[cnt] = NULL;
    707 
    708         struct ion_handle_data ion_handle;
    709         memset(&ion_handle, 0, sizeof(ion_handle));
    710         ion_handle.handle = mMemInfo[cnt].handle;
    711         if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
    712             ALOGE("ion free failed");
    713         }
    714         close(mMemInfo[cnt].main_ion_fd);
    715         ALOGV("put buffer %d successfully", cnt);
    716     }
    717     mBufferCount = 0;
    718     ALOGV(" %s : X ",__FUNCTION__);
    719 }
    720 
    721 /*===========================================================================
    722  * FUNCTION   : markFrameNumber
    723  *
    724  * DESCRIPTION: We use this function from the request call path to mark the
    725  *              buffers with the frame number they are intended for this info
    726  *              is used later when giving out callback & it is duty of PP to
    727  *              ensure that data for that particular frameNumber/Request is
    728  *              written to this buffer.
    729  * PARAMETERS :
    730  *   @index   : index of the buffer
    731  *   @frame#  : Frame number from the framework
    732  *
    733  * RETURN     : int32_t type of status
    734  *              NO_ERROR  -- success
    735  *              none-zero failure code
    736  *==========================================================================*/
    737 int32_t QCamera3GrallocMemory::markFrameNumber(int index, uint32_t frameNumber)
    738 {
    739     if(index >= mBufferCount || index >= MM_CAMERA_MAX_NUM_FRAMES) {
    740         ALOGE("%s: Index out of bounds",__func__);
    741         return BAD_INDEX;
    742     }
    743     mCurrentFrameNumbers[index] = frameNumber;
    744     return NO_ERROR;
    745 }
    746 
    747 /*===========================================================================
    748  * FUNCTION   : getFrameNumber
    749  *
    750  * DESCRIPTION: We use this to fetch the frameNumber for the request with which
    751  *              this buffer was given to HAL
    752  *
    753  *
    754  * PARAMETERS :
    755  *   @index   : index of the buffer
    756  *
    757  * RETURN     : int32_t frameNumber
    758  *              postive/zero  -- success
    759  *              negetive failure
    760  *==========================================================================*/
    761 int32_t QCamera3GrallocMemory::getFrameNumber(int index)
    762 {
    763     if(index >= mBufferCount || index >= MM_CAMERA_MAX_NUM_FRAMES) {
    764         ALOGE("%s: Index out of bounds",__func__);
    765         return -1;
    766     }
    767 
    768     return mCurrentFrameNumbers[index];
    769 }
    770 
    771 /*===========================================================================
    772  * FUNCTION   : cacheOps
    773  *
    774  * DESCRIPTION: ion related memory cache operations
    775  *
    776  * PARAMETERS :
    777  *   @index   : index of the buffer
    778  *   @cmd     : cache ops command
    779  *
    780  * RETURN     : int32_t type of status
    781  *              NO_ERROR  -- success
    782  *              none-zero failure code
    783  *==========================================================================*/
    784 int QCamera3GrallocMemory::cacheOps(int index, unsigned int cmd)
    785 {
    786     if (index >= mBufferCount)
    787         return BAD_INDEX;
    788     return cacheOpsInternal(index, cmd, mPtr[index]);
    789 }
    790 
    791 /*===========================================================================
    792  * FUNCTION   : getRegFlags
    793  *
    794  * DESCRIPTION: query initial reg flags
    795  *
    796  * PARAMETERS :
    797  *   @regFlags: initial reg flags of the allocated buffers
    798  *
    799  * RETURN     : int32_t type of status
    800  *              NO_ERROR  -- success
    801  *              none-zero failure code
    802  *==========================================================================*/
    803 int QCamera3GrallocMemory::getRegFlags(uint8_t *regFlags) const
    804 {
    805     int i;
    806     for (i = 0; i < mBufferCount; i ++)
    807         regFlags[i] = 0;
    808     return NO_ERROR;
    809 }
    810 
    811 /*===========================================================================
    812  * FUNCTION   : getMatchBufIndex
    813  *
    814  * DESCRIPTION: query buffer index by object ptr
    815  *
    816  * PARAMETERS :
    817  *   @opaque  : opaque ptr
    818  *
    819  * RETURN     : buffer index if match found,
    820  *              -1 if failed
    821  *==========================================================================*/
    822 int QCamera3GrallocMemory::getMatchBufIndex(void *object)
    823 {
    824     int index = -1;
    825     buffer_handle_t *key = (buffer_handle_t*) object;
    826     if (!key) {
    827         return BAD_VALUE;
    828     }
    829     for (int i = 0; i < mBufferCount; i++) {
    830         if (mBufferHandle[i] == key) {
    831             index = i;
    832             break;
    833         }
    834     }
    835     return index;
    836 }
    837 
    838 /*===========================================================================
    839  * FUNCTION   : getPtr
    840  *
    841  * DESCRIPTION: return buffer pointer
    842  *
    843  * PARAMETERS :
    844  *   @index   : index of the buffer
    845  *
    846  * RETURN     : buffer ptr
    847  *==========================================================================*/
    848 void *QCamera3GrallocMemory::getPtr(int index) const
    849 {
    850     if (index >= mBufferCount) {
    851         ALOGE("index out of bound");
    852         return (void *)BAD_INDEX;
    853     }
    854     return mPtr[index];
    855 }
    856 
    857 }; //namespace qcamera
    858