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