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