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