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