1 /* Copyright (c) 2012-2016, The Linux Foundation. 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 // System dependencies
33 #include <fcntl.h>
34 #define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h>
35 #include MMAN_H
36 #include "gralloc_priv.h"
37 
38 // Display dependencies
39 #include "qdMetaData.h"
40 
41 // Camera dependencies
42 #include "QCamera3HWI.h"
43 #include "QCamera3Mem.h"
44 #include "QCameraTrace.h"
45 
46 extern "C" {
47 #include "mm_camera_dbg.h"
48 #include "mm_camera_interface.h"
49 }
50 
51 using namespace android;
52 
53 namespace qcamera {
54 
55 // QCaemra2Memory base class
56 
57 /*===========================================================================
58  * FUNCTION   : QCamera3Memory
59  *
60  * DESCRIPTION: default constructor of QCamera3Memory
61  *
62  * PARAMETERS : none
63  *
64  * RETURN     : None
65  *==========================================================================*/
QCamera3Memory()66 QCamera3Memory::QCamera3Memory()
67 {
68     mBufferCount = 0;
69     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
70         mMemInfo[i].fd = -1;
71         mMemInfo[i].main_ion_fd = -1;
72         mMemInfo[i].handle = 0;
73         mMemInfo[i].size = 0;
74         mCurrentFrameNumbers[i] = -1;
75     }
76 }
77 
78 /*===========================================================================
79  * FUNCTION   : ~QCamera3Memory
80  *
81  * DESCRIPTION: deconstructor of QCamera3Memory
82  *
83  * PARAMETERS : none
84  *
85  * RETURN     : None
86  *==========================================================================*/
~QCamera3Memory()87 QCamera3Memory::~QCamera3Memory()
88 {
89 }
90 
91 /*===========================================================================
92  * FUNCTION   : cacheOpsInternal
93  *
94  * DESCRIPTION: ion related memory cache operations
95  *
96  * PARAMETERS :
97  *   @index   : index of the buffer
98  *   @cmd     : cache ops command
99  *   @vaddr   : ptr to the virtual address
100  *
101  * RETURN     : int32_t type of status
102  *              NO_ERROR  -- success
103  *              none-zero failure code
104  *==========================================================================*/
cacheOpsInternal(uint32_t index,unsigned int cmd,void * vaddr)105 int QCamera3Memory::cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr)
106 {
107     Mutex::Autolock lock(mLock);
108 
109     struct ion_flush_data cache_inv_data;
110     struct ion_custom_data custom_data;
111     int ret = OK;
112 
113     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
114         LOGE("index %d out of bound [0, %d)",
115                  index, MM_CAMERA_MAX_NUM_FRAMES);
116         return BAD_INDEX;
117     }
118 
119     if (0 == mMemInfo[index].handle) {
120         LOGE("Buffer at %d not registered", index);
121         return BAD_INDEX;
122     }
123 
124     memset(&cache_inv_data, 0, sizeof(cache_inv_data));
125     memset(&custom_data, 0, sizeof(custom_data));
126     cache_inv_data.vaddr = vaddr;
127     cache_inv_data.fd = mMemInfo[index].fd;
128     cache_inv_data.handle = mMemInfo[index].handle;
129     cache_inv_data.length = (unsigned int)mMemInfo[index].size;
130     custom_data.cmd = cmd;
131     custom_data.arg = (unsigned long)&cache_inv_data;
132 
133     LOGD("addr = %p, fd = %d, handle = %lx length = %d, ION Fd = %d",
134           cache_inv_data.vaddr, cache_inv_data.fd,
135          (unsigned long)cache_inv_data.handle, cache_inv_data.length,
136          mMemInfo[index].main_ion_fd);
137     ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
138     if (ret < 0)
139         LOGE("Cache Invalidate failed: %s\n", strerror(errno));
140 
141     return ret;
142 }
143 
144 /*===========================================================================
145  * FUNCTION   : getFd
146  *
147  * DESCRIPTION: return file descriptor of the indexed buffer
148  *
149  * PARAMETERS :
150  *   @index   : index of the buffer
151  *
152  * RETURN     : file descriptor
153  *==========================================================================*/
getFd(uint32_t index)154 int QCamera3Memory::getFd(uint32_t index)
155 {
156     Mutex::Autolock lock(mLock);
157 
158     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
159         return BAD_INDEX;
160     }
161 
162     if (0 == mMemInfo[index].handle) {
163         return BAD_INDEX;
164     }
165 
166     return mMemInfo[index].fd;
167 }
168 
169 /*===========================================================================
170  * FUNCTION   : getSize
171  *
172  * DESCRIPTION: return buffer size of the indexed buffer
173  *
174  * PARAMETERS :
175  *   @index   : index of the buffer
176  *
177  * RETURN     : buffer size
178  *==========================================================================*/
getSize(uint32_t index)179 ssize_t QCamera3Memory::getSize(uint32_t index)
180 {
181     Mutex::Autolock lock(mLock);
182 
183     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
184         return BAD_INDEX;
185     }
186 
187     if (0 == mMemInfo[index].handle) {
188         return BAD_INDEX;
189     }
190 
191     return (ssize_t)mMemInfo[index].size;
192 }
193 
194 /*===========================================================================
195  * FUNCTION   : getCnt
196  *
197  * DESCRIPTION: query number of buffers allocated
198  *
199  * PARAMETERS : none
200  *
201  * RETURN     : number of buffers allocated
202  *==========================================================================*/
getCnt()203 uint32_t QCamera3Memory::getCnt()
204 {
205     Mutex::Autolock lock(mLock);
206 
207     return mBufferCount;
208 }
209 
210 /*===========================================================================
211  * FUNCTION   : getBufDef
212  *
213  * DESCRIPTION: query detailed buffer information
214  *
215  * PARAMETERS :
216  *   @offset  : [input] frame buffer offset
217  *   @bufDef  : [output] reference to struct to store buffer definition
218  *   @index   : [input] index of the buffer
219  *
220  * RETURN     : int32_t type of status
221  *              NO_ERROR  -- success
222  *              none-zero failure code
223  *==========================================================================*/
getBufDef(const cam_frame_len_offset_t & offset,mm_camera_buf_def_t & bufDef,uint32_t index)224 int32_t QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
225         mm_camera_buf_def_t &bufDef, uint32_t index)
226 {
227     Mutex::Autolock lock(mLock);
228 
229     if (!mBufferCount) {
230         LOGE("Memory not allocated");
231         return NO_INIT;
232     }
233 
234     bufDef.fd = mMemInfo[index].fd;
235     bufDef.frame_len = mMemInfo[index].size;
236     bufDef.mem_info = (void *)this;
237     bufDef.buffer = getPtrLocked(index);
238     bufDef.planes_buf.num_planes = (int8_t)offset.num_planes;
239     bufDef.buf_idx = (uint8_t)index;
240 
241     /* Plane 0 needs to be set separately. Set other planes in a loop */
242     bufDef.planes_buf.planes[0].length = offset.mp[0].len;
243     bufDef.planes_buf.planes[0].m.userptr = (long unsigned int)mMemInfo[index].fd;
244     bufDef.planes_buf.planes[0].data_offset = offset.mp[0].offset;
245     bufDef.planes_buf.planes[0].reserved[0] = 0;
246     for (int i = 1; i < bufDef.planes_buf.num_planes; i++) {
247          bufDef.planes_buf.planes[i].length = offset.mp[i].len;
248          bufDef.planes_buf.planes[i].m.userptr = (long unsigned int)mMemInfo[i].fd;
249          bufDef.planes_buf.planes[i].data_offset = offset.mp[i].offset;
250          bufDef.planes_buf.planes[i].reserved[0] =
251                  bufDef.planes_buf.planes[i-1].reserved[0] +
252                  bufDef.planes_buf.planes[i-1].length;
253     }
254 
255     return NO_ERROR;
256 }
257 
258 /*===========================================================================
259  * FUNCTION   : QCamera3HeapMemory
260  *
261  * DESCRIPTION: constructor of QCamera3HeapMemory for ion memory used internally in HAL
262  *
263  * PARAMETERS : none
264  *
265  * RETURN     : none
266  *==========================================================================*/
QCamera3HeapMemory(uint32_t maxCnt)267 QCamera3HeapMemory::QCamera3HeapMemory(uint32_t maxCnt)
268     : QCamera3Memory()
269 {
270     mMaxCnt = MIN(maxCnt, MM_CAMERA_MAX_NUM_FRAMES);
271     for (uint32_t i = 0; i < mMaxCnt; i ++)
272         mPtr[i] = NULL;
273 }
274 
275 /*===========================================================================
276  * FUNCTION   : ~QCamera3HeapMemory
277  *
278  * DESCRIPTION: deconstructor of QCamera3HeapMemory
279  *
280  * PARAMETERS : none
281  *
282  * RETURN     : none
283  *==========================================================================*/
~QCamera3HeapMemory()284 QCamera3HeapMemory::~QCamera3HeapMemory()
285 {
286 }
287 
288 /*===========================================================================
289  * FUNCTION   : allocOneBuffer
290  *
291  * DESCRIPTION: impl of allocating one buffers of certain size
292  *
293  * PARAMETERS :
294  *   @memInfo : [output] reference to struct to store additional memory allocation info
295  *   @heap    : [input] heap id to indicate where the buffers will be allocated from
296  *   @size    : [input] lenght of the buffer to be allocated
297  *
298  * RETURN     : int32_t type of status
299  *              NO_ERROR  -- success
300  *              none-zero failure code
301  *==========================================================================*/
allocOneBuffer(QCamera3MemInfo & memInfo,unsigned int heap_id,size_t size)302 int QCamera3HeapMemory::allocOneBuffer(QCamera3MemInfo &memInfo,
303         unsigned int heap_id, size_t size)
304 {
305     int rc = OK;
306     struct ion_handle_data handle_data;
307     struct ion_allocation_data allocData;
308     struct ion_fd_data ion_info_fd;
309     int main_ion_fd = -1;
310 
311     main_ion_fd = open("/dev/ion", O_RDONLY);
312     if (main_ion_fd < 0) {
313         LOGE("Ion dev open failed: %s\n", strerror(errno));
314         goto ION_OPEN_FAILED;
315     }
316 
317     memset(&allocData, 0, sizeof(allocData));
318     allocData.len = size;
319     /* to make it page size aligned */
320     allocData.len = (allocData.len + 4095U) & (~4095U);
321     allocData.align = 4096;
322     allocData.flags = ION_FLAG_CACHED;
323     allocData.heap_id_mask = heap_id;
324     rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &allocData);
325     if (rc < 0) {
326         LOGE("ION allocation for len %d failed: %s\n", allocData.len,
327             strerror(errno));
328         goto ION_ALLOC_FAILED;
329     }
330 
331     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
332     ion_info_fd.handle = allocData.handle;
333     rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
334     if (rc < 0) {
335         LOGE("ION map failed %s\n", strerror(errno));
336         goto ION_MAP_FAILED;
337     }
338 
339     memInfo.main_ion_fd = main_ion_fd;
340     memInfo.fd = ion_info_fd.fd;
341     memInfo.handle = ion_info_fd.handle;
342     memInfo.size = allocData.len;
343     return OK;
344 
345 ION_MAP_FAILED:
346     memset(&handle_data, 0, sizeof(handle_data));
347     handle_data.handle = ion_info_fd.handle;
348     ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
349 ION_ALLOC_FAILED:
350     close(main_ion_fd);
351 ION_OPEN_FAILED:
352     return NO_MEMORY;
353 }
354 
355 /*===========================================================================
356  * FUNCTION   : deallocOneBuffer
357  *
358  * DESCRIPTION: impl of deallocating one buffers
359  *
360  * PARAMETERS :
361  *   @memInfo : reference to struct that stores additional memory allocation info
362  *
363  * RETURN     : none
364  *==========================================================================*/
deallocOneBuffer(QCamera3MemInfo & memInfo)365 void QCamera3HeapMemory::deallocOneBuffer(QCamera3MemInfo &memInfo)
366 {
367     struct ion_handle_data handle_data;
368 
369     if (memInfo.fd >= 0) {
370         close(memInfo.fd);
371         memInfo.fd = -1;
372     }
373 
374     if (memInfo.main_ion_fd >= 0) {
375         memset(&handle_data, 0, sizeof(handle_data));
376         handle_data.handle = memInfo.handle;
377         ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
378         close(memInfo.main_ion_fd);
379         memInfo.main_ion_fd = -1;
380     }
381     memInfo.handle = 0;
382     memInfo.size = 0;
383 }
384 
385 /*===========================================================================
386  * FUNCTION   : getPtrLocked
387  *
388  * DESCRIPTION: Return buffer pointer.
389  *
390  * PARAMETERS :
391  *   @index   : index of the buffer
392  *
393  * RETURN     : buffer ptr
394  *==========================================================================*/
getPtrLocked(uint32_t index)395 void *QCamera3HeapMemory::getPtrLocked(uint32_t index)
396 {
397     if (index >= mBufferCount) {
398         LOGE("index out of bound");
399         return (void *)BAD_INDEX;
400     }
401     return mPtr[index];
402 }
403 
404 /*===========================================================================
405  * FUNCTION   : markFrameNumber
406  *
407  * DESCRIPTION: We use this function from the request call path to mark the
408  *              buffers with the frame number they are intended for this info
409  *              is used later when giving out callback & it is duty of PP to
410  *              ensure that data for that particular frameNumber/Request is
411  *              written to this buffer.
412  * PARAMETERS :
413  *   @index   : index of the buffer
414  *   @frame#  : Frame number from the framework
415  *
416  * RETURN     : int32_t type of status
417  *              NO_ERROR  -- success
418  *              none-zero failure code
419  *==========================================================================*/
markFrameNumber(uint32_t index,uint32_t frameNumber)420 int32_t QCamera3HeapMemory::markFrameNumber(uint32_t index, uint32_t frameNumber)
421 {
422     Mutex::Autolock lock(mLock);
423 
424     if (index >= mBufferCount) {
425         LOGE("Index %d out of bounds, current buffer count is %d",
426                  index, mBufferCount);
427         return BAD_INDEX;
428     }
429 
430     if (0 == mMemInfo[index].handle) {
431         LOGE("Buffer at %d not allocated", index);
432         return BAD_INDEX;
433     }
434 
435     mCurrentFrameNumbers[index] = (int32_t)frameNumber;
436 
437     return NO_ERROR;
438 }
439 
440 /*===========================================================================
441  * FUNCTION   : getFrameNumber
442  *
443  * DESCRIPTION: We use this to fetch the frameNumber for the request with which
444  *              this buffer was given to HAL
445  *
446  *
447  * PARAMETERS :
448  *   @index   : index of the buffer
449  *
450  * RETURN     : int32_t frameNumber
451  *              positive/zero  -- success
452  *              negative failure
453  *==========================================================================*/
getFrameNumber(uint32_t index)454 int32_t QCamera3HeapMemory::getFrameNumber(uint32_t index)
455 {
456     Mutex::Autolock lock(mLock);
457 
458     if (index >= mBufferCount) {
459         LOGE("Index %d out of bounds, current buffer count is %d",
460                  index, mBufferCount);
461         return -1;
462     }
463 
464     if (0 == mMemInfo[index].handle) {
465         LOGE("Buffer at %d not registered", index);
466         return -1;
467     }
468 
469     return mCurrentFrameNumbers[index];
470 }
471 
472 /*===========================================================================
473  * FUNCTION   : getBufferIndex
474  *
475  * DESCRIPTION: We use this to fetch the buffer index for the request with
476  *              a particular frame number
477  *
478  *
479  * PARAMETERS :
480  *   @frameNumber  : frame number of the buffer
481  *
482  * RETURN     : int32_t buffer index
483  *              negative failure
484  *==========================================================================*/
getBufferIndex(uint32_t frameNumber)485 int32_t QCamera3HeapMemory::getBufferIndex(uint32_t frameNumber)
486 {
487     Mutex::Autolock lock(mLock);
488 
489     for (uint32_t index = 0;
490             index < mBufferCount; index++) {
491         if (mMemInfo[index].handle &&
492                 mCurrentFrameNumbers[index] == (int32_t)frameNumber)
493             return (int32_t)index;
494     }
495     return -1;
496 }
497 
498 /*===========================================================================
499  * FUNCTION   : getPtr
500  *
501  * DESCRIPTION: Return buffer pointer
502  *
503  * PARAMETERS :
504  *   @index   : index of the buffer
505  *
506  * RETURN     : buffer ptr
507  *==========================================================================*/
getPtr(uint32_t index)508 void *QCamera3HeapMemory::getPtr(uint32_t index)
509 {
510     return getPtrLocked(index);
511 }
512 
513 /*===========================================================================
514  * FUNCTION   : allocate
515  *
516  * DESCRIPTION: allocate requested number of buffers of certain size
517  *
518  * PARAMETERS :
519  *   @size    : lenght of the buffer to be allocated
520  *
521  * RETURN     : int32_t type of status
522  *              NO_ERROR  -- success
523  *              none-zero failure code
524  *==========================================================================*/
allocate(size_t size)525 int QCamera3HeapMemory::allocate(size_t size)
526 {
527     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
528     uint32_t i;
529     int rc = NO_ERROR;
530 
531     //Note that now we allow incremental allocation. In other words, we allow
532     //multiple alloc being called as long as the sum of count does not exceed
533     //mMaxCnt.
534     if (mBufferCount > 0) {
535         LOGE("There is already buffer allocated.");
536         return BAD_INDEX;
537     }
538 
539     for (i = 0; i < mMaxCnt; i ++) {
540         rc = allocOneBuffer(mMemInfo[i], heap_id_mask, size);
541         if (rc < 0) {
542             LOGE("AllocateIonMemory failed");
543             goto ALLOC_FAILED;
544         }
545 
546         void *vaddr = mmap(NULL,
547                     mMemInfo[i].size,
548                     PROT_READ | PROT_WRITE,
549                     MAP_SHARED,
550                     mMemInfo[i].fd, 0);
551         if (vaddr == MAP_FAILED) {
552             deallocOneBuffer(mMemInfo[i]);
553             LOGE("mmap failed for buffer %d", i);
554             goto ALLOC_FAILED;
555         } else
556             mPtr[i] = vaddr;
557     }
558     if (rc == 0)
559         mBufferCount = mMaxCnt;
560 
561     return OK;
562 
563 ALLOC_FAILED:
564     for (uint32_t j = 0; j < i; j++) {
565         munmap(mPtr[j], mMemInfo[j].size);
566         mPtr[j] = NULL;
567         deallocOneBuffer(mMemInfo[j]);
568     }
569     return NO_MEMORY;
570 }
571 
572 /*===========================================================================
573  * FUNCTION   : allocateOne
574  *
575  * DESCRIPTION: allocate one buffer
576  *
577  * PARAMETERS :
578  *   @size    : lenght of the buffer to be allocated
579  *
580  * RETURN     : int32_t type of status
581  *              NO_ERROR  -- success
582  *              none-zero failure code
583  *==========================================================================*/
allocateOne(size_t size)584 int QCamera3HeapMemory::allocateOne(size_t size)
585 {
586     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
587     int rc = NO_ERROR;
588 
589     //Note that now we allow incremental allocation. In other words, we allow
590     //multiple alloc being called as long as the sum of count does not exceed
591     //mMaxCnt.
592     if (mBufferCount + 1 > mMaxCnt) {
593         LOGE("Buffer count %d + 1 out of bound. Max is %d",
594                 mBufferCount, mMaxCnt);
595         return BAD_INDEX;
596     }
597 
598     rc = allocOneBuffer(mMemInfo[mBufferCount], heap_id_mask, size);
599     if (rc < 0) {
600         LOGE("AllocateIonMemory failed");
601         return NO_MEMORY;
602     }
603 
604     void *vaddr = mmap(NULL,
605                 mMemInfo[mBufferCount].size,
606                 PROT_READ | PROT_WRITE,
607                 MAP_SHARED,
608                 mMemInfo[mBufferCount].fd, 0);
609     if (vaddr == MAP_FAILED) {
610         deallocOneBuffer(mMemInfo[mBufferCount]);
611         LOGE("mmap failed for buffer");
612         return NO_MEMORY;
613     } else
614         mPtr[mBufferCount] = vaddr;
615 
616     if (rc == 0)
617         mBufferCount += 1;
618 
619     return mBufferCount-1;
620 }
621 
622 /*===========================================================================
623  * FUNCTION   : deallocate
624  *
625  * DESCRIPTION: deallocate buffers
626  *
627  * PARAMETERS : none
628  *
629  * RETURN     : none
630  *==========================================================================*/
deallocate()631 void QCamera3HeapMemory::deallocate()
632 {
633     for (uint32_t i = 0; i < mBufferCount; i++) {
634         munmap(mPtr[i], mMemInfo[i].size);
635         mPtr[i] = NULL;
636         deallocOneBuffer(mMemInfo[i]);
637         mCurrentFrameNumbers[i] = -1;
638     }
639     mBufferCount = 0;
640 }
641 
642 /*===========================================================================
643  * FUNCTION   : cacheOps
644  *
645  * DESCRIPTION: ion related memory cache operations
646  *
647  * PARAMETERS :
648  *   @index   : index of the buffer
649  *   @cmd     : cache ops command
650  *
651  * RETURN     : int32_t type of status
652  *              NO_ERROR  -- success
653  *              none-zero failure code
654  *==========================================================================*/
cacheOps(uint32_t index,unsigned int cmd)655 int QCamera3HeapMemory::cacheOps(uint32_t index, unsigned int cmd)
656 {
657     if (index >= mBufferCount)
658         return BAD_INDEX;
659     return cacheOpsInternal(index, cmd, mPtr[index]);
660 }
661 
662 /*===========================================================================
663  * FUNCTION   : getMatchBufIndex
664  *
665  * DESCRIPTION: query buffer index by object ptr
666  *
667  * PARAMETERS :
668  *   @object  : object ptr
669  *
670  * RETURN     : buffer index if match found,
671  *              -1 if failed
672  *==========================================================================*/
getMatchBufIndex(void *)673 int QCamera3HeapMemory::getMatchBufIndex(void * /*object*/)
674 {
675 
676 /*
677     TODO for HEAP memory type, would there be an equivalent requirement?
678 
679     int index = -1;
680     buffer_handle_t *key = (buffer_handle_t*) object;
681     if (!key) {
682         return BAD_VALUE;
683     }
684     for (int i = 0; i < mBufferCount; i++) {
685         if (mBufferHandle[i] == key) {
686             index = i;
687             break;
688         }
689     }
690     return index;
691 */
692     LOGE("FATAL: Not supposed to come here");
693     return -1;
694 }
695 
696 /*===========================================================================
697  * FUNCTION   : QCamera3GrallocMemory
698  *
699  * DESCRIPTION: constructor of QCamera3GrallocMemory
700  *              preview stream buffers are allocated from gralloc native_windoe
701  *
702  * PARAMETERS :
703  *   @startIdx : start index of array after which we can register buffers in.
704  *
705  * RETURN     : none
706  *==========================================================================*/
QCamera3GrallocMemory(uint32_t startIdx)707 QCamera3GrallocMemory::QCamera3GrallocMemory(uint32_t startIdx)
708         : QCamera3Memory(), mStartIdx(startIdx)
709 {
710     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
711         mBufferHandle[i] = NULL;
712         mPrivateHandle[i] = NULL;
713     }
714 }
715 
716 /*===========================================================================
717  * FUNCTION   : ~QCamera3GrallocMemory
718  *
719  * DESCRIPTION: deconstructor of QCamera3GrallocMemory
720  *
721  * PARAMETERS : none
722  *
723  * RETURN     : none
724  *==========================================================================*/
~QCamera3GrallocMemory()725 QCamera3GrallocMemory::~QCamera3GrallocMemory()
726 {
727 }
728 
729 /*===========================================================================
730  * FUNCTION   : registerBuffer
731  *
732  * DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t
733  *
734  * PARAMETERS :
735  *   @buffers : buffer_handle_t pointer
736  *   @type :    cam_stream_type_t
737  *
738  * RETURN     : int32_t type of status
739  *              NO_ERROR  -- success
740  *              none-zero failure code
741  *==========================================================================*/
registerBuffer(buffer_handle_t * buffer,__unused cam_stream_type_t type)742 int QCamera3GrallocMemory::registerBuffer(buffer_handle_t *buffer,
743         __unused cam_stream_type_t type)
744 {
745     status_t ret = NO_ERROR;
746     struct ion_fd_data ion_info_fd;
747     void *vaddr = NULL;
748     int32_t colorSpace = ITU_R_601_FR;
749     int32_t idx = -1;
750 
751     LOGD("E");
752 
753     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
754 
755     if (0 <= getMatchBufIndex((void *) buffer)) {
756         LOGL("Buffer already registered");
757         return ALREADY_EXISTS;
758     }
759 
760     Mutex::Autolock lock(mLock);
761     if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1 - mStartIdx)) {
762         LOGE("Number of buffers %d greater than what's supported %d",
763                  mBufferCount, MM_CAMERA_MAX_NUM_FRAMES - mStartIdx);
764         return BAD_INDEX;
765     }
766 
767     idx = getFreeIndexLocked();
768     if (0 > idx) {
769         LOGE("No available memory slots");
770         return BAD_INDEX;
771     }
772 
773     mBufferHandle[idx] = buffer;
774     mPrivateHandle[idx] = (struct private_handle_t *)(*mBufferHandle[idx]);
775 
776     setMetaData(mPrivateHandle[idx], UPDATE_COLOR_SPACE, &colorSpace);
777 
778     mMemInfo[idx].main_ion_fd = open("/dev/ion", O_RDONLY);
779     if (mMemInfo[idx].main_ion_fd < 0) {
780         LOGE("failed: could not open ion device");
781         ret = NO_MEMORY;
782         goto end;
783     } else {
784         ion_info_fd.fd = mPrivateHandle[idx]->fd;
785         if (ioctl(mMemInfo[idx].main_ion_fd,
786                   ION_IOC_IMPORT, &ion_info_fd) < 0) {
787             LOGE("ION import failed\n");
788             close(mMemInfo[idx].main_ion_fd);
789             ret = NO_MEMORY;
790             goto end;
791         }
792     }
793     LOGD("idx = %d, fd = %d, size = %d, offset = %d",
794              idx, mPrivateHandle[idx]->fd,
795             mPrivateHandle[idx]->size,
796             mPrivateHandle[idx]->offset);
797     mMemInfo[idx].fd = mPrivateHandle[idx]->fd;
798     mMemInfo[idx].size =
799             ( /* FIXME: Should update ION interface */ size_t)
800             mPrivateHandle[idx]->size;
801     mMemInfo[idx].handle = ion_info_fd.handle;
802 
803     vaddr = mmap(NULL,
804             mMemInfo[idx].size,
805             PROT_READ | PROT_WRITE,
806             MAP_SHARED,
807             mMemInfo[idx].fd, 0);
808     if (vaddr == MAP_FAILED) {
809         mMemInfo[idx].handle = 0;
810         ret = NO_MEMORY;
811     } else {
812         mPtr[idx] = vaddr;
813         mBufferCount++;
814     }
815 
816 end:
817     LOGD("X ");
818     return ret;
819 }
820 /*===========================================================================
821  * FUNCTION   : unregisterBufferLocked
822  *
823  * DESCRIPTION: Unregister buffer. Please note that this method has to be
824  *              called with 'mLock' acquired.
825  *
826  * PARAMETERS :
827  *   @idx     : unregister buffer at index 'idx'
828  *
829  * RETURN     : int32_t type of status
830  *              NO_ERROR  -- success
831  *              none-zero failure code
832  *==========================================================================*/
unregisterBufferLocked(size_t idx)833 int32_t QCamera3GrallocMemory::unregisterBufferLocked(size_t idx)
834 {
835     munmap(mPtr[idx], mMemInfo[idx].size);
836     mPtr[idx] = NULL;
837 
838     struct ion_handle_data ion_handle;
839     memset(&ion_handle, 0, sizeof(ion_handle));
840     ion_handle.handle = mMemInfo[idx].handle;
841     if (ioctl(mMemInfo[idx].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
842         LOGE("ion free failed");
843     }
844     close(mMemInfo[idx].main_ion_fd);
845     memset(&mMemInfo[idx], 0, sizeof(struct QCamera3MemInfo));
846     mMemInfo[idx].main_ion_fd = -1;
847     mBufferHandle[idx] = NULL;
848     mPrivateHandle[idx] = NULL;
849     mCurrentFrameNumbers[idx] = -1;
850     mBufferCount--;
851 
852     return NO_ERROR;
853 }
854 
855 /*===========================================================================
856  * FUNCTION   : unregisterBuffer
857  *
858  * DESCRIPTION: unregister buffer
859  *
860  * PARAMETERS :
861  *   @idx     : unregister buffer at index 'idx'
862  *
863  * RETURN     : int32_t type of status
864  *              NO_ERROR  -- success
865  *              none-zero failure code
866  *==========================================================================*/
unregisterBuffer(size_t idx)867 int32_t QCamera3GrallocMemory::unregisterBuffer(size_t idx)
868 {
869     int32_t rc = NO_ERROR;
870     Mutex::Autolock lock(mLock);
871 
872     LOGD("E ", __FUNCTION__);
873 
874     if (MM_CAMERA_MAX_NUM_FRAMES <= idx) {
875         LOGE("Buffer index %d greater than what is supported %d",
876                  idx, MM_CAMERA_MAX_NUM_FRAMES);
877         return BAD_VALUE;
878     }
879     if (idx < mStartIdx) {
880         LOGE("buffer index %d less than starting index %d",
881                  idx, mStartIdx);
882         return BAD_INDEX;
883     }
884 
885     if (0 == mMemInfo[idx].handle) {
886         LOGE("Trying to unregister buffer at %d which still not registered",
887                  idx);
888         return BAD_VALUE;
889     }
890 
891     rc = unregisterBufferLocked(idx);
892 
893     LOGD("X ",__FUNCTION__);
894 
895     return rc;
896 }
897 
898 /*===========================================================================
899  * FUNCTION   : unregisterBuffers
900  *
901  * DESCRIPTION: unregister buffers
902  *
903  * PARAMETERS : none
904  *
905  * RETURN     : none
906  *==========================================================================*/
unregisterBuffers()907 void QCamera3GrallocMemory::unregisterBuffers()
908 {
909     int err = NO_ERROR;
910     Mutex::Autolock lock(mLock);
911 
912     LOGD("E ", __FUNCTION__);
913 
914     for (uint32_t cnt = mStartIdx; cnt < MM_CAMERA_MAX_NUM_FRAMES; cnt++) {
915         if (0 == mMemInfo[cnt].handle) {
916             continue;
917         }
918         err = unregisterBufferLocked(cnt);
919         if (NO_ERROR != err) {
920             LOGE("Error unregistering buffer %d error %d",
921                      cnt, err);
922         }
923     }
924     mBufferCount = 0;
925     LOGD("X ",__FUNCTION__);
926 }
927 
928 /*===========================================================================
929  * FUNCTION   : markFrameNumber
930  *
931  * DESCRIPTION: We use this function from the request call path to mark the
932  *              buffers with the frame number they are intended for this info
933  *              is used later when giving out callback & it is duty of PP to
934  *              ensure that data for that particular frameNumber/Request is
935  *              written to this buffer.
936  * PARAMETERS :
937  *   @index   : index of the buffer
938  *   @frame#  : Frame number from the framework
939  *
940  * RETURN     : int32_t type of status
941  *              NO_ERROR  -- success
942  *              none-zero failure code
943  *==========================================================================*/
markFrameNumber(uint32_t index,uint32_t frameNumber)944 int32_t QCamera3GrallocMemory::markFrameNumber(uint32_t index, uint32_t frameNumber)
945 {
946     Mutex::Autolock lock(mLock);
947 
948     if (index >= MM_CAMERA_MAX_NUM_FRAMES) {
949         LOGE("Index out of bounds");
950         return BAD_INDEX;
951     }
952     if (index < mStartIdx) {
953         LOGE("buffer index %d less than starting index %d",
954                  index, mStartIdx);
955         return BAD_INDEX;
956     }
957 
958     if (0 == mMemInfo[index].handle) {
959         LOGE("Buffer at %d not registered", index);
960         return BAD_INDEX;
961     }
962 
963     mCurrentFrameNumbers[index] = (int32_t)frameNumber;
964 
965     return NO_ERROR;
966 }
967 
968 /*===========================================================================
969  * FUNCTION   : getFrameNumber
970  *
971  * DESCRIPTION: We use this to fetch the frameNumber for the request with which
972  *              this buffer was given to HAL
973  *
974  *
975  * PARAMETERS :
976  *   @index   : index of the buffer
977  *
978  * RETURN     : int32_t frameNumber
979  *              positive/zero  -- success
980  *              negative failure
981  *==========================================================================*/
getFrameNumber(uint32_t index)982 int32_t QCamera3GrallocMemory::getFrameNumber(uint32_t index)
983 {
984     Mutex::Autolock lock(mLock);
985 
986     if (index >= MM_CAMERA_MAX_NUM_FRAMES) {
987         LOGE("Index out of bounds");
988         return -1;
989     }
990     if (index < mStartIdx) {
991         LOGE("buffer index %d less than starting index %d",
992                  index, mStartIdx);
993         return BAD_INDEX;
994     }
995 
996     if (0 == mMemInfo[index].handle) {
997         LOGE("Buffer at %d not registered", index);
998         return -1;
999     }
1000 
1001     return mCurrentFrameNumbers[index];
1002 }
1003 
1004 /*===========================================================================
1005  * FUNCTION   : getBufferIndex
1006  *
1007  * DESCRIPTION: We use this to fetch the buffer index for the request with
1008  *              a particular frame number
1009  *
1010  *
1011  * PARAMETERS :
1012  *   @frameNumber  : frame number of the buffer
1013  *
1014  * RETURN     : int32_t buffer index
1015  *              negative failure
1016  *==========================================================================*/
getBufferIndex(uint32_t frameNumber)1017 int32_t QCamera3GrallocMemory::getBufferIndex(uint32_t frameNumber)
1018 {
1019     for (uint32_t index = mStartIdx;
1020             index < MM_CAMERA_MAX_NUM_FRAMES; index++) {
1021         if (mMemInfo[index].handle &&
1022                 mCurrentFrameNumbers[index] == (int32_t)frameNumber)
1023             return (int32_t)index;
1024     }
1025     return -1;
1026 }
1027 
1028 /*===========================================================================
1029  * FUNCTION   : cacheOps
1030  *
1031  * DESCRIPTION: ion related memory cache operations
1032  *
1033  * PARAMETERS :
1034  *   @index   : index of the buffer
1035  *   @cmd     : cache ops command
1036  *
1037  * RETURN     : int32_t type of status
1038  *              NO_ERROR  -- success
1039  *              none-zero failure code
1040  *==========================================================================*/
cacheOps(uint32_t index,unsigned int cmd)1041 int QCamera3GrallocMemory::cacheOps(uint32_t index, unsigned int cmd)
1042 {
1043     if (index >= MM_CAMERA_MAX_NUM_FRAMES) {
1044         LOGE("Index out of bounds");
1045         return -1;
1046     }
1047     if (index < mStartIdx) {
1048         LOGE("buffer index %d less than starting index %d",
1049                  index, mStartIdx);
1050         return BAD_INDEX;
1051     }
1052 
1053     return cacheOpsInternal(index, cmd, mPtr[index]);
1054 }
1055 
1056 /*===========================================================================
1057  * FUNCTION   : getMatchBufIndex
1058  *
1059  * DESCRIPTION: query buffer index by object ptr
1060  *
1061  * PARAMETERS :
1062  *   @opaque  : opaque ptr
1063  *
1064  * RETURN     : buffer index if match found,
1065  *              -1 if failed
1066  *==========================================================================*/
getMatchBufIndex(void * object)1067 int QCamera3GrallocMemory::getMatchBufIndex(void *object)
1068 {
1069     Mutex::Autolock lock(mLock);
1070 
1071     int index = -1;
1072     buffer_handle_t *key = (buffer_handle_t*) object;
1073     if (!key) {
1074         return BAD_VALUE;
1075     }
1076     for (uint32_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
1077         if (mBufferHandle[i] == key) {
1078             index = (int)i;
1079             break;
1080         }
1081     }
1082 
1083     return index;
1084 }
1085 
1086 /*===========================================================================
1087  * FUNCTION   : getFreeIndexLocked
1088  *
1089  * DESCRIPTION: Find free index slot. Note 'mLock' needs to be acquired
1090  *              before calling this method.
1091  *
1092  * PARAMETERS : None
1093  *
1094  * RETURN     : free buffer index if found,
1095  *              -1 if failed
1096  *==========================================================================*/
getFreeIndexLocked()1097 int QCamera3GrallocMemory::getFreeIndexLocked()
1098 {
1099     int index = -1;
1100 
1101     if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1)) {
1102         LOGE("Number of buffers %d greater than what's supported %d",
1103              mBufferCount, MM_CAMERA_MAX_NUM_FRAMES);
1104         return index;
1105     }
1106 
1107     for (size_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
1108         if (0 == mMemInfo[i].handle) {
1109             index = i;
1110             break;
1111         }
1112     }
1113 
1114     return index;
1115 }
1116 
1117 /*===========================================================================
1118  * FUNCTION   : getPtrLocked
1119  *
1120  * DESCRIPTION: Return buffer pointer. Please note 'mLock' must be acquired
1121  *              before calling this method.
1122  *
1123  * PARAMETERS :
1124  *   @index   : index of the buffer
1125  *
1126  * RETURN     : buffer ptr
1127  *==========================================================================*/
getPtrLocked(uint32_t index)1128 void *QCamera3GrallocMemory::getPtrLocked(uint32_t index)
1129 {
1130     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
1131         LOGE("index %d out of bound [0, %d)",
1132                  index, MM_CAMERA_MAX_NUM_FRAMES);
1133         return NULL;
1134     }
1135     if (index < mStartIdx) {
1136         LOGE("buffer index %d less than starting index %d",
1137                  index, mStartIdx);
1138         return NULL;
1139     }
1140 
1141 
1142     if (0 == mMemInfo[index].handle) {
1143         LOGE("Buffer at %d not registered", index);
1144         return NULL;
1145     }
1146 
1147     return mPtr[index];
1148 }
1149 
1150 /*===========================================================================
1151  * FUNCTION   : getPtr
1152  *
1153  * DESCRIPTION: Return buffer pointer.
1154  *
1155  * PARAMETERS :
1156  *   @index   : index of the buffer
1157  *
1158  * RETURN     : buffer ptr
1159  *==========================================================================*/
getPtr(uint32_t index)1160 void *QCamera3GrallocMemory::getPtr(uint32_t index)
1161 {
1162     Mutex::Autolock lock(mLock);
1163     return getPtrLocked(index);
1164 }
1165 
1166 /*===========================================================================
1167  * FUNCTION   : getBufferHandle
1168  *
1169  * DESCRIPTION: return framework pointer
1170  *
1171  * PARAMETERS :
1172  *   @index   : index of the buffer
1173  *
1174  * RETURN     : buffer ptr if match found
1175                 NULL if failed
1176  *==========================================================================*/
getBufferHandle(uint32_t index)1177 void *QCamera3GrallocMemory::getBufferHandle(uint32_t index)
1178 {
1179     Mutex::Autolock lock(mLock);
1180 
1181     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
1182         LOGE("index %d out of bound [0, %d)",
1183                  index, MM_CAMERA_MAX_NUM_FRAMES);
1184         return NULL;
1185     }
1186     if (index < mStartIdx) {
1187         LOGE("buffer index %d less than starting index %d",
1188                  index, mStartIdx);
1189         return NULL;
1190     }
1191 
1192     if (0 == mMemInfo[index].handle) {
1193         LOGE("Buffer at %d not registered", index);
1194         return NULL;
1195     }
1196 
1197     return mBufferHandle[index];
1198 }
1199 }; //namespace qcamera
1200