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