• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 NULL;
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 /*===========================================================================
442  * FUNCTION   : getFrameNumber
443  *
444  * DESCRIPTION: We use this to fetch the frameNumber for the request with which
445  *              this buffer was given to HAL
446  *
447  *
448  * PARAMETERS :
449  *   @index   : index of the buffer
450  *
451  * RETURN     : int32_t frameNumber
452  *              positive/zero  -- success
453  *              negative failure
454  *==========================================================================*/
getFrameNumber(uint32_t index)455 int32_t QCamera3HeapMemory::getFrameNumber(uint32_t index)
456 {
457     Mutex::Autolock lock(mLock);
458 
459     if (index >= mBufferCount) {
460         LOGE("Index %d out of bounds, current buffer count is %d",
461                  index, mBufferCount);
462         return -1;
463     }
464 
465     if (0 == mMemInfo[index].handle) {
466         LOGE("Buffer at %d not registered", index);
467         return -1;
468     }
469 
470     return mCurrentFrameNumbers[index];
471 }
472 
473 
474 /*===========================================================================
475  * FUNCTION   : getOldestFrameNumber
476  *
477  * DESCRIPTION: We use this to fetch the oldest frame number expected per FIFO
478  *
479  *
480  * PARAMETERS :
481  *
482  *
483  * RETURN     : int32_t frameNumber
484  *              negative failure
485  *==========================================================================*/
getOldestFrameNumber(uint32_t & bufIndex)486 int32_t QCamera3HeapMemory::getOldestFrameNumber(uint32_t &bufIndex)
487 {
488     Mutex::Autolock lock(mLock);
489 
490     int32_t oldest = INT_MAX;
491     bool empty = true;
492 
493     for (uint32_t index = 0;
494             index < mBufferCount; index++) {
495         if (mMemInfo[index].handle) {
496             if ((empty) || (!empty && oldest > mCurrentFrameNumbers[index]
497                 && mCurrentFrameNumbers[index] != -1)) {
498                 oldest = mCurrentFrameNumbers[index];
499                 bufIndex = index;
500             }
501             empty = false;
502         }
503     }
504     if (empty)
505         return -1;
506     else
507         return oldest;
508 }
509 
510 
511 /*===========================================================================
512  * FUNCTION   : getBufferIndex
513  *
514  * DESCRIPTION: We use this to fetch the buffer index for the request with
515  *              a particular frame number
516  *
517  *
518  * PARAMETERS :
519  *   @frameNumber  : frame number of the buffer
520  *
521  * RETURN     : int32_t buffer index
522  *              negative failure
523  *==========================================================================*/
getBufferIndex(uint32_t frameNumber)524 int32_t QCamera3HeapMemory::getBufferIndex(uint32_t frameNumber)
525 {
526     Mutex::Autolock lock(mLock);
527 
528     for (uint32_t index = 0;
529             index < mBufferCount; index++) {
530         if (mMemInfo[index].handle &&
531                 mCurrentFrameNumbers[index] == (int32_t)frameNumber)
532             return (int32_t)index;
533     }
534     return -1;
535 }
536 
537 /*===========================================================================
538  * FUNCTION   : getPtr
539  *
540  * DESCRIPTION: Return buffer pointer
541  *
542  * PARAMETERS :
543  *   @index   : index of the buffer
544  *
545  * RETURN     : buffer ptr
546  *==========================================================================*/
getPtr(uint32_t index)547 void *QCamera3HeapMemory::getPtr(uint32_t index)
548 {
549     return getPtrLocked(index);
550 }
551 
552 /*===========================================================================
553  * FUNCTION   : allocate
554  *
555  * DESCRIPTION: allocate requested number of buffers of certain size
556  *
557  * PARAMETERS :
558  *   @size    : lenght of the buffer to be allocated
559  *
560  * RETURN     : int32_t type of status
561  *              NO_ERROR  -- success
562  *              none-zero failure code
563  *==========================================================================*/
allocate(size_t size)564 int QCamera3HeapMemory::allocate(size_t size)
565 {
566     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
567     uint32_t i;
568     int rc = NO_ERROR;
569 
570     //Note that now we allow incremental allocation. In other words, we allow
571     //multiple alloc being called as long as the sum of count does not exceed
572     //mMaxCnt.
573     if (mBufferCount > 0) {
574         LOGE("There is already buffer allocated.");
575         return BAD_INDEX;
576     }
577 
578     for (i = 0; i < mMaxCnt; i ++) {
579         rc = allocOneBuffer(mMemInfo[i], heap_id_mask, size);
580         if (rc < 0) {
581             LOGE("AllocateIonMemory failed");
582             goto ALLOC_FAILED;
583         }
584 
585         void *vaddr = mmap(NULL,
586                     mMemInfo[i].size,
587                     PROT_READ | PROT_WRITE,
588                     MAP_SHARED,
589                     mMemInfo[i].fd, 0);
590         if (vaddr == MAP_FAILED) {
591             deallocOneBuffer(mMemInfo[i]);
592             LOGE("mmap failed for buffer %d", i);
593             goto ALLOC_FAILED;
594         } else
595             mPtr[i] = vaddr;
596     }
597     if (rc == 0)
598         mBufferCount = mMaxCnt;
599 
600     return OK;
601 
602 ALLOC_FAILED:
603     for (uint32_t j = 0; j < i; j++) {
604         munmap(mPtr[j], mMemInfo[j].size);
605         mPtr[j] = NULL;
606         deallocOneBuffer(mMemInfo[j]);
607     }
608     return NO_MEMORY;
609 }
610 
611 /*===========================================================================
612  * FUNCTION   : allocateOne
613  *
614  * DESCRIPTION: allocate one buffer
615  *
616  * PARAMETERS :
617  *   @size    : lenght of the buffer to be allocated
618  *
619  * RETURN     : int32_t type of status
620  *              NO_ERROR  -- success
621  *              none-zero failure code
622  *==========================================================================*/
allocateOne(size_t size)623 int QCamera3HeapMemory::allocateOne(size_t size)
624 {
625     unsigned int heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
626     int rc = NO_ERROR;
627 
628     //Note that now we allow incremental allocation. In other words, we allow
629     //multiple alloc being called as long as the sum of count does not exceed
630     //mMaxCnt.
631     if (mBufferCount + 1 > mMaxCnt) {
632         LOGE("Buffer count %d + 1 out of bound. Max is %d",
633                 mBufferCount, mMaxCnt);
634         return BAD_INDEX;
635     }
636 
637     rc = allocOneBuffer(mMemInfo[mBufferCount], heap_id_mask, size);
638     if (rc < 0) {
639         LOGE("AllocateIonMemory failed");
640         return NO_MEMORY;
641     }
642 
643     void *vaddr = mmap(NULL,
644                 mMemInfo[mBufferCount].size,
645                 PROT_READ | PROT_WRITE,
646                 MAP_SHARED,
647                 mMemInfo[mBufferCount].fd, 0);
648     if (vaddr == MAP_FAILED) {
649         deallocOneBuffer(mMemInfo[mBufferCount]);
650         LOGE("mmap failed for buffer");
651         return NO_MEMORY;
652     } else
653         mPtr[mBufferCount] = vaddr;
654 
655     if (rc == 0)
656         mBufferCount += 1;
657 
658     return mBufferCount-1;
659 }
660 
661 /*===========================================================================
662  * FUNCTION   : deallocate
663  *
664  * DESCRIPTION: deallocate buffers
665  *
666  * PARAMETERS : none
667  *
668  * RETURN     : none
669  *==========================================================================*/
deallocate()670 void QCamera3HeapMemory::deallocate()
671 {
672     for (uint32_t i = 0; i < mBufferCount; i++) {
673         munmap(mPtr[i], mMemInfo[i].size);
674         mPtr[i] = NULL;
675         deallocOneBuffer(mMemInfo[i]);
676         mCurrentFrameNumbers[i] = -1;
677     }
678     mBufferCount = 0;
679 }
680 
681 /*===========================================================================
682  * FUNCTION   : cacheOps
683  *
684  * DESCRIPTION: ion related memory cache operations
685  *
686  * PARAMETERS :
687  *   @index   : index of the buffer
688  *   @cmd     : cache ops command
689  *
690  * RETURN     : int32_t type of status
691  *              NO_ERROR  -- success
692  *              none-zero failure code
693  *==========================================================================*/
cacheOps(uint32_t index,unsigned int cmd)694 int QCamera3HeapMemory::cacheOps(uint32_t index, unsigned int cmd)
695 {
696     if (index >= mBufferCount)
697         return BAD_INDEX;
698     return cacheOpsInternal(index, cmd, mPtr[index]);
699 }
700 
701 /*===========================================================================
702  * FUNCTION   : getMatchBufIndex
703  *
704  * DESCRIPTION: query buffer index by object ptr
705  *
706  * PARAMETERS :
707  *   @object  : object ptr
708  *
709  * RETURN     : buffer index if match found,
710  *              -1 if failed
711  *==========================================================================*/
getMatchBufIndex(void *)712 int QCamera3HeapMemory::getMatchBufIndex(void * /*object*/)
713 {
714 
715 /*
716     TODO for HEAP memory type, would there be an equivalent requirement?
717 
718     int index = -1;
719     buffer_handle_t *key = (buffer_handle_t*) object;
720     if (!key) {
721         return BAD_VALUE;
722     }
723     for (int i = 0; i < mBufferCount; i++) {
724         if (mBufferHandle[i] == key) {
725             index = i;
726             break;
727         }
728     }
729     return index;
730 */
731     LOGE("FATAL: Not supposed to come here");
732     return -1;
733 }
734 
735 /*===========================================================================
736  * FUNCTION   : QCamera3GrallocMemory
737  *
738  * DESCRIPTION: constructor of QCamera3GrallocMemory
739  *              preview stream buffers are allocated from gralloc native_windoe
740  *
741  * PARAMETERS :
742  *   @startIdx : start index of array after which we can register buffers in.
743  *
744  * RETURN     : none
745  *==========================================================================*/
QCamera3GrallocMemory(uint32_t startIdx)746 QCamera3GrallocMemory::QCamera3GrallocMemory(uint32_t startIdx)
747         : QCamera3Memory(), mStartIdx(startIdx)
748 {
749     for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
750         mBufferHandle[i] = NULL;
751         mPrivateHandle[i] = NULL;
752     }
753 }
754 
755 /*===========================================================================
756  * FUNCTION   : ~QCamera3GrallocMemory
757  *
758  * DESCRIPTION: deconstructor of QCamera3GrallocMemory
759  *
760  * PARAMETERS : none
761  *
762  * RETURN     : none
763  *==========================================================================*/
~QCamera3GrallocMemory()764 QCamera3GrallocMemory::~QCamera3GrallocMemory()
765 {
766 }
767 
768 /*===========================================================================
769  * FUNCTION   : registerBuffer
770  *
771  * DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t
772  *
773  * PARAMETERS :
774  *   @buffers : buffer_handle_t pointer
775  *   @type :    cam_stream_type_t
776  *
777  * RETURN     : int32_t type of status
778  *              NO_ERROR  -- success
779  *              none-zero failure code
780  *==========================================================================*/
registerBuffer(buffer_handle_t * buffer,__unused cam_stream_type_t type)781 int QCamera3GrallocMemory::registerBuffer(buffer_handle_t *buffer,
782         __unused cam_stream_type_t type)
783 {
784     status_t ret = NO_ERROR;
785     struct ion_fd_data ion_info_fd;
786     void *vaddr = NULL;
787     int32_t colorSpace = ITU_R_601_FR;
788     int32_t idx = -1;
789 
790     LOGD("E");
791 
792     memset(&ion_info_fd, 0, sizeof(ion_info_fd));
793 
794     if (0 <= getMatchBufIndex((void *) buffer)) {
795         LOGL("Buffer already registered");
796         return ALREADY_EXISTS;
797     }
798 
799     Mutex::Autolock lock(mLock);
800     if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1 - mStartIdx)) {
801         LOGE("Number of buffers %d greater than what's supported %d",
802                  mBufferCount, MM_CAMERA_MAX_NUM_FRAMES - mStartIdx);
803         return BAD_INDEX;
804     }
805 
806     idx = getFreeIndexLocked();
807     if (0 > idx) {
808         LOGE("No available memory slots");
809         return BAD_INDEX;
810     }
811 
812     mBufferHandle[idx] = buffer;
813     mPrivateHandle[idx] = (struct private_handle_t *)(*mBufferHandle[idx]);
814 
815     setMetaData(mPrivateHandle[idx], UPDATE_COLOR_SPACE, &colorSpace);
816 
817     mMemInfo[idx].main_ion_fd = open("/dev/ion", O_RDONLY);
818     if (mMemInfo[idx].main_ion_fd < 0) {
819         LOGE("failed: could not open ion device");
820         ret = NO_MEMORY;
821         goto end;
822     } else {
823         ion_info_fd.fd = mPrivateHandle[idx]->fd;
824         if (ioctl(mMemInfo[idx].main_ion_fd,
825                   ION_IOC_IMPORT, &ion_info_fd) < 0) {
826             LOGE("ION import failed\n");
827             close(mMemInfo[idx].main_ion_fd);
828             ret = NO_MEMORY;
829             goto end;
830         }
831     }
832     LOGD("idx = %d, fd = %d, size = %d, offset = %d",
833              idx, mPrivateHandle[idx]->fd,
834             mPrivateHandle[idx]->size,
835             mPrivateHandle[idx]->offset);
836     mMemInfo[idx].fd = mPrivateHandle[idx]->fd;
837     mMemInfo[idx].size =
838             ( /* FIXME: Should update ION interface */ size_t)
839             mPrivateHandle[idx]->size;
840     mMemInfo[idx].handle = ion_info_fd.handle;
841 
842     vaddr = mmap(NULL,
843             mMemInfo[idx].size,
844             PROT_READ | PROT_WRITE,
845             MAP_SHARED,
846             mMemInfo[idx].fd, 0);
847     if (vaddr == MAP_FAILED) {
848         mMemInfo[idx].handle = 0;
849         ret = NO_MEMORY;
850     } else {
851         mPtr[idx] = vaddr;
852         mBufferCount++;
853     }
854 
855 end:
856     LOGD("X ");
857     return ret;
858 }
859 /*===========================================================================
860  * FUNCTION   : unregisterBufferLocked
861  *
862  * DESCRIPTION: Unregister buffer. Please note that this method has to be
863  *              called with 'mLock' acquired.
864  *
865  * PARAMETERS :
866  *   @idx     : unregister buffer at index 'idx'
867  *
868  * RETURN     : int32_t type of status
869  *              NO_ERROR  -- success
870  *              none-zero failure code
871  *==========================================================================*/
unregisterBufferLocked(size_t idx)872 int32_t QCamera3GrallocMemory::unregisterBufferLocked(size_t idx)
873 {
874     munmap(mPtr[idx], mMemInfo[idx].size);
875     mPtr[idx] = NULL;
876 
877     struct ion_handle_data ion_handle;
878     memset(&ion_handle, 0, sizeof(ion_handle));
879     ion_handle.handle = mMemInfo[idx].handle;
880     if (ioctl(mMemInfo[idx].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
881         LOGE("ion free failed");
882     }
883     close(mMemInfo[idx].main_ion_fd);
884     memset(&mMemInfo[idx], 0, sizeof(struct QCamera3MemInfo));
885     mMemInfo[idx].main_ion_fd = -1;
886     mBufferHandle[idx] = NULL;
887     mPrivateHandle[idx] = NULL;
888     mCurrentFrameNumbers[idx] = -1;
889     mBufferCount--;
890 
891     return NO_ERROR;
892 }
893 
894 /*===========================================================================
895  * FUNCTION   : unregisterBuffer
896  *
897  * DESCRIPTION: unregister buffer
898  *
899  * PARAMETERS :
900  *   @idx     : unregister buffer at index 'idx'
901  *
902  * RETURN     : int32_t type of status
903  *              NO_ERROR  -- success
904  *              none-zero failure code
905  *==========================================================================*/
unregisterBuffer(size_t idx)906 int32_t QCamera3GrallocMemory::unregisterBuffer(size_t idx)
907 {
908     int32_t rc = NO_ERROR;
909     Mutex::Autolock lock(mLock);
910 
911     LOGD("E ", __FUNCTION__);
912 
913     if (MM_CAMERA_MAX_NUM_FRAMES <= idx) {
914         LOGE("Buffer index %d greater than what is supported %d",
915                  idx, MM_CAMERA_MAX_NUM_FRAMES);
916         return BAD_VALUE;
917     }
918     if (idx < mStartIdx) {
919         LOGE("buffer index %d less than starting index %d",
920                  idx, mStartIdx);
921         return BAD_INDEX;
922     }
923 
924     if (0 == mMemInfo[idx].handle) {
925         LOGE("Trying to unregister buffer at %d which still not registered",
926                  idx);
927         return BAD_VALUE;
928     }
929 
930     rc = unregisterBufferLocked(idx);
931 
932     LOGD("X ",__FUNCTION__);
933 
934     return rc;
935 }
936 
937 /*===========================================================================
938  * FUNCTION   : unregisterBuffers
939  *
940  * DESCRIPTION: unregister buffers
941  *
942  * PARAMETERS : none
943  *
944  * RETURN     : none
945  *==========================================================================*/
unregisterBuffers()946 void QCamera3GrallocMemory::unregisterBuffers()
947 {
948     int err = NO_ERROR;
949     Mutex::Autolock lock(mLock);
950 
951     LOGD("E ", __FUNCTION__);
952 
953     for (uint32_t cnt = mStartIdx; cnt < MM_CAMERA_MAX_NUM_FRAMES; cnt++) {
954         if (0 == mMemInfo[cnt].handle) {
955             continue;
956         }
957         err = unregisterBufferLocked(cnt);
958         if (NO_ERROR != err) {
959             LOGE("Error unregistering buffer %d error %d",
960                      cnt, err);
961         }
962     }
963     mBufferCount = 0;
964     LOGD("X ",__FUNCTION__);
965 }
966 
967 /*===========================================================================
968  * FUNCTION   : markFrameNumber
969  *
970  * DESCRIPTION: We use this function from the request call path to mark the
971  *              buffers with the frame number they are intended for this info
972  *              is used later when giving out callback & it is duty of PP to
973  *              ensure that data for that particular frameNumber/Request is
974  *              written to this buffer.
975  * PARAMETERS :
976  *   @index   : index of the buffer
977  *   @frame#  : Frame number from the framework
978  *
979  * RETURN     : int32_t type of status
980  *              NO_ERROR  -- success
981  *              none-zero failure code
982  *==========================================================================*/
markFrameNumber(uint32_t index,uint32_t frameNumber)983 int32_t QCamera3GrallocMemory::markFrameNumber(uint32_t index, uint32_t frameNumber)
984 {
985     Mutex::Autolock lock(mLock);
986 
987     if (index >= MM_CAMERA_MAX_NUM_FRAMES) {
988         LOGE("Index out of bounds");
989         return BAD_INDEX;
990     }
991     if (index < mStartIdx) {
992         LOGE("buffer index %d less than starting index %d",
993                  index, mStartIdx);
994         return BAD_INDEX;
995     }
996 
997     if (0 == mMemInfo[index].handle) {
998         LOGE("Buffer at %d not registered", index);
999         return BAD_INDEX;
1000     }
1001 
1002     mCurrentFrameNumbers[index] = (int32_t)frameNumber;
1003 
1004     return NO_ERROR;
1005 }
1006 
1007 /*===========================================================================
1008  * FUNCTION   : getFrameNumber
1009  *
1010  * DESCRIPTION: We use this to fetch the frameNumber for the request with which
1011  *              this buffer was given to HAL
1012  *
1013  *
1014  * PARAMETERS :
1015  *   @index   : index of the buffer
1016  *
1017  * RETURN     : int32_t frameNumber
1018  *              positive/zero  -- success
1019  *              negative failure
1020  *==========================================================================*/
getFrameNumber(uint32_t index)1021 int32_t QCamera3GrallocMemory::getFrameNumber(uint32_t index)
1022 {
1023     Mutex::Autolock lock(mLock);
1024 
1025     if (index >= MM_CAMERA_MAX_NUM_FRAMES) {
1026         LOGE("Index out of bounds");
1027         return -1;
1028     }
1029     if (index < mStartIdx) {
1030         LOGE("buffer index %d less than starting index %d",
1031                  index, mStartIdx);
1032         return BAD_INDEX;
1033     }
1034 
1035     if (0 == mMemInfo[index].handle) {
1036         LOGE("Buffer at %d not registered", index);
1037         return -1;
1038     }
1039 
1040     return mCurrentFrameNumbers[index];
1041 }
1042 
1043 /*===========================================================================
1044  * FUNCTION   : getOldestFrameNumber
1045  *
1046  * DESCRIPTION: We use this to fetch the oldest frame number expected per FIFO
1047  *
1048  *
1049  * PARAMETERS :
1050  *
1051  *
1052  * RETURN     : int32_t frameNumber
1053  *              negative failure
1054  *==========================================================================*/
getOldestFrameNumber(uint32_t & bufIndex)1055 int32_t QCamera3GrallocMemory::getOldestFrameNumber(uint32_t &bufIndex)
1056 {
1057     int32_t oldest = INT_MAX;
1058     bool empty = true;
1059     for (uint32_t index = mStartIdx;
1060             index < MM_CAMERA_MAX_NUM_FRAMES; index++) {
1061         if (mMemInfo[index].handle) {
1062             if ((empty) ||
1063                 (!empty && oldest > mCurrentFrameNumbers[index]
1064                 && mCurrentFrameNumbers[index] != -1)) {
1065                 oldest = mCurrentFrameNumbers[index];
1066                 bufIndex = index;
1067             }
1068             empty = false;
1069         }
1070     }
1071     if (empty)
1072         return -1;
1073     else
1074         return oldest;
1075 }
1076 
1077 
1078 /*===========================================================================
1079  * FUNCTION   : getBufferIndex
1080  *
1081  * DESCRIPTION: We use this to fetch the buffer index for the request with
1082  *              a particular frame number
1083  *
1084  *
1085  * PARAMETERS :
1086  *   @frameNumber  : frame number of the buffer
1087  *
1088  * RETURN     : int32_t buffer index
1089  *              negative failure
1090  *==========================================================================*/
getBufferIndex(uint32_t frameNumber)1091 int32_t QCamera3GrallocMemory::getBufferIndex(uint32_t frameNumber)
1092 {
1093     for (uint32_t index = mStartIdx;
1094             index < MM_CAMERA_MAX_NUM_FRAMES; index++) {
1095         if (mMemInfo[index].handle &&
1096                 mCurrentFrameNumbers[index] == (int32_t)frameNumber)
1097             return (int32_t)index;
1098     }
1099     return -1;
1100 }
1101 
1102 /*===========================================================================
1103  * FUNCTION   : cacheOps
1104  *
1105  * DESCRIPTION: ion related memory cache operations
1106  *
1107  * PARAMETERS :
1108  *   @index   : index of the buffer
1109  *   @cmd     : cache ops command
1110  *
1111  * RETURN     : int32_t type of status
1112  *              NO_ERROR  -- success
1113  *              none-zero failure code
1114  *==========================================================================*/
cacheOps(uint32_t index,unsigned int cmd)1115 int QCamera3GrallocMemory::cacheOps(uint32_t index, unsigned int cmd)
1116 {
1117     if (index >= MM_CAMERA_MAX_NUM_FRAMES) {
1118         LOGE("Index out of bounds");
1119         return -1;
1120     }
1121     if (index < mStartIdx) {
1122         LOGE("buffer index %d less than starting index %d",
1123                  index, mStartIdx);
1124         return BAD_INDEX;
1125     }
1126 
1127     return cacheOpsInternal(index, cmd, mPtr[index]);
1128 }
1129 
1130 /*===========================================================================
1131  * FUNCTION   : getMatchBufIndex
1132  *
1133  * DESCRIPTION: query buffer index by object ptr
1134  *
1135  * PARAMETERS :
1136  *   @opaque  : opaque ptr
1137  *
1138  * RETURN     : buffer index if match found,
1139  *              -1 if failed
1140  *==========================================================================*/
getMatchBufIndex(void * object)1141 int QCamera3GrallocMemory::getMatchBufIndex(void *object)
1142 {
1143     Mutex::Autolock lock(mLock);
1144 
1145     int index = -1;
1146     buffer_handle_t *key = (buffer_handle_t*) object;
1147     if (!key) {
1148         return BAD_VALUE;
1149     }
1150     for (uint32_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
1151         if (mBufferHandle[i] == key) {
1152             index = (int)i;
1153             break;
1154         }
1155     }
1156 
1157     return index;
1158 }
1159 
1160 /*===========================================================================
1161  * FUNCTION   : getFreeIndexLocked
1162  *
1163  * DESCRIPTION: Find free index slot. Note 'mLock' needs to be acquired
1164  *              before calling this method.
1165  *
1166  * PARAMETERS : None
1167  *
1168  * RETURN     : free buffer index if found,
1169  *              -1 if failed
1170  *==========================================================================*/
getFreeIndexLocked()1171 int QCamera3GrallocMemory::getFreeIndexLocked()
1172 {
1173     int index = -1;
1174 
1175     if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1)) {
1176         LOGE("Number of buffers %d greater than what's supported %d",
1177              mBufferCount, MM_CAMERA_MAX_NUM_FRAMES);
1178         return index;
1179     }
1180 
1181     for (size_t i = mStartIdx; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
1182         if (0 == mMemInfo[i].handle) {
1183             index = i;
1184             break;
1185         }
1186     }
1187 
1188     return index;
1189 }
1190 
1191 /*===========================================================================
1192  * FUNCTION   : getPtrLocked
1193  *
1194  * DESCRIPTION: Return buffer pointer. Please note 'mLock' must be acquired
1195  *              before calling this method.
1196  *
1197  * PARAMETERS :
1198  *   @index   : index of the buffer
1199  *
1200  * RETURN     : buffer ptr
1201  *==========================================================================*/
getPtrLocked(uint32_t index)1202 void *QCamera3GrallocMemory::getPtrLocked(uint32_t index)
1203 {
1204     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
1205         LOGE("index %d out of bound [0, %d)",
1206                  index, MM_CAMERA_MAX_NUM_FRAMES);
1207         return NULL;
1208     }
1209     if (index < mStartIdx) {
1210         LOGE("buffer index %d less than starting index %d",
1211                  index, mStartIdx);
1212         return NULL;
1213     }
1214 
1215 
1216     if (0 == mMemInfo[index].handle) {
1217         LOGE("Buffer at %d not registered", index);
1218         return NULL;
1219     }
1220 
1221     return mPtr[index];
1222 }
1223 
1224 /*===========================================================================
1225  * FUNCTION   : getPtr
1226  *
1227  * DESCRIPTION: Return buffer pointer.
1228  *
1229  * PARAMETERS :
1230  *   @index   : index of the buffer
1231  *
1232  * RETURN     : buffer ptr
1233  *==========================================================================*/
getPtr(uint32_t index)1234 void *QCamera3GrallocMemory::getPtr(uint32_t index)
1235 {
1236     Mutex::Autolock lock(mLock);
1237     return getPtrLocked(index);
1238 }
1239 
1240 /*===========================================================================
1241  * FUNCTION   : getBufferHandle
1242  *
1243  * DESCRIPTION: return framework pointer
1244  *
1245  * PARAMETERS :
1246  *   @index   : index of the buffer
1247  *
1248  * RETURN     : buffer ptr if match found
1249                 NULL if failed
1250  *==========================================================================*/
getBufferHandle(uint32_t index)1251 void *QCamera3GrallocMemory::getBufferHandle(uint32_t index)
1252 {
1253     Mutex::Autolock lock(mLock);
1254 
1255     if (MM_CAMERA_MAX_NUM_FRAMES <= index) {
1256         LOGE("index %d out of bound [0, %d)",
1257                  index, MM_CAMERA_MAX_NUM_FRAMES);
1258         return NULL;
1259     }
1260     if (index < mStartIdx) {
1261         LOGE("buffer index %d less than starting index %d",
1262                  index, mStartIdx);
1263         return NULL;
1264     }
1265 
1266     if (0 == mMemInfo[index].handle) {
1267         LOGE("Buffer at %d not registered", index);
1268         return NULL;
1269     }
1270 
1271     return mBufferHandle[index];
1272 }
1273 }; //namespace qcamera
1274