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