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