1 /* Copyright (c) 2012-2013, 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 "QCamera3HWI_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 "QCamera3Mem.h"
39
40 extern "C" {
41 #include <mm_camera_interface.h>
42 }
43
44 using namespace android;
45
46 namespace qcamera {
47
48 // QCaemra2Memory base class
49
50 /*===========================================================================
51 * FUNCTION : QCamera3Memory
52 *
53 * DESCRIPTION: default constructor of QCamera3Memory
54 *
55 * PARAMETERS : none
56 *
57 * RETURN : None
58 *==========================================================================*/
QCamera3Memory()59 QCamera3Memory::QCamera3Memory()
60 {
61 mBufferCount = 0;
62 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i++) {
63 mMemInfo[i].fd = 0;
64 mMemInfo[i].main_ion_fd = 0;
65 mMemInfo[i].handle = NULL;
66 mMemInfo[i].size = 0;
67 }
68 }
69
70 /*===========================================================================
71 * FUNCTION : ~QCamera3Memory
72 *
73 * DESCRIPTION: deconstructor of QCamera3Memory
74 *
75 * PARAMETERS : none
76 *
77 * RETURN : None
78 *==========================================================================*/
~QCamera3Memory()79 QCamera3Memory::~QCamera3Memory()
80 {
81 }
82
83 /*===========================================================================
84 * FUNCTION : cacheOpsInternal
85 *
86 * DESCRIPTION: ion related memory cache operations
87 *
88 * PARAMETERS :
89 * @index : index of the buffer
90 * @cmd : cache ops command
91 * @vaddr : ptr to the virtual address
92 *
93 * RETURN : int32_t type of status
94 * NO_ERROR -- success
95 * none-zero failure code
96 *==========================================================================*/
cacheOpsInternal(int index,unsigned int cmd,void * vaddr)97 int QCamera3Memory::cacheOpsInternal(int index, unsigned int cmd, void *vaddr)
98 {
99 struct ion_flush_data cache_inv_data;
100 struct ion_custom_data custom_data;
101 int ret = OK;
102
103 if (index >= mBufferCount) {
104 ALOGE("%s: index %d out of bound [0, %d)", __func__, index, mBufferCount);
105 return BAD_INDEX;
106 }
107
108 memset(&cache_inv_data, 0, sizeof(cache_inv_data));
109 memset(&custom_data, 0, sizeof(custom_data));
110 cache_inv_data.vaddr = vaddr;
111 cache_inv_data.fd = mMemInfo[index].fd;
112 cache_inv_data.handle = mMemInfo[index].handle;
113 cache_inv_data.length = mMemInfo[index].size;
114 custom_data.cmd = cmd;
115 custom_data.arg = (unsigned long)&cache_inv_data;
116
117 ALOGV("%s: addr = %p, fd = %d, handle = %p length = %d, ION Fd = %d",
118 __func__, cache_inv_data.vaddr, cache_inv_data.fd,
119 cache_inv_data.handle, cache_inv_data.length,
120 mMemInfo[index].main_ion_fd);
121 ret = ioctl(mMemInfo[index].main_ion_fd, ION_IOC_CUSTOM, &custom_data);
122 if (ret < 0)
123 ALOGE("%s: Cache Invalidate failed: %s\n", __func__, strerror(errno));
124
125 return ret;
126 }
127
128 /*===========================================================================
129 * FUNCTION : getFd
130 *
131 * DESCRIPTION: return file descriptor of the indexed buffer
132 *
133 * PARAMETERS :
134 * @index : index of the buffer
135 *
136 * RETURN : file descriptor
137 *==========================================================================*/
getFd(int index) const138 int QCamera3Memory::getFd(int index) const
139 {
140 if (index >= mBufferCount)
141 return BAD_INDEX;
142
143 return mMemInfo[index].fd;
144 }
145
146 /*===========================================================================
147 * FUNCTION : getSize
148 *
149 * DESCRIPTION: return buffer size of the indexed buffer
150 *
151 * PARAMETERS :
152 * @index : index of the buffer
153 *
154 * RETURN : buffer size
155 *==========================================================================*/
getSize(int index) const156 int QCamera3Memory::getSize(int index) const
157 {
158 if (index >= mBufferCount)
159 return BAD_INDEX;
160
161 return (int)mMemInfo[index].size;
162 }
163
164 /*===========================================================================
165 * FUNCTION : getCnt
166 *
167 * DESCRIPTION: query number of buffers allocated
168 *
169 * PARAMETERS : none
170 *
171 * RETURN : number of buffers allocated
172 *==========================================================================*/
getCnt() const173 int QCamera3Memory::getCnt() const
174 {
175 return mBufferCount;
176 }
177
178 /*===========================================================================
179 * FUNCTION : getBufDef
180 *
181 * DESCRIPTION: query detailed buffer information
182 *
183 * PARAMETERS :
184 * @offset : [input] frame buffer offset
185 * @bufDef : [output] reference to struct to store buffer definition
186 * @index : [input] index of the buffer
187 *
188 * RETURN : int32_t type of status
189 * NO_ERROR -- success
190 * none-zero failure code
191 *==========================================================================*/
getBufDef(const cam_frame_len_offset_t & offset,mm_camera_buf_def_t & bufDef,int index) const192 int32_t QCamera3Memory::getBufDef(const cam_frame_len_offset_t &offset,
193 mm_camera_buf_def_t &bufDef, int index) const
194 {
195 if (!mBufferCount) {
196 ALOGE("Memory not allocated");
197 return NO_INIT;
198 }
199
200 bufDef.fd = mMemInfo[index].fd;
201 bufDef.frame_len = mMemInfo[index].size;
202 bufDef.mem_info = (void *)this;
203 bufDef.num_planes = offset.num_planes;
204 bufDef.buffer = getPtr(index);
205 bufDef.buf_idx = index;
206
207 /* Plane 0 needs to be set separately. Set other planes in a loop */
208 bufDef.planes[0].length = offset.mp[0].len;
209 bufDef.planes[0].m.userptr = mMemInfo[index].fd;
210 bufDef.planes[0].data_offset = offset.mp[0].offset;
211 bufDef.planes[0].reserved[0] = 0;
212 for (int i = 1; i < bufDef.num_planes; i++) {
213 bufDef.planes[i].length = offset.mp[i].len;
214 bufDef.planes[i].m.userptr = mMemInfo[i].fd;
215 bufDef.planes[i].data_offset = offset.mp[i].offset;
216 bufDef.planes[i].reserved[0] =
217 bufDef.planes[i-1].reserved[0] +
218 bufDef.planes[i-1].length;
219 }
220
221 return NO_ERROR;
222 }
223
224 /*===========================================================================
225 * FUNCTION : QCamera3HeapMemory
226 *
227 * DESCRIPTION: constructor of QCamera3HeapMemory for ion memory used internally in HAL
228 *
229 * PARAMETERS : none
230 *
231 * RETURN : none
232 *==========================================================================*/
QCamera3HeapMemory()233 QCamera3HeapMemory::QCamera3HeapMemory()
234 : QCamera3Memory()
235 {
236 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++)
237 mPtr[i] = NULL;
238 }
239
240 /*===========================================================================
241 * FUNCTION : ~QCamera3HeapMemory
242 *
243 * DESCRIPTION: deconstructor of QCamera3HeapMemory
244 *
245 * PARAMETERS : none
246 *
247 * RETURN : none
248 *==========================================================================*/
~QCamera3HeapMemory()249 QCamera3HeapMemory::~QCamera3HeapMemory()
250 {
251 }
252
253 /*===========================================================================
254 * FUNCTION : alloc
255 *
256 * DESCRIPTION: allocate requested number of buffers of certain size
257 *
258 * PARAMETERS :
259 * @count : number of buffers to be allocated
260 * @size : lenght of the buffer to be allocated
261 * @heap_id : heap id to indicate where the buffers will be allocated from
262 *
263 * RETURN : int32_t type of status
264 * NO_ERROR -- success
265 * none-zero failure code
266 *==========================================================================*/
alloc(int count,int size,int heap_id)267 int QCamera3HeapMemory::alloc(int count, int size, int heap_id)
268 {
269 int rc = OK;
270 if (count > MM_CAMERA_MAX_NUM_FRAMES) {
271 ALOGE("Buffer count %d out of bound. Max is %d", count, MM_CAMERA_MAX_NUM_FRAMES);
272 return BAD_INDEX;
273 }
274 if (mBufferCount) {
275 ALOGE("Allocating a already allocated heap memory");
276 return INVALID_OPERATION;
277 }
278
279 for (int i = 0; i < count; i ++) {
280 rc = allocOneBuffer(mMemInfo[i], heap_id, size);
281 if (rc < 0) {
282 ALOGE("AllocateIonMemory failed");
283 for (int j = i-1; j >= 0; j--)
284 deallocOneBuffer(mMemInfo[j]);
285 break;
286 }
287 }
288 return rc;
289 }
290
291 /*===========================================================================
292 * FUNCTION : dealloc
293 *
294 * DESCRIPTION: deallocate buffers
295 *
296 * PARAMETERS : none
297 *
298 * RETURN : none
299 *==========================================================================*/
dealloc()300 void QCamera3HeapMemory::dealloc()
301 {
302 for (int i = 0; i < mBufferCount; i++)
303 deallocOneBuffer(mMemInfo[i]);
304 }
305
306 /*===========================================================================
307 * FUNCTION : allocOneBuffer
308 *
309 * DESCRIPTION: impl of allocating one buffers of certain size
310 *
311 * PARAMETERS :
312 * @memInfo : [output] reference to struct to store additional memory allocation info
313 * @heap : [input] heap id to indicate where the buffers will be allocated from
314 * @size : [input] lenght of the buffer to be allocated
315 *
316 * RETURN : int32_t type of status
317 * NO_ERROR -- success
318 * none-zero failure code
319 *==========================================================================*/
allocOneBuffer(QCamera3MemInfo & memInfo,int heap_id,int size)320 int QCamera3HeapMemory::allocOneBuffer(QCamera3MemInfo &memInfo, int heap_id, int size)
321 {
322 int rc = OK;
323 struct ion_handle_data handle_data;
324 struct ion_allocation_data alloc;
325 struct ion_fd_data ion_info_fd;
326 int main_ion_fd = 0;
327
328 main_ion_fd = open("/dev/ion", O_RDONLY);
329 if (main_ion_fd < 0) {
330 ALOGE("Ion dev open failed: %s\n", strerror(errno));
331 goto ION_OPEN_FAILED;
332 }
333
334 memset(&alloc, 0, sizeof(alloc));
335 alloc.len = size;
336 /* to make it page size aligned */
337 alloc.len = (alloc.len + 4095) & (~4095);
338 alloc.align = 4096;
339 alloc.flags = ION_FLAG_CACHED;
340 alloc.heap_id_mask = heap_id;
341 rc = ioctl(main_ion_fd, ION_IOC_ALLOC, &alloc);
342 if (rc < 0) {
343 ALOGE("ION allocation for len %d failed: %s\n", alloc.len,
344 strerror(errno));
345 goto ION_ALLOC_FAILED;
346 }
347
348 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
349 ion_info_fd.handle = alloc.handle;
350 rc = ioctl(main_ion_fd, ION_IOC_SHARE, &ion_info_fd);
351 if (rc < 0) {
352 ALOGE("ION map failed %s\n", strerror(errno));
353 goto ION_MAP_FAILED;
354 }
355
356 memInfo.main_ion_fd = main_ion_fd;
357 memInfo.fd = ion_info_fd.fd;
358 memInfo.handle = ion_info_fd.handle;
359 memInfo.size = alloc.len;
360 return OK;
361
362 ION_MAP_FAILED:
363 memset(&handle_data, 0, sizeof(handle_data));
364 handle_data.handle = ion_info_fd.handle;
365 ioctl(main_ion_fd, ION_IOC_FREE, &handle_data);
366 ION_ALLOC_FAILED:
367 close(main_ion_fd);
368 ION_OPEN_FAILED:
369 return NO_MEMORY;
370 }
371
372 /*===========================================================================
373 * FUNCTION : deallocOneBuffer
374 *
375 * DESCRIPTION: impl of deallocating one buffers
376 *
377 * PARAMETERS :
378 * @memInfo : reference to struct that stores additional memory allocation info
379 *
380 * RETURN : none
381 *==========================================================================*/
deallocOneBuffer(QCamera3MemInfo & memInfo)382 void QCamera3HeapMemory::deallocOneBuffer(QCamera3MemInfo &memInfo)
383 {
384 struct ion_handle_data handle_data;
385
386 if (memInfo.fd > 0) {
387 close(memInfo.fd);
388 memInfo.fd = 0;
389 }
390
391 if (memInfo.main_ion_fd > 0) {
392 memset(&handle_data, 0, sizeof(handle_data));
393 handle_data.handle = memInfo.handle;
394 ioctl(memInfo.main_ion_fd, ION_IOC_FREE, &handle_data);
395 close(memInfo.main_ion_fd);
396 memInfo.main_ion_fd = 0;
397 }
398 memInfo.handle = NULL;
399 memInfo.size = 0;
400 }
401
402 /*===========================================================================
403 * FUNCTION : getPtr
404 *
405 * DESCRIPTION: return buffer pointer
406 *
407 * PARAMETERS :
408 * @index : index of the buffer
409 *
410 * RETURN : buffer ptr
411 *==========================================================================*/
getPtr(int index) const412 void *QCamera3HeapMemory::getPtr(int index) const
413 {
414 if (index >= mBufferCount) {
415 ALOGE("index out of bound");
416 return (void *)BAD_INDEX;
417 }
418 return mPtr[index];
419 }
420
421 /*===========================================================================
422 * FUNCTION : allocate
423 *
424 * DESCRIPTION: allocate requested number of buffers of certain size
425 *
426 * PARAMETERS :
427 * @count : number of buffers to be allocated
428 * @size : lenght of the buffer to be allocated
429 * @queueAll: whether to queue all allocated buffers at the beginning
430 *
431 * RETURN : int32_t type of status
432 * NO_ERROR -- success
433 * none-zero failure code
434 *==========================================================================*/
allocate(int count,int size,bool queueAll)435 int QCamera3HeapMemory::allocate(int count, int size, bool queueAll)
436 {
437 int heap_mask = 0x1 << ION_IOMMU_HEAP_ID;
438 int rc = alloc(count, size, heap_mask);
439 if (rc < 0)
440 return rc;
441
442 for (int i = 0; i < count; i ++) {
443 void *vaddr = mmap(NULL,
444 mMemInfo[i].size,
445 PROT_READ | PROT_WRITE,
446 MAP_SHARED,
447 mMemInfo[i].fd, 0);
448 if (vaddr == MAP_FAILED) {
449 for (int j = i-1; j >= 0; j --) {
450 munmap(mPtr[i], mMemInfo[i].size);
451 rc = NO_MEMORY;
452 break;
453 }
454 } else
455 mPtr[i] = vaddr;
456 }
457 if (rc == 0)
458 mBufferCount = count;
459
460 mQueueAll = queueAll;
461 return OK;
462 }
463
464 /*===========================================================================
465 * FUNCTION : deallocate
466 *
467 * DESCRIPTION: deallocate buffers
468 *
469 * PARAMETERS : none
470 *
471 * RETURN : none
472 *==========================================================================*/
deallocate()473 void QCamera3HeapMemory::deallocate()
474 {
475 for (int i = 0; i < mBufferCount; i++) {
476 munmap(mPtr[i], mMemInfo[i].size);
477 mPtr[i] = NULL;
478 }
479 dealloc();
480 mBufferCount = 0;
481 }
482
483 /*===========================================================================
484 * FUNCTION : cacheOps
485 *
486 * DESCRIPTION: ion related memory cache operations
487 *
488 * PARAMETERS :
489 * @index : index of the buffer
490 * @cmd : cache ops command
491 *
492 * RETURN : int32_t type of status
493 * NO_ERROR -- success
494 * none-zero failure code
495 *==========================================================================*/
cacheOps(int index,unsigned int cmd)496 int QCamera3HeapMemory::cacheOps(int index, unsigned int cmd)
497 {
498 if (index >= mBufferCount)
499 return BAD_INDEX;
500 return cacheOpsInternal(index, cmd, mPtr[index]);
501 }
502
503 /*===========================================================================
504 * FUNCTION : getRegFlags
505 *
506 * DESCRIPTION: query initial reg flags
507 *
508 * PARAMETERS :
509 * @regFlags: initial reg flags of the allocated buffers
510 *
511 * RETURN : int32_t type of status
512 * NO_ERROR -- success
513 * none-zero failure code
514 *==========================================================================*/
getRegFlags(uint8_t * regFlags) const515 int QCamera3HeapMemory::getRegFlags(uint8_t * regFlags) const
516 {
517 int i;
518 for (i = 0; i < mBufferCount; i ++)
519 regFlags[i] = (mQueueAll ? 1 : 0);
520 return NO_ERROR;
521 }
522
523 /*===========================================================================
524 * FUNCTION : getMatchBufIndex
525 *
526 * DESCRIPTION: query buffer index by object ptr
527 *
528 * PARAMETERS :
529 * @object : object ptr
530 *
531 * RETURN : buffer index if match found,
532 * -1 if failed
533 *==========================================================================*/
getMatchBufIndex(void *)534 int QCamera3HeapMemory::getMatchBufIndex(void * /*object*/)
535 {
536
537 /*
538 TODO for HEAP memory type, would there be an equivalent requirement?
539
540 int index = -1;
541 buffer_handle_t *key = (buffer_handle_t*) object;
542 if (!key) {
543 return BAD_VALUE;
544 }
545 for (int i = 0; i < mBufferCount; i++) {
546 if (mBufferHandle[i] == key) {
547 index = i;
548 break;
549 }
550 }
551 return index;
552 */
553 ALOGE("%s: FATAL: Not supposed to come here", __func__);
554 return -1;
555 }
556
557 /*===========================================================================
558 * FUNCTION : QCamera3GrallocMemory
559 *
560 * DESCRIPTION: constructor of QCamera3GrallocMemory
561 * preview stream buffers are allocated from gralloc native_windoe
562 *
563 * PARAMETERS :
564 * @getMemory : camera memory request ops table
565 *
566 * RETURN : none
567 *==========================================================================*/
QCamera3GrallocMemory()568 QCamera3GrallocMemory::QCamera3GrallocMemory()
569 : QCamera3Memory()
570 {
571 for (int i = 0; i < MM_CAMERA_MAX_NUM_FRAMES; i ++) {
572 mBufferHandle[i] = NULL;
573 mPrivateHandle[i] = NULL;
574 mCurrentFrameNumbers[i] = -1;
575 }
576 }
577
578 /*===========================================================================
579 * FUNCTION : ~QCamera3GrallocMemory
580 *
581 * DESCRIPTION: deconstructor of QCamera3GrallocMemory
582 *
583 * PARAMETERS : none
584 *
585 * RETURN : none
586 *==========================================================================*/
~QCamera3GrallocMemory()587 QCamera3GrallocMemory::~QCamera3GrallocMemory()
588 {
589 }
590
591 /*===========================================================================
592 * FUNCTION : registerBuffer
593 *
594 * DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t
595 *
596 * PARAMETERS :
597 * @buffers : buffer_handle_t pointer
598 *
599 * RETURN : int32_t type of status
600 * NO_ERROR -- success
601 * none-zero failure code
602 *==========================================================================*/
registerBuffer(buffer_handle_t * buffer)603 int QCamera3GrallocMemory::registerBuffer(buffer_handle_t *buffer)
604 {
605 status_t ret = NO_ERROR;
606 struct ion_fd_data ion_info_fd;
607 void *vaddr = NULL;
608 ALOGV(" %s : E ", __FUNCTION__);
609
610 memset(&ion_info_fd, 0, sizeof(ion_info_fd));
611
612 if (mBufferCount >= (MM_CAMERA_MAX_NUM_FRAMES - 1)) {
613 ALOGE("%s: Number of buffers %d greater than what's supported %d",
614 __func__, mBufferCount, MM_CAMERA_MAX_NUM_FRAMES);
615 return -EINVAL;
616 }
617
618 if (0 <= getMatchBufIndex((void *) buffer)) {
619 ALOGV("%s: Buffer already registered", __func__);
620 return ALREADY_EXISTS;
621 }
622
623 mBufferHandle[mBufferCount] = buffer;
624 mPrivateHandle[mBufferCount] =
625 (struct private_handle_t *)(*mBufferHandle[mBufferCount]);
626 mMemInfo[mBufferCount].main_ion_fd = open("/dev/ion", O_RDONLY);
627 if (mMemInfo[mBufferCount].main_ion_fd < 0) {
628 ALOGE("%s: failed: could not open ion device", __func__);
629 ret = NO_MEMORY;
630 goto end;
631 } else {
632 ion_info_fd.fd = mPrivateHandle[mBufferCount]->fd;
633 if (ioctl(mMemInfo[mBufferCount].main_ion_fd,
634 ION_IOC_IMPORT, &ion_info_fd) < 0) {
635 ALOGE("%s: ION import failed\n", __func__);
636 close(mMemInfo[mBufferCount].main_ion_fd);
637 ret = NO_MEMORY;
638 goto end;
639 }
640 }
641 ALOGV("%s: idx = %d, fd = %d, size = %d, offset = %d",
642 __func__, mBufferCount, mPrivateHandle[mBufferCount]->fd,
643 mPrivateHandle[mBufferCount]->size,
644 mPrivateHandle[mBufferCount]->offset);
645 mMemInfo[mBufferCount].fd =
646 mPrivateHandle[mBufferCount]->fd;
647 mMemInfo[mBufferCount].size =
648 mPrivateHandle[mBufferCount]->size;
649 mMemInfo[mBufferCount].handle = ion_info_fd.handle;
650
651 vaddr = mmap(NULL,
652 mMemInfo[mBufferCount].size,
653 PROT_READ | PROT_WRITE,
654 MAP_SHARED,
655 mMemInfo[mBufferCount].fd, 0);
656 if (vaddr == MAP_FAILED) {
657 ret = NO_MEMORY;
658 } else {
659 mPtr[mBufferCount] = vaddr;
660 mBufferCount++;
661 }
662
663 end:
664 ALOGV(" %s : X ",__func__);
665 return ret;
666 }
667
668 /*===========================================================================
669 * FUNCTION : unregisterBuffers
670 *
671 * DESCRIPTION: unregister buffers
672 *
673 * PARAMETERS : none
674 *
675 * RETURN : none
676 *==========================================================================*/
unregisterBuffers()677 void QCamera3GrallocMemory::unregisterBuffers()
678 {
679 ALOGV("%s: E ", __FUNCTION__);
680
681 for (int cnt = 0; cnt < mBufferCount; cnt++) {
682 munmap(mPtr[cnt], mMemInfo[cnt].size);
683 mPtr[cnt] = NULL;
684
685 struct ion_handle_data ion_handle;
686 memset(&ion_handle, 0, sizeof(ion_handle));
687 ion_handle.handle = mMemInfo[cnt].handle;
688 if (ioctl(mMemInfo[cnt].main_ion_fd, ION_IOC_FREE, &ion_handle) < 0) {
689 ALOGE("ion free failed");
690 }
691 close(mMemInfo[cnt].main_ion_fd);
692 ALOGV("put buffer %d successfully", cnt);
693 }
694 mBufferCount = 0;
695 ALOGV(" %s : X ",__FUNCTION__);
696 }
697
698 /*===========================================================================
699 * FUNCTION : markFrameNumber
700 *
701 * DESCRIPTION: We use this function from the request call path to mark the
702 * buffers with the frame number they are intended for this info
703 * is used later when giving out callback & it is duty of PP to
704 * ensure that data for that particular frameNumber/Request is
705 * written to this buffer.
706 * PARAMETERS :
707 * @index : index of the buffer
708 * @frame# : Frame number from the framework
709 *
710 * RETURN : int32_t type of status
711 * NO_ERROR -- success
712 * none-zero failure code
713 *==========================================================================*/
markFrameNumber(int index,uint32_t frameNumber)714 int32_t QCamera3GrallocMemory::markFrameNumber(int index, uint32_t frameNumber)
715 {
716 if(index >= mBufferCount || index >= MM_CAMERA_MAX_NUM_FRAMES) {
717 ALOGE("%s: Index out of bounds",__func__);
718 return BAD_INDEX;
719 }
720 mCurrentFrameNumbers[index] = frameNumber;
721 return NO_ERROR;
722 }
723
724 /*===========================================================================
725 * FUNCTION : getFrameNumber
726 *
727 * DESCRIPTION: We use this to fetch the frameNumber for the request with which
728 * this buffer was given to HAL
729 *
730 *
731 * PARAMETERS :
732 * @index : index of the buffer
733 *
734 * RETURN : int32_t frameNumber
735 * postive/zero -- success
736 * negetive failure
737 *==========================================================================*/
getFrameNumber(int index)738 int32_t QCamera3GrallocMemory::getFrameNumber(int index)
739 {
740 if(index >= mBufferCount || index >= MM_CAMERA_MAX_NUM_FRAMES) {
741 ALOGE("%s: Index out of bounds",__func__);
742 return -1;
743 }
744
745 return mCurrentFrameNumbers[index];
746 }
747
748 /*===========================================================================
749 * FUNCTION : cacheOps
750 *
751 * DESCRIPTION: ion related memory cache operations
752 *
753 * PARAMETERS :
754 * @index : index of the buffer
755 * @cmd : cache ops command
756 *
757 * RETURN : int32_t type of status
758 * NO_ERROR -- success
759 * none-zero failure code
760 *==========================================================================*/
cacheOps(int index,unsigned int cmd)761 int QCamera3GrallocMemory::cacheOps(int index, unsigned int cmd)
762 {
763 if (index >= mBufferCount)
764 return BAD_INDEX;
765 return cacheOpsInternal(index, cmd, mPtr[index]);
766 }
767
768 /*===========================================================================
769 * FUNCTION : getRegFlags
770 *
771 * DESCRIPTION: query initial reg flags
772 *
773 * PARAMETERS :
774 * @regFlags: initial reg flags of the allocated buffers
775 *
776 * RETURN : int32_t type of status
777 * NO_ERROR -- success
778 * none-zero failure code
779 *==========================================================================*/
getRegFlags(uint8_t * regFlags) const780 int QCamera3GrallocMemory::getRegFlags(uint8_t *regFlags) const
781 {
782 int i;
783 for (i = 0; i < mBufferCount; i ++)
784 regFlags[i] = 0;
785 return NO_ERROR;
786 }
787
788 /*===========================================================================
789 * FUNCTION : getMatchBufIndex
790 *
791 * DESCRIPTION: query buffer index by object ptr
792 *
793 * PARAMETERS :
794 * @opaque : opaque ptr
795 *
796 * RETURN : buffer index if match found,
797 * -1 if failed
798 *==========================================================================*/
getMatchBufIndex(void * object)799 int QCamera3GrallocMemory::getMatchBufIndex(void *object)
800 {
801 int index = -1;
802 buffer_handle_t *key = (buffer_handle_t*) object;
803 if (!key) {
804 return BAD_VALUE;
805 }
806 for (int i = 0; i < mBufferCount; i++) {
807 if (mBufferHandle[i] == key) {
808 index = i;
809 break;
810 }
811 }
812 return index;
813 }
814
815 /*===========================================================================
816 * FUNCTION : getPtr
817 *
818 * DESCRIPTION: return buffer pointer
819 *
820 * PARAMETERS :
821 * @index : index of the buffer
822 *
823 * RETURN : buffer ptr
824 *==========================================================================*/
getPtr(int index) const825 void *QCamera3GrallocMemory::getPtr(int index) const
826 {
827 if (index >= mBufferCount) {
828 ALOGE("index out of bound");
829 return (void *)BAD_INDEX;
830 }
831 return mPtr[index];
832 }
833
834 /*===========================================================================
835 * FUNCTION : getBufferHandle
836 *
837 * DESCRIPTION: return framework pointer
838 *
839 * PARAMETERS :
840 * @index : index of the buffer
841 *
842 * RETURN : buffer ptr if match found
843 NULL if failed
844 *==========================================================================*/
getBufferHandle(int index)845 void *QCamera3GrallocMemory::getBufferHandle(int index)
846 {
847 if (index >= mBufferCount) {
848 ALOGE("index out of bound");
849 return NULL;
850 }
851 return mBufferHandle[index];
852 }
853
854 }; //namespace qcamera
855