1 /* Copyright (c) 2012-2015, 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/Errors.h>
36 #include <gralloc_priv.h>
37 #include <QComOMXMetadata.h>
38 #include "QCamera2HWI.h"
39 #include "QCameraMem.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   : QCameraMemory
53  *
54  * DESCRIPTION: default constructor of QCameraMemory
55  *
56  * PARAMETERS :
57  *   @cached  : flag indicates if using cached memory
58  *
59  * RETURN     : None
60  *==========================================================================*/
QCameraMemory(bool cached,QCameraMemoryPool * pool,cam_stream_type_t streamType)61 QCameraMemory::QCameraMemory(bool cached,
62         QCameraMemoryPool *pool,
63         cam_stream_type_t streamType)
64     :m_bCached(cached),
65      mMemoryPool(pool),
66      mStreamType(streamType)
67 {
68     mBufferCount = 0;
69     memset(mMemInfo, 0, sizeof(mMemInfo));
70 }
71 
72 /*===========================================================================
73  * FUNCTION   : ~QCameraMemory
74  *
75  * DESCRIPTION: deconstructor of QCameraMemory
76  *
77  * PARAMETERS : none
78  *
79  * RETURN     : None
80  *==========================================================================*/
~QCameraMemory()81 QCameraMemory::~QCameraMemory()
82 {
83 }
84 
85 /*===========================================================================
86  * FUNCTION   : cacheOpsInternal
87  *
88  * DESCRIPTION: ion related memory cache operations
89  *
90  * PARAMETERS :
91  *   @index   : index of the buffer
92  *   @cmd     : cache ops command
93  *   @vaddr   : ptr to the virtual address
94  *
95  * RETURN     : int32_t type of status
96  *              NO_ERROR  -- success
97  *              none-zero failure code
98  *==========================================================================*/
cacheOpsInternal(int index,unsigned int cmd,void * vaddr)99 int QCameraMemory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr)
100 {
101     if (!m_bCached) {
102         // Memory is not cached, no need for cache ops
103         CDBG("%s: No cache ops here for uncached memory", __func__);
104         return OK;
105     }
106 
107     struct ion_flush_data cache_inv_data;
108     struct ion_custom_data custom_data;
109     int ret = OK;
110 
111     if (index >= mBufferCount) {
112         ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount);
113         return BAD_INDEX;
114     }
115 
116     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
117     memset(&custom_data, 0, sizeof(custom_data));
118     cache_inv_data.vaddr = vaddr;
119     cache_inv_data.fd = mMemInfo[index].fd;
120     cache_inv_data.handle = mMemInfo[index].handle;
121     cache_inv_data.length = mMemInfo[index].size;
122     custom_data.cmd = cmd;
123     custom_data.arg = (unsigned long)&cache_inv_data;
124 
125     CDBG_HIGH("%s: addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
126          __func__, cache_inv_data.vaddr, cache_inv_data.fd,
127          (unsigned long)cache_inv_data.handle, cache_inv_data.length,
128          mMemInfo[index].main_ion_fd);
129     ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
130     if (ret < 0)
131         ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
132 
133     return ret;
134 }
135 
136 /*===========================================================================
137  * FUNCTION   : getFd
138  *
139  * DESCRIPTION: return file descriptor of the indexed buffer
140  *
141  * PARAMETERS :
142  *   @index   : index of the buffer
143  *
144  * RETURN     : file descriptor
145  *==========================================================================*/
getFd(int index) const146 int QCameraMemory::getFd(int index) const
147 {
148     if (index >= mBufferCount)
149         return BAD_INDEX;
150 
151     return mMemInfo[index].fd;
152 }
153 
154 /*===========================================================================
155  * FUNCTION   : getSize
156  *
157  * DESCRIPTION: return buffer size of the indexed buffer
158  *
159  * PARAMETERS :
160  *   @index   : index of the buffer
161  *
162  * RETURN     : buffer size
163  *==========================================================================*/
getSize(int index) const164 int QCameraMemory::getSize(int index) const
165 {
166     if (index >= mBufferCount)
167         return BAD_INDEX;
168 
169     return (int)mMemInfo[index].size;
170 }
171 
172 /*===========================================================================
173  * FUNCTION   : getCnt
174  *
175  * DESCRIPTION: query number of buffers allocated
176  *
177  * PARAMETERS : none
178  *
179  * RETURN     : number of buffers allocated
180  *==========================================================================*/
getCnt() const181 int QCameraMemory::getCnt() const
182 {
183     return mBufferCount;
184 }
185 
186 /*===========================================================================
187  * FUNCTION   : getBufDef
188  *
189  * DESCRIPTION: query detailed buffer information
190  *
191  * PARAMETERS :
192  *   @offset  : [input] frame buffer offset
193  *   @bufDef  : [output] reference to struct to store buffer definition
194  *   @index   : [input] index of the buffer
195  *
196  * RETURN     : none
197  *==========================================================================*/
getBufDef(const cam_frame_len_offset_t & offset,mm_camera_buf_def_t & bufDef,int index) const198 void QCameraMemory::getBufDef(const cam_frame_len_offset_t &offset,
199         mm_camera_buf_def_t &bufDef, int index) const
200 {
201     if (!mBufferCount) {
202         ALOGE("Memory not allocated");
203         return;
204     }
205     bufDef.fd = mMemInfo[index].fd;
206     bufDef.frame_len = offset.frame_len;
207     bufDef.mem_info = (void *)this;
208     bufDef.num_planes = offset.num_planes;
209 	bufDef.buffer = getPtr(index);
210     bufDef.buf_idx = index;
211 
212     /* Plane 0 needs to be set separately. Set other planes in a loop */
213     bufDef.planes[0].length = offset.mp[0].len;
214     bufDef.planes[0].m.userptr = mMemInfo[index].fd;
215     bufDef.planes[0].data_offset = offset.mp[0].offset;
216     bufDef.planes[0].reserved[0] = 0;
217     for (int i = 1; i < bufDef.num_planes; i++) {
218          bufDef.planes[i].length = offset.mp[i].len;
219          bufDef.planes[i].m.userptr = mMemInfo[i].fd;
220          bufDef.planes[i].data_offset = offset.mp[i].offset;
221          bufDef.planes[i].reserved[0] =
222                  bufDef.planes[i-1].reserved[0] +
223                  bufDef.planes[i-1].length;
224     }
225 }
226 
227 /*===========================================================================
228  * FUNCTION   : alloc
229  *
230  * DESCRIPTION: allocate requested number of buffers of certain size
231  *
232  * PARAMETERS :
233  *   @count   : number of buffers to be allocated
234  *   @size    : lenght of the buffer to be allocated
235  *   @heap_id : heap id to indicate where the buffers will be allocated from
236  *
237  * RETURN     : int32_t type of status
238  *              NO_ERROR  -- success
239  *              none-zero failure code
240  *==========================================================================*/
alloc(int count,int size,int heap_id,uint32_t secure_mode)241 int QCameraMemory::alloc(int count, int size, int heap_id, uint32_t secure_mode)
242 {
243     int rc = OK;
244 
245     if (mBufferCount < 0) {
246         mBufferCount = 0;
247     }
248 
249     int new_bufCnt = mBufferCount + count;
250 
251     if (new_bufCnt > MM_CAMERA_MAX_NUM_FRAMES) {
252         ALOGE("%s: Buffer count %d out of bound. Max is %d",
253               __func__, new_bufCnt, MM_CAMERA_MAX_NUM_FRAMES);
254         return BAD_INDEX;
255     }
256 
257     for (int i = mBufferCount; i < new_bufCnt; i ++) {
258         if ( NULL == mMemoryPool ) {
259             ALOGE("%s : No memory pool available", __func__);
260             rc = allocOneBuffer(mMemInfo[i], heap_id, size, m_bCached,
261                      secure_mode);
262             if (rc < 0) {
263                 ALOGE("%s: AllocateIonMemory failed", __func__);
264                 for (int j = i-1; j >= 0; j--)
265                     deallocOneBuffer(mMemInfo[j]);
266                 break;
267             }
268         } else {
269             rc = mMemoryPool->allocateBuffer(mMemInfo[i],
270                                              heap_id,
271                                              size,
272                                              m_bCached,
273                                              mStreamType,
274                                              secure_mode);
275             if (rc < 0) {
276                 ALOGE("%s: Memory pool allocation failed", __func__);
277                 for (int j = i-1; j >= 0; j--)
278                     mMemoryPool->releaseBuffer(mMemInfo[j],
279                                                mStreamType);
280                 break;
281             }
282         }
283 
284     }
285     return rc;
286 }
287 
288 /*===========================================================================
289  * FUNCTION   : dealloc
290  *
291  * DESCRIPTION: deallocate buffers
292  *
293  * PARAMETERS : none
294  *
295  * RETURN     : none
296  *==========================================================================*/
dealloc()297 void QCameraMemory::dealloc()
298 {
299     for (int i = 0; i < mBufferCount; i++) {
300         if ( NULL == mMemoryPool ) {
301             deallocOneBuffer(mMemInfo[i]);
302         } else {
303             mMemoryPool->releaseBuffer(mMemInfo[i], mStreamType);
304         }
305     }
306 }
307 
308 /*===========================================================================
309  * FUNCTION   : allocOneBuffer
310  *
311  * DESCRIPTION: impl of allocating one buffers of certain size
312  *
313  * PARAMETERS :
314  *   @memInfo : [output] reference to struct to store additional memory allocation info
315  *   @heap    : [input] heap id to indicate where the buffers will be allocated from
316  *   @size    : [input] lenght of the buffer to be allocated
317  *   @cached  : [input] flag whether buffer needs to be cached
318  *
319  * RETURN     : int32_t type of status
320  *              NO_ERROR  -- success
321  *              none-zero failure code
322  *==========================================================================*/
allocOneBuffer(QCameraMemInfo & memInfo,int heap_id,int size,bool cached,uint32_t secure_mode)323 int QCameraMemory::allocOneBuffer(QCameraMemInfo &memInfo,
324         int heap_id,
325         int size,
326         bool cached,
327         uint32_t secure_mode)
328 {
329     int rc = OK;
330     struct ion_handle_data handle_data;
331     struct ion_allocation_data alloc;
332     struct ion_fd_data ion_info_fd;
333     int main_ion_fd = 0;
334 
335     main_ion_fd = open("/dev/ion", O_RDONLY);
336     if (main_ion_fd < 0) {
337         ALOGE("Ion dev open failed: %s\n", strerror(errno));
338         goto ION_OPEN_FAILED;
339     }
340 
341     memset(&alloc, 0, sizeof(alloc));
342     alloc.len = size;
343     /* to make it page size aligned */
344     alloc.len = (alloc.len + 4095) & (~4095);
345     alloc.align = 4096;
346     if (cached) {
347         alloc.flags = ION_FLAG_CACHED;
348     }
349     alloc.heap_mask = heap_id;
350     if (secure_mode == SECURE) {
351         ALOGD("%s: Allocate secure buffer\n", __func__);
352         alloc.flags = ION_SECURE;
353         alloc.heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID);
354         alloc.align = 1024*1024; //1 MB alignment to be able to protect later
355         alloc.len = (alloc.len + (1024 * 1024 - 1)) & (~(1024 * 1024 -1));
356     }
357 
358     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
359     if (rc < 0) {
360         ALOGE("ION allocation failed: %s\n", strerror(errno));
361         goto ION_ALLOC_FAILED;
362     }
363 
364     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
365     ion_info_fd.handle = alloc.handle;
366     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
367     if (rc < 0) {
368         ALOGE("ION map failed %s\n", strerror(errno));
369         goto ION_MAP_FAILED;
370     }
371 
372     memInfo.main_ion_fd = main_ion_fd;
373     memInfo.fd = ion_info_fd.fd;
374     memInfo.handle = ion_info_fd.handle;
375     memInfo.size = alloc.len;
376     memInfo.cached = cached;
377     memInfo.heap_id = heap_id;
378 
379     ALOGD("%s : ION buffer %lx with size %d allocated",
380             __func__, (unsigned long)memInfo.handle, alloc.len);
381     return OK;
382 
383 ION_MAP_FAILED:
384     memset(&handle_data, 0, sizeof(handle_data));
385     handle_data.handle = ion_info_fd.handle;
386     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
387 ION_ALLOC_FAILED:
388     close(main_ion_fd);
389 ION_OPEN_FAILED:
390     return NO_MEMORY;
391 }
392 
393 /*===========================================================================
394  * FUNCTION   : deallocOneBuffer
395  *
396  * DESCRIPTION: impl of deallocating one buffers
397  *
398  * PARAMETERS :
399  *   @memInfo : reference to struct that stores additional memory allocation info
400  *
401  * RETURN     : none
402  *==========================================================================*/
deallocOneBuffer(QCameraMemInfo & memInfo)403 void QCameraMemory::deallocOneBuffer(QCameraMemInfo &memInfo)
404 {
405     struct ion_handle_data handle_data;
406 
407     if (memInfo.fd > 0) {
408         close(memInfo.fd);
409         memInfo.fd = 0;
410     }
411 
412     if (memInfo.main_ion_fd > 0) {
413         memset(&handle_data, 0, sizeof(handle_data));
414         handle_data.handle = memInfo.handle;
415         ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
416         close(memInfo.main_ion_fd);
417         memInfo.main_ion_fd = 0;
418     }
419     memInfo.handle = 0;
420     memInfo.size = 0;
421 }
422 
423 /*===========================================================================
424  * FUNCTION   : QCameraMemoryPool
425  *
426  * DESCRIPTION: default constructor of QCameraMemoryPool
427  *
428  * PARAMETERS : None
429  *
430  * RETURN     : None
431  *==========================================================================*/
QCameraMemoryPool()432 QCameraMemoryPool::QCameraMemoryPool()
433 {
434     pthread_mutex_init(&mLock, NULL);
435 }
436 
437 
438 /*===========================================================================
439  * FUNCTION   : ~QCameraMemoryPool
440  *
441  * DESCRIPTION: deconstructor of QCameraMemoryPool
442  *
443  * PARAMETERS : None
444  *
445  * RETURN     : None
446  *==========================================================================*/
~QCameraMemoryPool()447 QCameraMemoryPool::~QCameraMemoryPool()
448 {
449     clear();
450     pthread_mutex_destroy(&mLock);
451 }
452 
453 /*===========================================================================
454  * FUNCTION   : releaseBuffer
455  *
456  * DESCRIPTION: release one cached buffers
457  *
458  * PARAMETERS :
459  *   @memInfo : reference to struct that stores additional memory allocation info
460  *   @streamType: Type of stream the buffers belongs to
461  *
462  * RETURN     : none
463  *==========================================================================*/
releaseBuffer(struct QCameraMemory::QCameraMemInfo & memInfo,cam_stream_type_t streamType)464 void QCameraMemoryPool::releaseBuffer(
465         struct QCameraMemory::QCameraMemInfo &memInfo,
466         cam_stream_type_t streamType)
467 {
468     pthread_mutex_lock(&mLock);
469 
470     mPools[streamType].push_back(memInfo);
471 
472     pthread_mutex_unlock(&mLock);
473 }
474 
475 /*===========================================================================
476  * FUNCTION   : clear
477  *
478  * DESCRIPTION: clears all cached buffers
479  *
480  * PARAMETERS : none
481  *
482  * RETURN     : none
483  *==========================================================================*/
clear()484 void QCameraMemoryPool::clear()
485 {
486     pthread_mutex_lock(&mLock);
487 
488     for (int i = CAM_STREAM_TYPE_DEFAULT; i < CAM_STREAM_TYPE_MAX; i++ ) {
489         List<struct QCameraMemory::QCameraMemInfo>::iterator it;
490         it = mPools[i].begin();
491         for( ; it != mPools[i].end() ; it++) {
492             QCameraMemory::deallocOneBuffer(*it);
493         }
494 
495         mPools[i].clear();
496     }
497 
498     pthread_mutex_unlock(&mLock);
499 }
500 
501 /*===========================================================================
502  * FUNCTION   : findBufferLocked
503  *
504  * DESCRIPTION: search for a appropriate cached buffer
505  *
506  * PARAMETERS :
507  *   @memInfo : reference to struct that stores additional memory allocation info
508  *   @heap_id : type of heap
509  *   @size    : size of the buffer
510  *   @cached  : whether the buffer should be cached
511  *   @streaType: type of stream this buffer belongs to
512  *
513  * RETURN     : int32_t type of status
514  *              NO_ERROR  -- success
515  *              none-zero failure code
516  *==========================================================================*/
findBufferLocked(struct QCameraMemory::QCameraMemInfo & memInfo,int heap_id,uint32_t size,bool cached,cam_stream_type_t streamType)517 int QCameraMemoryPool::findBufferLocked(
518         struct QCameraMemory::QCameraMemInfo &memInfo,
519         int heap_id,
520         uint32_t size,
521         bool cached,
522         cam_stream_type_t streamType)
523 {
524     int rc = NAME_NOT_FOUND;
525 
526     if (mPools[streamType].empty()) {
527         return NAME_NOT_FOUND;
528     }
529 
530     List<struct QCameraMemory::QCameraMemInfo>::iterator it;
531     it = mPools[streamType].begin();
532     for ( ; it != mPools[streamType].end() ; it++) {
533         if ( ((*it).size >= size) &&
534             ((*it).heap_id == heap_id) &&
535             ((*it).cached == cached) ) {
536             memInfo = *it;
537             mPools[streamType].erase(it);
538             rc = NO_ERROR;
539             break;
540         }
541     }
542 
543     return rc;
544 }
545 
546 /*===========================================================================
547  * FUNCTION   : allocateBuffer
548  *
549  * DESCRIPTION: allocates a buffer from the memory pool,
550  *              it will re-use cached buffers if possible
551  *
552  * PARAMETERS :
553  *   @memInfo : reference to struct that stores additional memory allocation info
554  *   @heap_id : type of heap
555  *   @size    : size of the buffer
556  *   @cached  : whether the buffer should be cached
557  *   @streaType: type of stream this buffer belongs to
558  *
559  * RETURN     : int32_t type of status
560  *              NO_ERROR  -- success
561  *              none-zero failure code
562  *==========================================================================*/
allocateBuffer(struct QCameraMemory::QCameraMemInfo & memInfo,int heap_id,int size,bool cached,cam_stream_type_t streamType,int secure_mode)563 int QCameraMemoryPool::allocateBuffer(
564         struct QCameraMemory::QCameraMemInfo &memInfo,
565         int heap_id,
566         int size,
567         bool cached,
568         cam_stream_type_t streamType,
569         int secure_mode)
570 {
571     int rc = NO_ERROR;
572 
573     pthread_mutex_lock(&mLock);
574 
575     rc = findBufferLocked(memInfo, heap_id, size, cached, streamType);
576     if (NAME_NOT_FOUND == rc ) {
577         ALOGE("%s : Buffer not found!", __func__);
578         rc = QCameraMemory::allocOneBuffer(memInfo, heap_id, size, cached,
579                  secure_mode);
580     }
581 
582     pthread_mutex_unlock(&mLock);
583 
584     return rc;
585 }
586 
587 /*===========================================================================
588  * FUNCTION   : QCameraHeapMemory
589  *
590  * DESCRIPTION: constructor of QCameraHeapMemory for ion memory used internally in HAL
591  *
592  * PARAMETERS :
593  *   @cached  : flag indicates if using cached memory
594  *
595  * RETURN     : none
596  *==========================================================================*/
QCameraHeapMemory(bool cached)597 QCameraHeapMemory::QCameraHeapMemory(bool cached)
598     : QCameraMemory(cached)
599 {
600     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
601         mPtr[i] = NULL;
602 }
603 
604 /*===========================================================================
605  * FUNCTION   : ~QCameraHeapMemory
606  *
607  * DESCRIPTION: deconstructor of QCameraHeapMemory
608  *
609  * PARAMETERS : none
610  *
611  * RETURN     : none
612  *==========================================================================*/
~QCameraHeapMemory()613 QCameraHeapMemory::~QCameraHeapMemory()
614 {
615 }
616 
617 /*===========================================================================
618  * FUNCTION   : getPtr
619  *
620  * DESCRIPTION: return buffer pointer
621  *
622  * PARAMETERS :
623  *   @index   : index of the buffer
624  *
625  * RETURN     : buffer ptr
626  *==========================================================================*/
getPtr(int index) const627 void *QCameraHeapMemory::getPtr(int index) const
628 {
629     if (index >= mBufferCount) {
630         ALOGE("index out of bound");
631         return (void *)BAD_INDEX;
632     }
633     return mPtr[index];
634 }
635 
636 /*===========================================================================
637  * FUNCTION   : allocate
638  *
639  * DESCRIPTION: allocate requested number of buffers of certain size
640  *
641  * PARAMETERS :
642  *   @count   : number of buffers to be allocated
643  *   @size    : lenght of the buffer to be allocated
644  *
645  * RETURN     : int32_t type of status
646  *              NO_ERROR  -- success
647  *              none-zero failure code
648  *==========================================================================*/
allocate(int count,int size,uint32_t isSecure)649 int QCameraHeapMemory::allocate(int count, int size, uint32_t isSecure)
650 {
651     int rc = -1;
652     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
653     if (isSecure == SECURE) {
654         int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
655         rc = alloc(count, size, heap_mask, SECURE);
656         if (rc < 0)
657             return rc;
658 
659     } else {
660         rc = alloc(count, size, heap_mask, NON_SECURE);
661         if (rc < 0)
662             return rc;
663 
664         for (int i = 0; i < count; i ++) {
665             void *vaddr = mmap(NULL,
666                         mMemInfo[i].size,
667                         PROT_READ | PROT_WRITE,
668                         MAP_SHARED,
669                         mMemInfo[i].fd, 0);
670             if (vaddr == MAP_FAILED) {
671                 for (int j = i-1; j >= 0; j --) {
672                     munmap(mPtr[j], mMemInfo[j].size);
673                     mPtr[j] = NULL;
674                     deallocOneBuffer(mMemInfo[j]);
675                 }
676                 return NO_MEMORY;
677             } else
678                 mPtr[i] = vaddr;
679         }
680     }
681     if (rc == 0) {
682         mBufferCount = count;
683     }
684     return OK;
685 }
686 
687 /*===========================================================================
688  * FUNCTION   : allocateMore
689  *
690  * DESCRIPTION: allocate more requested number of buffers of certain size
691  *
692  * PARAMETERS :
693  *   @count   : number of buffers to be allocated
694  *   @size    : lenght of the buffer to be allocated
695  *
696  * RETURN     : int32_t type of status
697  *              NO_ERROR  -- success
698  *              none-zero failure code
699  *==========================================================================*/
allocateMore(int count,int size)700 int QCameraHeapMemory::allocateMore(int count, int size)
701 {
702     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
703     int rc = alloc(count, size, heap_mask, NON_SECURE);
704     if (rc < 0)
705         return rc;
706 
707     for (int i = mBufferCount; i < count + mBufferCount; i ++) {
708         void *vaddr = mmap(NULL,
709                     mMemInfo[i].size,
710                     PROT_READ | PROT_WRITE,
711                     MAP_SHARED,
712                     mMemInfo[i].fd, 0);
713         if (vaddr == MAP_FAILED) {
714             for (int j = i-1; j >= mBufferCount; j --) {
715                 munmap(mPtr[j], mMemInfo[j].size);
716                 mPtr[j] = NULL;
717                 deallocOneBuffer(mMemInfo[j]);
718             }
719             return NO_MEMORY;
720         } else {
721             mPtr[i] = vaddr;
722         }
723     }
724     mBufferCount += count;
725     return OK;
726 }
727 
728 /*===========================================================================
729  * FUNCTION   : deallocate
730  *
731  * DESCRIPTION: deallocate buffers
732  *
733  * PARAMETERS : none
734  *
735  * RETURN     : none
736  *==========================================================================*/
deallocate()737 void QCameraHeapMemory::deallocate()
738 {
739     for (int i = 0; i < mBufferCount; i++) {
740         munmap(mPtr[i], mMemInfo[i].size);
741         mPtr[i] = NULL;
742     }
743     dealloc();
744     mBufferCount = 0;
745 }
746 
747 /*===========================================================================
748  * FUNCTION   : cacheOps
749  *
750  * DESCRIPTION: ion related memory cache operations
751  *
752  * PARAMETERS :
753  *   @index   : index of the buffer
754  *   @cmd     : cache ops command
755  *
756  * RETURN     : int32_t type of status
757  *              NO_ERROR  -- success
758  *              none-zero failure code
759  *==========================================================================*/
cacheOps(int index,unsigned int cmd)760 int QCameraHeapMemory::cacheOps(int index, unsigned int cmd)
761 {
762     if (index >= mBufferCount)
763         return BAD_INDEX;
764     return cacheOpsInternal(index, cmd, mPtr[index]);
765 }
766 
767 /*===========================================================================
768  * FUNCTION   : getRegFlags
769  *
770  * DESCRIPTION: query initial reg flags
771  *
772  * PARAMETERS :
773  *   @regFlags: initial reg flags of the allocated buffers
774  *
775  * RETURN     : int32_t type of status
776  *              NO_ERROR  -- success
777  *              none-zero failure code
778  *==========================================================================*/
getRegFlags(uint8_t *) const779 int QCameraHeapMemory::getRegFlags(uint8_t * /*regFlags*/) const
780 {
781     return INVALID_OPERATION;
782 }
783 
784 /*===========================================================================
785  * FUNCTION   : getMemory
786  *
787  * DESCRIPTION: get camera memory
788  *
789  * PARAMETERS :
790  *   @index   : buffer index
791  *   @metadata: flag if it's metadata
792  *
793  * RETURN     : camera memory ptr
794  *              NULL if not supported or failed
795  *==========================================================================*/
getMemory(int,bool) const796 camera_memory_t *QCameraHeapMemory::getMemory(
797                 int /*index*/, bool /*metadata*/) const
798 {
799     return NULL;
800 }
801 
802 /*===========================================================================
803  * FUNCTION   : getMatchBufIndex
804  *
805  * DESCRIPTION: query buffer index by opaque ptr
806  *
807  * PARAMETERS :
808  *   @opaque  : opaque ptr
809  *   @metadata: flag if it's metadata
810  *
811  * RETURN     : buffer index if match found,
812  *              -1 if failed
813  *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const814 int QCameraHeapMemory::getMatchBufIndex(const void *opaque,
815                                         bool metadata) const
816 {
817     int index = -1;
818     if (metadata) {
819         return -1;
820     }
821     for (int i = 0; i < mBufferCount; i++) {
822         if (mPtr[i] == opaque) {
823             index = i;
824             break;
825         }
826     }
827     return index;
828 }
829 
830 /*===========================================================================
831  * FUNCTION   : QCameraStreamMemory
832  *
833  * DESCRIPTION: constructor of QCameraStreamMemory
834  *              ION memory allocated directly from /dev/ion and shared with framework
835  *
836  * PARAMETERS :
837  *   @getMemory : camera memory request ops table
838  *   @cached    : flag indicates if using cached memory
839  *
840  * RETURN     : none
841  *==========================================================================*/
QCameraStreamMemory(camera_request_memory getMemory,bool cached,QCameraMemoryPool * pool,cam_stream_type_t streamType)842 QCameraStreamMemory::QCameraStreamMemory(camera_request_memory getMemory,
843         bool cached,
844         QCameraMemoryPool *pool,
845         cam_stream_type_t streamType)
846     :QCameraMemory(cached, pool, streamType),
847      mGetMemory(getMemory)
848 {
849     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
850         mCameraMemory[i] = NULL;
851 }
852 
853 /*===========================================================================
854  * FUNCTION   : ~QCameraStreamMemory
855  *
856  * DESCRIPTION: deconstructor of QCameraStreamMemory
857  *
858  * PARAMETERS : none
859  *
860  * RETURN     : none
861  *==========================================================================*/
~QCameraStreamMemory()862 QCameraStreamMemory::~QCameraStreamMemory()
863 {
864 }
865 
866 /*===========================================================================
867  * FUNCTION   : allocate
868  *
869  * DESCRIPTION: allocate requested number of buffers of certain size
870  *
871  * PARAMETERS :
872  *   @count   : number of buffers to be allocated
873  *   @size    : lenght of the buffer to be allocated
874  *
875  * RETURN     : int32_t type of status
876  *              NO_ERROR  -- success
877  *              none-zero failure code
878  *==========================================================================*/
allocate(int count,int size,uint32_t isSecure)879 int QCameraStreamMemory::allocate(int count, int size, uint32_t isSecure)
880 {
881     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
882     int rc = alloc(count, size, heap_mask, isSecure);
883     if (rc < 0)
884         return rc;
885 
886     for (int i = 0; i < count; i ++) {
887         if (isSecure == SECURE) {
888             mCameraMemory[i] = 0;
889         } else {
890             mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
891         }
892     }
893     mBufferCount = count;
894     return NO_ERROR;
895 }
896 
897 /*===========================================================================
898  * FUNCTION   : allocateMore
899  *
900  * DESCRIPTION: allocate more requested number of buffers of certain size
901  *
902  * PARAMETERS :
903  *   @count   : number of buffers to be allocated
904  *   @size    : lenght of the buffer to be allocated
905  *
906  * RETURN     : int32_t type of status
907  *              NO_ERROR  -- success
908  *              none-zero failure code
909  *==========================================================================*/
allocateMore(int count,int size)910 int QCameraStreamMemory::allocateMore(int count, int size)
911 {
912     int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
913     int rc = alloc(count, size, heap_mask, NON_SECURE);
914     if (rc < 0)
915         return rc;
916 
917     for (int i = mBufferCount; i < mBufferCount + count; i++) {
918         mCameraMemory[i] = mGetMemory(mMemInfo[i].fd, mMemInfo[i].size, 1, this);
919     }
920     mBufferCount += count;
921     return NO_ERROR;
922 }
923 
924 /*===========================================================================
925  * FUNCTION   : deallocate
926  *
927  * DESCRIPTION: deallocate buffers
928  *
929  * PARAMETERS : none
930  *
931  * RETURN     : none
932  *==========================================================================*/
deallocate()933 void QCameraStreamMemory::deallocate()
934 {
935     for (int i = 0; i < mBufferCount; i ++) {
936         if (mCameraMemory[i])
937             mCameraMemory[i]->release(mCameraMemory[i]);
938         mCameraMemory[i] = NULL;
939     }
940     dealloc();
941     mBufferCount = 0;
942 }
943 
944 /*===========================================================================
945  * FUNCTION   : cacheOps
946  *
947  * DESCRIPTION: ion related memory cache operations
948  *
949  * PARAMETERS :
950  *   @index   : index of the buffer
951  *   @cmd     : cache ops command
952  *
953  * RETURN     : int32_t type of status
954  *              NO_ERROR  -- success
955  *              none-zero failure code
956  *==========================================================================*/
cacheOps(int index,unsigned int cmd)957 int QCameraStreamMemory::cacheOps(int index, unsigned int cmd)
958 {
959     if (index >= mBufferCount)
960         return BAD_INDEX;
961     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
962 }
963 
964 /*===========================================================================
965  * FUNCTION   : getRegFlags
966  *
967  * DESCRIPTION: query initial reg flags
968  *
969  * PARAMETERS :
970  *   @regFlags: initial reg flags of the allocated buffers
971  *
972  * RETURN     : int32_t type of status
973  *              NO_ERROR  -- success
974  *              none-zero failure code
975  *==========================================================================*/
getRegFlags(uint8_t * regFlags) const976 int QCameraStreamMemory::getRegFlags(uint8_t *regFlags) const
977 {
978     for (int i = 0; i < mBufferCount; i ++)
979         regFlags[i] = 1;
980     return NO_ERROR;
981 }
982 
983 /*===========================================================================
984  * FUNCTION   : getMemory
985  *
986  * DESCRIPTION: get camera memory
987  *
988  * PARAMETERS :
989  *   @index   : buffer index
990  *   @metadata: flag if it's metadata
991  *
992  * RETURN     : camera memory ptr
993  *              NULL if not supported or failed
994  *==========================================================================*/
getMemory(int index,bool metadata) const995 camera_memory_t *QCameraStreamMemory::getMemory(int index, bool metadata) const
996 {
997     if (index >= mBufferCount || metadata)
998         return NULL;
999     return mCameraMemory[index];
1000 }
1001 
1002 /*===========================================================================
1003  * FUNCTION   : getMatchBufIndex
1004  *
1005  * DESCRIPTION: query buffer index by opaque ptr
1006  *
1007  * PARAMETERS :
1008  *   @opaque  : opaque ptr
1009  *   @metadata: flag if it's metadata
1010  *
1011  * RETURN     : buffer index if match found,
1012  *              -1 if failed
1013  *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1014 int QCameraStreamMemory::getMatchBufIndex(const void *opaque,
1015                                           bool metadata) const
1016 {
1017     int index = -1;
1018     if (metadata) {
1019         return -1;
1020     }
1021     for (int i = 0; i < mBufferCount; i++) {
1022         if (mCameraMemory[i]->data == opaque) {
1023             index = i;
1024             break;
1025         }
1026     }
1027     return index;
1028 }
1029 
1030 /*===========================================================================
1031  * FUNCTION   : getPtr
1032  *
1033  * DESCRIPTION: return buffer pointer
1034  *
1035  * PARAMETERS :
1036  *   @index   : index of the buffer
1037  *
1038  * RETURN     : buffer ptr
1039  *==========================================================================*/
getPtr(int index) const1040 void *QCameraStreamMemory::getPtr(int index) const
1041 {
1042     if (index >= mBufferCount) {
1043         ALOGE("index out of bound");
1044         return (void *)BAD_INDEX;
1045     }
1046     if (mCameraMemory[index] == 0) {
1047         return NULL;
1048     }
1049     return mCameraMemory[index]->data;
1050 }
1051 
1052 /*===========================================================================
1053  * FUNCTION   : QCameraVideoMemory
1054  *
1055  * DESCRIPTION: constructor of QCameraVideoMemory
1056  *              VideoStream buffers also include metadata buffers
1057  *
1058  * PARAMETERS :
1059  *   @getMemory : camera memory request ops table
1060  *   @cached    : flag indicates if using cached ION memory
1061  *
1062  * RETURN     : none
1063  *==========================================================================*/
QCameraVideoMemory(camera_request_memory getMemory,bool cached)1064 QCameraVideoMemory::QCameraVideoMemory(camera_request_memory getMemory,
1065                                        bool cached)
1066     : QCameraStreamMemory(getMemory, cached)
1067 {
1068     memset(mMetadata, 0, sizeof(mMetadata));
1069 }
1070 
1071 /*===========================================================================
1072  * FUNCTION   : ~QCameraVideoMemory
1073  *
1074  * DESCRIPTION: deconstructor of QCameraVideoMemory
1075  *
1076  * PARAMETERS : none
1077  *
1078  * RETURN     : none
1079  *==========================================================================*/
~QCameraVideoMemory()1080 QCameraVideoMemory::~QCameraVideoMemory()
1081 {
1082 }
1083 
1084 /*===========================================================================
1085  * FUNCTION   : allocate
1086  *
1087  * DESCRIPTION: allocate requested number of buffers of certain size
1088  *
1089  * PARAMETERS :
1090  *   @count   : number of buffers to be allocated
1091  *   @size    : lenght of the buffer to be allocated
1092  *
1093  * RETURN     : int32_t type of status
1094  *              NO_ERROR  -- success
1095  *              none-zero failure code
1096  *==========================================================================*/
allocate(int count,int size,uint32_t isSecure)1097 int QCameraVideoMemory::allocate(int count, int size, uint32_t isSecure)
1098 {
1099     int rc = QCameraStreamMemory::allocate(count, size, isSecure);
1100     if (rc < 0)
1101         return rc;
1102 
1103     for (int i = 0; i < count; i ++) {
1104         mMetadata[i] = mGetMemory(-1,
1105                 sizeof(struct encoder_media_buffer_type), 1, this);
1106         if (!mMetadata[i]) {
1107             ALOGE("allocation of video metadata failed.");
1108             for (int j = 0; j <= i-1; j ++)
1109                 mMetadata[j]->release(mMetadata[j]);
1110             QCameraStreamMemory::deallocate();
1111             return NO_MEMORY;
1112         }
1113         struct encoder_media_buffer_type * packet =
1114             (struct encoder_media_buffer_type *)mMetadata[i]->data;
1115         packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
1116         packet->buffer_type = kMetadataBufferTypeCameraSource;
1117         native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1118         nh->data[0] = mMemInfo[i].fd;
1119         nh->data[1] = 0;
1120         nh->data[2] = mMemInfo[i].size;
1121         nh->data[3] = private_handle_t::PRIV_FLAGS_ITU_R_709;
1122     }
1123     mBufferCount = count;
1124     return NO_ERROR;
1125 }
1126 
1127 /*===========================================================================
1128  * FUNCTION   : allocateMore
1129  *
1130  * DESCRIPTION: allocate more requested number of buffers of certain size
1131  *
1132  * PARAMETERS :
1133  *   @count   : number of buffers to be allocated
1134  *   @size    : lenght of the buffer to be allocated
1135  *
1136  * RETURN     : int32_t type of status
1137  *              NO_ERROR  -- success
1138  *              none-zero failure code
1139  *==========================================================================*/
allocateMore(int count,int size)1140 int QCameraVideoMemory::allocateMore(int count, int size)
1141 {
1142     int rc = QCameraStreamMemory::allocateMore(count, size);
1143     if (rc < 0)
1144         return rc;
1145 
1146     for (int i = mBufferCount; i < count + mBufferCount; i ++) {
1147         mMetadata[i] = mGetMemory(-1,
1148                 sizeof(struct encoder_media_buffer_type), 1, this);
1149         if (!mMetadata[i]) {
1150             ALOGE("allocation of video metadata failed.");
1151             for (int j = mBufferCount; j <= i-1; j ++) {
1152                 mMetadata[j]->release(mMetadata[j]);
1153                 mCameraMemory[j]->release(mCameraMemory[j]);
1154                 mCameraMemory[j] = NULL;
1155                 deallocOneBuffer(mMemInfo[j]);;
1156             }
1157             return NO_MEMORY;
1158         }
1159         struct encoder_media_buffer_type * packet =
1160             (struct encoder_media_buffer_type *)mMetadata[i]->data;
1161         packet->meta_handle = native_handle_create(1, 2); //1 fd, 1 offset and 1 size
1162         packet->buffer_type = kMetadataBufferTypeCameraSource;
1163         native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1164         nh->data[0] = mMemInfo[i].fd;
1165         nh->data[1] = 0;
1166         nh->data[2] = mMemInfo[i].size;
1167     }
1168     mBufferCount += count;
1169     return NO_ERROR;
1170 }
1171 
1172 /*===========================================================================
1173  * FUNCTION   : deallocate
1174  *
1175  * DESCRIPTION: deallocate buffers
1176  *
1177  * PARAMETERS : none
1178  *
1179  * RETURN     : none
1180  *==========================================================================*/
deallocate()1181 void QCameraVideoMemory::deallocate()
1182 {
1183     for (int i = 0; i < mBufferCount; i ++) {
1184         struct encoder_media_buffer_type * packet =
1185             (struct encoder_media_buffer_type *)mMetadata[i]->data;
1186         if (NULL != packet) {
1187             native_handle_t * nh = const_cast<native_handle_t *>(packet->meta_handle);
1188             if (NULL != nh) {
1189                if (native_handle_delete(nh)) {
1190                    ALOGE("Unable to delete native handle");
1191                }
1192             }
1193             else {
1194                ALOGE("native handle not available");
1195             }
1196         }
1197         else {
1198             ALOGE("packet not available");
1199         }
1200         mMetadata[i]->release(mMetadata[i]);
1201         mMetadata[i] = NULL;
1202     }
1203     QCameraStreamMemory::deallocate();
1204     mBufferCount = 0;
1205 }
1206 
1207 /*===========================================================================
1208  * FUNCTION   : getMemory
1209  *
1210  * DESCRIPTION: get camera memory
1211  *
1212  * PARAMETERS :
1213  *   @index   : buffer index
1214  *   @metadata: flag if it's metadata
1215  *
1216  * RETURN     : camera memory ptr
1217  *              NULL if not supported or failed
1218  *==========================================================================*/
getMemory(int index,bool metadata) const1219 camera_memory_t *QCameraVideoMemory::getMemory(int index, bool metadata) const
1220 {
1221     if (index >= mBufferCount)
1222         return NULL;
1223     if (metadata)
1224         return mMetadata[index];
1225     else
1226         return mCameraMemory[index];
1227 }
1228 
1229 /*===========================================================================
1230  * FUNCTION   : getMatchBufIndex
1231  *
1232  * DESCRIPTION: query buffer index by opaque ptr
1233  *
1234  * PARAMETERS :
1235  *   @opaque  : opaque ptr
1236  *   @metadata: flag if it's metadata
1237  *
1238  * RETURN     : buffer index if match found,
1239  *              -1 if failed
1240  *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1241 int QCameraVideoMemory::getMatchBufIndex(const void *opaque,
1242                                          bool metadata) const
1243 {
1244     int index = -1;
1245     for (int i = 0; i < mBufferCount; i++) {
1246         if (metadata) {
1247             if (mMetadata[i]->data == opaque) {
1248                 index = i;
1249                 break;
1250             }
1251         } else {
1252             if (mCameraMemory[i]->data == opaque) {
1253                 index = i;
1254                 break;
1255             }
1256         }
1257     }
1258     return index;
1259 }
1260 
1261 /*===========================================================================
1262  * FUNCTION   : QCameraGrallocMemory
1263  *
1264  * DESCRIPTION: constructor of QCameraGrallocMemory
1265  *              preview stream buffers are allocated from gralloc native_windoe
1266  *
1267  * PARAMETERS :
1268  *   @getMemory : camera memory request ops table
1269  *
1270  * RETURN     : none
1271  *==========================================================================*/
QCameraGrallocMemory(camera_request_memory getMemory)1272 QCameraGrallocMemory::QCameraGrallocMemory(camera_request_memory getMemory)
1273         : QCameraMemory(true), mColorSpace(ITU_R_601_FR)
1274 {
1275     mMinUndequeuedBuffers = 0;
1276     mWindow = NULL;
1277     mWidth = mHeight = mStride = mScanline = 0;
1278     mFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
1279     mGetMemory = getMemory;
1280     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
1281         mBufferHandle[i] = NULL;
1282         mLocalFlag[i] = BUFFER_NOT_OWNED;
1283         mPrivateHandle[i] = NULL;
1284     }
1285 }
1286 
1287 /*===========================================================================
1288  * FUNCTION   : ~QCameraGrallocMemory
1289  *
1290  * DESCRIPTION: deconstructor of QCameraGrallocMemory
1291  *
1292  * PARAMETERS : none
1293  *
1294  * RETURN     : none
1295  *==========================================================================*/
~QCameraGrallocMemory()1296 QCameraGrallocMemory::~QCameraGrallocMemory()
1297 {
1298 }
1299 
1300 /*===========================================================================
1301  * FUNCTION   : setWindowInfo
1302  *
1303  * DESCRIPTION: set native window gralloc ops table
1304  *
1305  * PARAMETERS :
1306  *   @window  : gralloc ops table ptr
1307  *   @width   : width of preview frame
1308  *   @height  : height of preview frame
1309  *   @stride  : stride of preview frame
1310  *   @scanline: scanline of preview frame
1311  *   @foramt  : format of preview image
1312  *
1313  * RETURN     : none
1314  *==========================================================================*/
setWindowInfo(preview_stream_ops_t * window,int width,int height,int stride,int scanline,int format)1315 void QCameraGrallocMemory::setWindowInfo(preview_stream_ops_t *window,
1316         int width, int height, int stride, int scanline, int format)
1317 {
1318     mWindow = window;
1319     mWidth = width;
1320     mHeight = height;
1321     mStride = stride;
1322     mScanline = scanline;
1323     mFormat = format;
1324 }
1325 
1326 /*===========================================================================
1327  * FUNCTION   : displayBuffer
1328  *
1329  * DESCRIPTION: send received frame to display
1330  *
1331  * PARAMETERS :
1332  *   @index   : index of preview frame
1333  *
1334  * RETURN     : int32_t type of status
1335  *              NO_ERROR  -- success
1336  *              none-zero failure code
1337  *==========================================================================*/
displayBuffer(int index)1338 int QCameraGrallocMemory::displayBuffer(int index)
1339 {
1340     int err = NO_ERROR;
1341     int dequeuedIdx = BAD_INDEX;
1342 
1343     if (BUFFER_NOT_OWNED == mLocalFlag[index]) {
1344         ALOGE("%s: buffer to be enqueued is not owned", __func__);
1345         return INVALID_OPERATION;
1346     }
1347 
1348     err = mWindow->enqueue_buffer(mWindow, (buffer_handle_t *)mBufferHandle[index]);
1349     if(err != 0) {
1350         ALOGE("%s: enqueue_buffer failed, err = %d", __func__, err);
1351     } else {
1352         CDBG("%s: enqueue_buffer hdl=%p", __func__, *mBufferHandle[index]);
1353         mLocalFlag[index] = BUFFER_NOT_OWNED;
1354     }
1355 
1356     buffer_handle_t *buffer_handle = NULL;
1357     int stride = 0;
1358     err = mWindow->dequeue_buffer(mWindow, &buffer_handle, &stride);
1359     if (err == NO_ERROR && buffer_handle != NULL) {
1360         int i;
1361         CDBG("%s: dequed buf hdl =%p", __func__, *buffer_handle);
1362         for(i = 0; i < mBufferCount; i++) {
1363             if(mBufferHandle[i] == buffer_handle) {
1364                 CDBG("%s: Found buffer in idx:%d", __func__, i);
1365                 mLocalFlag[i] = BUFFER_OWNED;
1366                 dequeuedIdx = i;
1367                 break;
1368             }
1369         }
1370     } else {
1371         CDBG_HIGH("%s: dequeue_buffer, no free buffer from display now", __func__);
1372     }
1373     return dequeuedIdx;
1374 }
1375 
1376 /*===========================================================================
1377  * FUNCTION   : allocate
1378  *
1379  * DESCRIPTION: allocate requested number of buffers of certain size
1380  *
1381  * PARAMETERS :
1382  *   @count   : number of buffers to be allocated
1383  *   @size    : lenght of the buffer to be allocated
1384  *
1385  * RETURN     : int32_t type of status
1386  *              NO_ERROR  -- success
1387  *              none-zero failure code
1388  *==========================================================================*/
allocate(int count,int,uint32_t)1389 int QCameraGrallocMemory::allocate(int count, int /*size*/, uint32_t /*isSecure*/)
1390 {
1391     int err = 0;
1392     status_t ret = NO_ERROR;
1393     int gralloc_usage = 0;
1394     struct ion_fd_data ion_info_fd;
1395     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
1396 
1397     CDBG(" %s : E ", __func__);
1398 
1399     if (!mWindow) {
1400         ALOGE("Invalid native window");
1401         return INVALID_OPERATION;
1402     }
1403 
1404     // Increment buffer count by min undequeued buffer.
1405     err = mWindow->get_min_undequeued_buffer_count(mWindow,&mMinUndequeuedBuffers);
1406     if (err != 0) {
1407         ALOGE("get_min_undequeued_buffer_count  failed: %s (%d)",
1408                 strerror(-err), -err);
1409         ret = UNKNOWN_ERROR;
1410         goto end;
1411     }
1412 
1413     err = mWindow->set_buffer_count(mWindow, count);
1414     if (err != 0) {
1415          ALOGE("set_buffer_count failed: %s (%d)",
1416                     strerror(-err), -err);
1417          ret = UNKNOWN_ERROR;
1418          goto end;
1419     }
1420 
1421     err = mWindow->set_buffers_geometry(mWindow, mStride, mScanline, mFormat);
1422     if (err != 0) {
1423          ALOGE("%s: set_buffers_geometry failed: %s (%d)",
1424                __func__, strerror(-err), -err);
1425          ret = UNKNOWN_ERROR;
1426          goto end;
1427     }
1428 
1429     err = mWindow->set_crop(mWindow, 0, 0, mWidth, mHeight);
1430     if (err != 0) {
1431          ALOGE("%s: set_crop failed: %s (%d)",
1432                __func__, strerror(-err), -err);
1433          ret = UNKNOWN_ERROR;
1434          goto end;
1435     }
1436 
1437     gralloc_usage = GRALLOC_USAGE_HW_CAMERA_WRITE | GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
1438     err = mWindow->set_usage(mWindow, gralloc_usage);
1439     if(err != 0) {
1440         /* set_usage error out */
1441         ALOGE("%s: set_usage rc = %d", __func__, err);
1442         ret = UNKNOWN_ERROR;
1443         goto end;
1444     }
1445     CDBG_HIGH("%s: usage = %d, geometry: %p, %d, %d, %d, %d, %d",
1446           __func__, gralloc_usage, mWindow, mWidth, mHeight, mStride,
1447           mScanline, mFormat);
1448 
1449     //Allocate cnt number of buffers from native window
1450     for (int cnt = 0; cnt < count; cnt++) {
1451         int stride;
1452         err = mWindow->dequeue_buffer(mWindow, &mBufferHandle[cnt], &stride);
1453         if(!err) {
1454             CDBG("dequeue buf hdl =%p", mBufferHandle[cnt]);
1455             mLocalFlag[cnt] = BUFFER_OWNED;
1456         } else {
1457             mLocalFlag[cnt] = BUFFER_NOT_OWNED;
1458             ALOGE("%s: dequeue_buffer idx = %d err = %d", __func__, cnt, err);
1459         }
1460 
1461         CDBG("%s: dequeue buf: %p\n", __func__, mBufferHandle[cnt]);
1462 
1463         if(err != 0) {
1464             ALOGE("%s: dequeue_buffer failed: %s (%d)",
1465                   __func__, strerror(-err), -err);
1466             ret = UNKNOWN_ERROR;
1467             for(int i = 0; i < cnt; i++) {
1468                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1469                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1470                     CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1471                 }
1472                 mLocalFlag[i] = BUFFER_NOT_OWNED;
1473                 mBufferHandle[i] = NULL;
1474             }
1475             memset(&mMemInfo, 0, sizeof(mMemInfo));
1476             goto end;
1477         }
1478 
1479         mPrivateHandle[cnt] =
1480             (struct private_handle_t *)(*mBufferHandle[cnt]);
1481         mMemInfo[cnt].main_ion_fd = open("/dev/ion", O_RDONLY);
1482         if (mMemInfo[cnt].main_ion_fd < 0) {
1483             ALOGE("%s: failed: could not open ion device", __func__);
1484             for(int i = 0; i < cnt; i++) {
1485                 struct ion_handle_data ion_handle;
1486                 memset(&ion_handle, 0, sizeof(ion_handle));
1487                 ion_handle.handle = mMemInfo[i].handle;
1488                 if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1489                     ALOGE("%s: ion free failed", __func__);
1490                 }
1491                 close(mMemInfo[i].main_ion_fd);
1492                 if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1493                     err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1494                     CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1495                 }
1496                 mLocalFlag[i] = BUFFER_NOT_OWNED;
1497                 mBufferHandle[i] = NULL;
1498             }
1499             memset(&mMemInfo, 0, sizeof(mMemInfo));
1500             ret = UNKNOWN_ERROR;
1501             goto end;
1502         } else {
1503             ion_info_fd.fd = mPrivateHandle[cnt]->fd;
1504             if (ioctl(mMemInfo[cnt].main_ion_fd,
1505                       ION_IOC_IMPORT, &ion_info_fd) < 0) {
1506                 ALOGE("%s: ION import failed\n", __func__);
1507                 for(int i = 0; i < cnt; i++) {
1508                     struct ion_handle_data ion_handle;
1509                     memset(&ion_handle, 0, sizeof(ion_handle));
1510                     ion_handle.handle = mMemInfo[i].handle;
1511                     if (ioctl(mMemInfo[i].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1512                         ALOGE("ion free failed");
1513                     }
1514                     close(mMemInfo[i].main_ion_fd);
1515 
1516                     if(mLocalFlag[i] != BUFFER_NOT_OWNED) {
1517                         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1518                         CDBG_HIGH("%s: cancel_buffer: hdl =%p", __func__, (*mBufferHandle[i]));
1519                     }
1520                     mLocalFlag[i] = BUFFER_NOT_OWNED;
1521                     mBufferHandle[i] = NULL;
1522                 }
1523                 close(mMemInfo[cnt].main_ion_fd);
1524                 memset(&mMemInfo, 0, sizeof(mMemInfo));
1525                 ret = UNKNOWN_ERROR;
1526                 goto end;
1527             }
1528         }
1529         setMetaData(mPrivateHandle[cnt], UPDATE_COLOR_SPACE, &mColorSpace);
1530         mCameraMemory[cnt] =
1531             mGetMemory(mPrivateHandle[cnt]->fd,
1532                     mPrivateHandle[cnt]->size,
1533                     1,
1534                     (void *)this);
1535         CDBG_HIGH("%s: idx = %d, fd = %d, size = %d, offset = %d",
1536               __func__, cnt, mPrivateHandle[cnt]->fd,
1537               mPrivateHandle[cnt]->size,
1538               mPrivateHandle[cnt]->offset);
1539         mMemInfo[cnt].fd =
1540             mPrivateHandle[cnt]->fd;
1541         mMemInfo[cnt].size =
1542             mPrivateHandle[cnt]->size;
1543         mMemInfo[cnt].handle = ion_info_fd.handle;
1544     }
1545     mBufferCount = count;
1546 
1547     //Cancel min_undequeued_buffer buffers back to the window
1548     for (int i = 0; i < mMinUndequeuedBuffers; i ++) {
1549         err = mWindow->cancel_buffer(mWindow, mBufferHandle[i]);
1550         mLocalFlag[i] = BUFFER_NOT_OWNED;
1551     }
1552 
1553 end:
1554     CDBG(" %s : X ",__func__);
1555     return ret;
1556 }
1557 
1558 
1559 /*===========================================================================
1560  * FUNCTION   : allocateMore
1561  *
1562  * DESCRIPTION: allocate more requested number of buffers of certain size
1563  *
1564  * PARAMETERS :
1565  *   @count   : number of buffers to be allocated
1566  *   @size    : lenght of the buffer to be allocated
1567  *
1568  * RETURN     : int32_t type of status
1569  *              NO_ERROR  -- success
1570  *              none-zero failure code
1571  *==========================================================================*/
allocateMore(int,int)1572 int QCameraGrallocMemory::allocateMore(int /*count*/, int /*size*/)
1573 {
1574     ALOGE("%s: Not implenmented yet", __func__);
1575     return UNKNOWN_ERROR;
1576 }
1577 
1578 /*===========================================================================
1579  * FUNCTION   : deallocate
1580  *
1581  * DESCRIPTION: deallocate buffers
1582  *
1583  * PARAMETERS : none
1584  *
1585  * RETURN     : none
1586  *==========================================================================*/
deallocate()1587 void QCameraGrallocMemory::deallocate()
1588 {
1589     CDBG("%s: E ", __FUNCTION__);
1590 
1591     for (int cnt = 0; cnt < mBufferCount; cnt++) {
1592         mCameraMemory[cnt]->release(mCameraMemory[cnt]);
1593         struct ion_handle_data ion_handle;
1594         memset(&ion_handle, 0, sizeof(ion_handle));
1595         ion_handle.handle = mMemInfo[cnt].handle;
1596         if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
1597             ALOGE("ion free failed");
1598         }
1599         close(mMemInfo[cnt].main_ion_fd);
1600         if(mLocalFlag[cnt] != BUFFER_NOT_OWNED) {
1601             if (mWindow) {
1602                 mWindow->cancel_buffer(mWindow, mBufferHandle[cnt]);
1603                 CDBG_HIGH("cancel_buffer: hdl =%p", (*mBufferHandle[cnt]));
1604             } else {
1605                 ALOGE("Preview window is NULL, cannot cancel_buffer: hdl =%p",
1606                       (*mBufferHandle[cnt]));
1607             }
1608         }
1609         mLocalFlag[cnt] = BUFFER_NOT_OWNED;
1610         CDBG_HIGH("put buffer %d successfully", cnt);
1611     }
1612     mBufferCount = 0;
1613     CDBG(" %s : X ",__FUNCTION__);
1614 }
1615 
1616 /*===========================================================================
1617  * FUNCTION   : cacheOps
1618  *
1619  * DESCRIPTION: ion related memory cache operations
1620  *
1621  * PARAMETERS :
1622  *   @index   : index of the buffer
1623  *   @cmd     : cache ops command
1624  *
1625  * RETURN     : int32_t type of status
1626  *              NO_ERROR  -- success
1627  *              none-zero failure code
1628  *==========================================================================*/
cacheOps(int index,unsigned int cmd)1629 int QCameraGrallocMemory::cacheOps(int index, unsigned int cmd)
1630 {
1631     if (index >= mBufferCount)
1632         return BAD_INDEX;
1633     return cacheOpsInternal(index, cmd, mCameraMemory[index]->data);
1634 }
1635 
1636 /*===========================================================================
1637  * FUNCTION   : getRegFlags
1638  *
1639  * DESCRIPTION: query initial reg flags
1640  *
1641  * PARAMETERS :
1642  *   @regFlags: initial reg flags of the allocated buffers
1643  *
1644  * RETURN     : int32_t type of status
1645  *              NO_ERROR  -- success
1646  *              none-zero failure code
1647  *==========================================================================*/
getRegFlags(uint8_t * regFlags) const1648 int QCameraGrallocMemory::getRegFlags(uint8_t *regFlags) const
1649 {
1650     int i = 0;
1651     for (i = 0; i < mMinUndequeuedBuffers; i ++)
1652         regFlags[i] = 0;
1653     for (; i < mBufferCount; i ++)
1654         regFlags[i] = 1;
1655     return NO_ERROR;
1656 }
1657 
1658 /*===========================================================================
1659  * FUNCTION   : getMemory
1660  *
1661  * DESCRIPTION: get camera memory
1662  *
1663  * PARAMETERS :
1664  *   @index   : buffer index
1665  *   @metadata: flag if it's metadata
1666  *
1667  * RETURN     : camera memory ptr
1668  *              NULL if not supported or failed
1669  *==========================================================================*/
getMemory(int index,bool metadata) const1670 camera_memory_t *QCameraGrallocMemory::getMemory(int index, bool metadata) const
1671 {
1672     if (index >= mBufferCount || metadata)
1673         return NULL;
1674     return mCameraMemory[index];
1675 }
1676 
1677 /*===========================================================================
1678  * FUNCTION   : getMatchBufIndex
1679  *
1680  * DESCRIPTION: query buffer index by opaque ptr
1681  *
1682  * PARAMETERS :
1683  *   @opaque  : opaque ptr
1684  *   @metadata: flag if it's metadata
1685  *
1686  * RETURN     : buffer index if match found,
1687  *              -1 if failed
1688  *==========================================================================*/
getMatchBufIndex(const void * opaque,bool metadata) const1689 int QCameraGrallocMemory::getMatchBufIndex(const void *opaque,
1690                                            bool metadata) const
1691 {
1692     int index = -1;
1693     if (metadata) {
1694         return -1;
1695     }
1696     for (int i = 0; i < mBufferCount; i++) {
1697         if (mCameraMemory[i]->data == opaque) {
1698             index = i;
1699             break;
1700         }
1701     }
1702     return index;
1703 }
1704 
1705 /*===========================================================================
1706  * FUNCTION   : getPtr
1707  *
1708  * DESCRIPTION: return buffer pointer
1709  *
1710  * PARAMETERS :
1711  *   @index   : index of the buffer
1712  *
1713  * RETURN     : buffer ptr
1714  *==========================================================================*/
getPtr(int index) const1715 void *QCameraGrallocMemory::getPtr(int index) const
1716 {
1717     if (index >= mBufferCount) {
1718         ALOGE("index out of bound");
1719         return (void *)BAD_INDEX;
1720     }
1721     return mCameraMemory[index]->data;
1722 }
1723 
1724 }; //namespace qcamera
1725