QCamera3Mem.cpp revision 33cb7276f6c4d2eda72253d11cd9242e1f82bf7d
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 "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 "QCamera3Mem.h"
39
40extern "C" {
41#include <mm_camera_interface.h>
42}
43
44using namespace android;
45
46namespace 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 *==========================================================================*/
59QCamera3Memory::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 *==========================================================================*/
79QCamera3Memory::~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 *==========================================================================*/
97int 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 *==========================================================================*/
138int 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 *==========================================================================*/
156int 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 *==========================================================================*/
173int 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 *==========================================================================*/
190void 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 *==========================================================================*/
228QCamera3HeapMemory::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 *==========================================================================*/
244QCamera3HeapMemory::~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 *==========================================================================*/
262int 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 *==========================================================================*/
295void 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 *==========================================================================*/
315int 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
357ION_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);
361ION_ALLOC_FAILED:
362    close(main_ion_fd);
363ION_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 *==========================================================================*/
377void 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 *==========================================================================*/
407void *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 *==========================================================================*/
430int 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 *==========================================================================*/
468void 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 *==========================================================================*/
491int 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 *==========================================================================*/
510int 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 *==========================================================================*/
529int 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 *==========================================================================*/
563QCamera3GrallocMemory::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 *==========================================================================*/
582QCamera3GrallocMemory::~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 *==========================================================================*/
599int 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    memset(&ion_info_fd, 0, sizeof(ion_info_fd));
604
605    ALOGI(" %s : E ", __FUNCTION__);
606
607    if (num_buffers > MM_CAMERA_MAX_NUM_FRAMES) {
608        ALOGE("%s: Number of buffers %d greater than what's supported %d",
609            __func__, num_buffers, MM_CAMERA_MAX_NUM_FRAMES);
610        return -EINVAL;
611    }
612
613    for (size_t cnt = 0; cnt < num_buffers; cnt++) {
614        if (buffers[cnt] == NULL) {
615            ALOGE("%s: Invalid buffers[%d].", __func__, cnt);
616            return -EINVAL;
617        }
618        mBufferHandle[cnt] = buffers[cnt];
619        mPrivateHandle[cnt] =
620            (struct private_handle_t *)(*mBufferHandle[cnt]);
621        mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
622        if (mMemInfo[cnt].main_ion_fd < 0) {
623            ALOGE("%s: failed: could not open ion device", __func__);
624            for(size_t i = 0; i < cnt; i++) {
625                struct ion_handle_data ion_handle;
626                memset(&ion_handle, 0, sizeof(ion_handle));
627                ion_handle.handle = mMemInfo[i].handle;
628                if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
629                    ALOGE("%s: ion free failed", __func__);
630                }
631                close(mMemInfo[i].main_ion_fd);
632                ALOGD("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
633                mBufferHandle[i] = NULL;
634            }
635            memset(&mMemInfo, 0, sizeof(mMemInfo));
636            ret = -ENOMEM;
637            goto end;
638        } else {
639            ion_info_fd.fd = mPrivateHandle[cnt]->fd;
640            if (ioctl(mMemInfo[cnt].main_ion_fd,
641                      ION_IOC_IMPORT, &ion_info_fd) < 0) {
642                ALOGE("%s: ION import failed\n", __func__);
643                for(size_t i = 0; i < cnt; i++) {
644                    struct ion_handle_data ion_handle;
645                    memset(&ion_handle, 0, sizeof(ion_handle));
646                    ion_handle.handle = mMemInfo[i].handle;
647                    if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
648                        ALOGE("ion free failed");
649                    }
650                    close(mMemInfo[i].main_ion_fd);
651                    mBufferHandle[i] = NULL;
652                }
653                close(mMemInfo[cnt].main_ion_fd);
654                memset(&mMemInfo, 0, sizeof(mMemInfo));
655                ret = -ENOMEM;
656                goto end;
657            }
658        }
659        ALOGD("%s: idx = %d, fd = %d, size = %d, offset = %d",
660              __func__, cnt, mPrivateHandle[cnt]->fd,
661              mPrivateHandle[cnt]->size,
662              mPrivateHandle[cnt]->offset);
663        mMemInfo[cnt].fd =
664            mPrivateHandle[cnt]->fd;
665        mMemInfo[cnt].size =
666            mPrivateHandle[cnt]->size;
667        mMemInfo[cnt].handle = ion_info_fd.handle;
668
669        void *vaddr = mmap(NULL,
670                    mMemInfo[cnt].size,
671                    PROT_READ | PROT_WRITE,
672                    MAP_SHARED,
673                    mMemInfo[cnt].fd, 0);
674        if (vaddr == MAP_FAILED) {
675            for (int j = cnt-1; j >= 0; j --) {
676                munmap(mPtr[cnt], mMemInfo[cnt].size);
677                ret = -ENOMEM;
678                break;
679            }
680        } else
681            mPtr[cnt] = vaddr;
682    }
683    mBufferCount = num_buffers;
684
685end:
686    ALOGI(" %s : X ",__func__);
687    return ret;
688}
689
690/*===========================================================================
691 * FUNCTION   : unregisterBuffers
692 *
693 * DESCRIPTION: unregister buffers
694 *
695 * PARAMETERS : none
696 *
697 * RETURN     : none
698 *==========================================================================*/
699void QCamera3GrallocMemory::unregisterBuffers()
700{
701    ALOGI("%s: E ", __FUNCTION__);
702
703    for (int cnt = 0; cnt < mBufferCount; cnt++) {
704        munmap(mPtr[cnt], mMemInfo[cnt].size);
705        mPtr[cnt] = NULL;
706
707        struct ion_handle_data ion_handle;
708        memset(&ion_handle, 0, sizeof(ion_handle));
709        ion_handle.handle = mMemInfo[cnt].handle;
710        if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
711            ALOGE("ion free failed");
712        }
713        close(mMemInfo[cnt].main_ion_fd);
714        ALOGD("put buffer %d successfully", cnt);
715    }
716    mBufferCount = 0;
717    ALOGI(" %s : X ",__FUNCTION__);
718}
719
720/*===========================================================================
721 * FUNCTION   : markFrameNumber
722 *
723 * DESCRIPTION: We use this function from the request call path to mark the
724 *              buffers with the frame number they are intended for this info
725 *              is used later when giving out callback & it is duty of PP to
726 *              ensure that data for that particular frameNumber/Request is
727 *              written to this buffer.
728 * PARAMETERS :
729 *   @index   : index of the buffer
730 *   @frame#  : Frame number from the framework
731 *
732 * RETURN     : int32_t type of status
733 *              NO_ERROR  -- success
734 *              none-zero failure code
735 *==========================================================================*/
736int32_t QCamera3GrallocMemory::markFrameNumber(int index, uint32_t frameNumber)
737{
738    if(index >= mBufferCount || index >= MM_CAMERA_MAX_NUM_FRAMES) {
739        ALOGE("%s: Index out of bounds",__func__);
740        return BAD_INDEX;
741    }
742    mCurrentFrameNumbers[index] = frameNumber;
743    return NO_ERROR;
744}
745
746/*===========================================================================
747 * FUNCTION   : getFrameNumber
748 *
749 * DESCRIPTION: We use this to fetch the frameNumber for the request with which
750 *              this buffer was given to HAL
751 *
752 *
753 * PARAMETERS :
754 *   @index   : index of the buffer
755 *
756 * RETURN     : int32_t frameNumber
757 *              postive/zero  -- success
758 *              negetive failure
759 *==========================================================================*/
760int32_t QCamera3GrallocMemory::getFrameNumber(int index)
761{
762    if(index >= mBufferCount || index >= MM_CAMERA_MAX_NUM_FRAMES) {
763        ALOGE("%s: Index out of bounds",__func__);
764        return -1;
765    }
766
767    return mCurrentFrameNumbers[index];
768}
769
770/*===========================================================================
771 * FUNCTION   : cacheOps
772 *
773 * DESCRIPTION: ion related memory cache operations
774 *
775 * PARAMETERS :
776 *   @index   : index of the buffer
777 *   @cmd     : cache ops command
778 *
779 * RETURN     : int32_t type of status
780 *              NO_ERROR  -- success
781 *              none-zero failure code
782 *==========================================================================*/
783int QCamera3GrallocMemory::cacheOps(int index, unsigned int cmd)
784{
785    if (index >= mBufferCount)
786        return BAD_INDEX;
787    return cacheOpsInternal(index, cmd, mPtr[index]);
788}
789
790/*===========================================================================
791 * FUNCTION   : getRegFlags
792 *
793 * DESCRIPTION: query initial reg flags
794 *
795 * PARAMETERS :
796 *   @regFlags: initial reg flags of the allocated buffers
797 *
798 * RETURN     : int32_t type of status
799 *              NO_ERROR  -- success
800 *              none-zero failure code
801 *==========================================================================*/
802int QCamera3GrallocMemory::getRegFlags(uint8_t *regFlags) const
803{
804    int i;
805    for (i = 0; i < mBufferCount; i ++)
806        regFlags[i] = 0;
807    return NO_ERROR;
808}
809
810/*===========================================================================
811 * FUNCTION   : getMatchBufIndex
812 *
813 * DESCRIPTION: query buffer index by object ptr
814 *
815 * PARAMETERS :
816 *   @opaque  : opaque ptr
817 *
818 * RETURN     : buffer index if match found,
819 *              -1 if failed
820 *==========================================================================*/
821int QCamera3GrallocMemory::getMatchBufIndex(void *object)
822{
823    int index = -1;
824    buffer_handle_t *key = (buffer_handle_t*) object;
825    if (!key) {
826        return BAD_VALUE;
827    }
828    for (int i = 0; i < mBufferCount; i++) {
829        if (mBufferHandle[i] == key) {
830            index = i;
831            break;
832        }
833    }
834    return index;
835}
836
837/*===========================================================================
838 * FUNCTION   : getPtr
839 *
840 * DESCRIPTION: return buffer pointer
841 *
842 * PARAMETERS :
843 *   @index   : index of the buffer
844 *
845 * RETURN     : buffer ptr
846 *==========================================================================*/
847void *QCamera3GrallocMemory::getPtr(int index) const
848{
849    if (index >= mBufferCount) {
850        ALOGE("index out of bound");
851        return (void *)BAD_INDEX;
852    }
853    return mPtr[index];
854}
855
856}; //namespace qcamera
857