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