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 "QCamera3StreamMem"
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
42extern "C" {
43#include <mm_camera_interface.h>
44}
45
46using namespace android;
47
48namespace qcamera {
49
50/*===========================================================================
51 * FUNCTION   : QCamera3StreamMem
52 *
53 * DESCRIPTION: default constructor of QCamera3StreamMem
54 *
55 * PARAMETERS : none
56 *
57 * RETURN     : None
58 *==========================================================================*/
59QCamera3StreamMem::QCamera3StreamMem(uint32_t maxHeapBuffer, bool queueHeapBuffers) :
60        mHeapMem(maxHeapBuffer),
61        mGrallocMem(maxHeapBuffer),
62        mMaxHeapBuffers(maxHeapBuffer),
63        mQueueHeapBuffers(queueHeapBuffers)
64{
65}
66
67/*===========================================================================
68 * FUNCTION   : QCamera3StreamMem
69 *
70 * DESCRIPTION: destructor of QCamera3StreamMem
71 *
72 * PARAMETERS : none
73 *
74 * RETURN     : None
75 *==========================================================================*/
76QCamera3StreamMem::~QCamera3StreamMem()
77{
78    clear();
79}
80
81/*===========================================================================
82 * FUNCTION   : getCnt
83 *
84 * DESCRIPTION: query number of buffers allocated/registered
85 *
86 * PARAMETERS : none
87 *
88 * RETURN     : number of buffers allocated
89 *==========================================================================*/
90uint32_t QCamera3StreamMem::getCnt()
91{
92    Mutex::Autolock lock(mLock);
93
94    return (mHeapMem.getCnt() + mGrallocMem.getCnt());
95}
96
97/*===========================================================================
98 * FUNCTION   : getRegFlags
99 *
100 * DESCRIPTION: query initial reg flags
101 *
102 * PARAMETERS :
103 *   @regFlags: initial reg flags of the allocated/registered buffers
104 *
105 * RETURN     : int32_t type of status
106 *              NO_ERROR  -- success
107 *              none-zero failure code
108 *==========================================================================*/
109int QCamera3StreamMem::getRegFlags(uint8_t * regFlags)
110{
111    // Assume that all buffers allocated can be queued.
112    for (uint32_t i = 0; i < mHeapMem.getCnt(); i ++)
113        regFlags[i] = (mQueueHeapBuffers ? 1 : 0);
114    return NO_ERROR;
115}
116
117/*===========================================================================
118 * FUNCTION   : getFd
119 *
120 * DESCRIPTION: return file descriptor of the indexed buffer
121 *
122 * PARAMETERS :
123 *   @index   : index of the buffer
124 *
125 * RETURN     : file descriptor
126 *==========================================================================*/
127int QCamera3StreamMem::getFd(uint32_t index)
128{
129    Mutex::Autolock lock(mLock);
130
131    if (index < mMaxHeapBuffers)
132        return mHeapMem.getFd(index);
133    else
134        return mGrallocMem.getFd(index);
135}
136
137/*===========================================================================
138 * FUNCTION   : getSize
139 *
140 * DESCRIPTION: return buffer size of the indexed buffer
141 *
142 * PARAMETERS :
143 *   @index   : index of the buffer
144 *
145 * RETURN     : buffer size
146 *==========================================================================*/
147ssize_t QCamera3StreamMem::getSize(uint32_t index)
148{
149    Mutex::Autolock lock(mLock);
150
151    if (index < mMaxHeapBuffers)
152        return mHeapMem.getSize(index);
153    else
154        return mGrallocMem.getSize(index);
155}
156
157/*===========================================================================
158 * FUNCTION   : invalidateCache
159 *
160 * DESCRIPTION: invalidate the cache of the indexed buffer
161 *
162 * PARAMETERS :
163 *   @index   : index of the buffer
164 *
165 * RETURN     : int32_t type of status
166 *              NO_ERROR  -- success
167 *              none-zero failure code
168 *==========================================================================*/
169int QCamera3StreamMem::invalidateCache(uint32_t index)
170{
171    Mutex::Autolock lock(mLock);
172
173    if (index < mMaxHeapBuffers)
174        return mHeapMem.invalidateCache(index);
175    else
176        return mGrallocMem.invalidateCache(index);
177}
178
179/*===========================================================================
180 * FUNCTION   : cleanInvalidateCache
181 *
182 * DESCRIPTION: clean and invalidate the cache of the indexed buffer
183 *
184 * PARAMETERS :
185 *   @index   : index of the buffer
186 *
187 * RETURN     : int32_t type of status
188 *              NO_ERROR  -- success
189 *              none-zero failure code
190 *==========================================================================*/
191int QCamera3StreamMem::cleanInvalidateCache(uint32_t index)
192{
193    Mutex::Autolock lock(mLock);
194
195    if (index < mMaxHeapBuffers)
196        return mHeapMem.cleanInvalidateCache(index);
197    else
198        return mGrallocMem.cleanInvalidateCache(index);
199}
200
201/*===========================================================================
202 * FUNCTION   : getBufDef
203 *
204 * DESCRIPTION: query detailed buffer information
205 *
206 * PARAMETERS :
207 *   @offset  : [input] frame buffer offset
208 *   @bufDef  : [output] reference to struct to store buffer definition
209 *   @index   : [input] index of the buffer
210 *
211 * RETURN     : int32_t type of status
212 *              NO_ERROR  -- success
213 *              none-zero failure code
214 *==========================================================================*/
215int32_t QCamera3StreamMem::getBufDef(const cam_frame_len_offset_t &offset,
216        mm_camera_buf_def_t &bufDef, uint32_t index)
217{
218    int32_t ret = NO_ERROR;
219
220    if (index < mMaxHeapBuffers)
221        ret = mHeapMem.getBufDef(offset, bufDef, index);
222    else
223        ret = mGrallocMem.getBufDef(offset, bufDef, index);
224
225    bufDef.mem_info = (void *)this;
226
227    return ret;
228}
229
230/*===========================================================================
231 * FUNCTION   : getPtr
232 *
233 * DESCRIPTION: return virtual address of the indexed buffer
234 *
235 * PARAMETERS :
236 *   @index   : index of the buffer
237 *
238 * RETURN     : virtual address
239 *==========================================================================*/
240void* QCamera3StreamMem::getPtr(uint32_t index)
241{
242    Mutex::Autolock lock(mLock);
243
244    if (index < mMaxHeapBuffers)
245        return mHeapMem.getPtr(index);
246    else
247        return mGrallocMem.getPtr(index);
248}
249
250/*===========================================================================
251 * FUNCTION   : valid
252 *
253 * DESCRIPTION: return whether there is a valid buffer at the current index
254 *
255 * PARAMETERS :
256 *   @index   : index of the buffer
257 *
258 * RETURN     : true if there is a buffer, false otherwise
259 *==========================================================================*/
260bool QCamera3StreamMem::valid(uint32_t index)
261{
262    Mutex::Autolock lock(mLock);
263
264    if (index < mMaxHeapBuffers)
265        return (mHeapMem.getSize(index) > 0);
266    else
267        return (mGrallocMem.getSize(index) > 0);
268}
269
270/*===========================================================================
271 * FUNCTION   : registerBuffer
272 *
273 * DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t
274 *
275 * PARAMETERS :
276 *   @buffers : buffer_handle_t pointer
277 *   @type :    cam_stream_type_t
278 *
279 * RETURN     : int32_t type of status
280 *              NO_ERROR  -- success
281 *              none-zero failure code
282 *==========================================================================*/
283int QCamera3StreamMem::registerBuffer(buffer_handle_t *buffer,
284        cam_stream_type_t type)
285{
286    Mutex::Autolock lock(mLock);
287    return mGrallocMem.registerBuffer(buffer, type);
288}
289
290
291/*===========================================================================
292 * FUNCTION   : unregisterBuffer
293 *
294 * DESCRIPTION: unregister buffer
295 *
296 * PARAMETERS :
297 *   @idx     : unregister buffer at index 'idx'
298 *
299 * RETURN     : int32_t type of status
300 *              NO_ERROR  -- success
301 *              none-zero failure code
302 *==========================================================================*/
303int32_t QCamera3StreamMem::unregisterBuffer(size_t idx)
304{
305    Mutex::Autolock lock(mLock);
306    return mGrallocMem.unregisterBuffer(idx);
307}
308
309/*===========================================================================
310 * FUNCTION   : getMatchBufIndex
311 *
312 * DESCRIPTION: query buffer index by object ptr
313 *
314 * PARAMETERS :
315 *   @opaque  : opaque ptr
316 *
317 * RETURN     : buffer index if match found,
318 *              -1 if failed
319 *==========================================================================*/
320int QCamera3StreamMem::getMatchBufIndex(void *object)
321{
322    Mutex::Autolock lock(mLock);
323    return mGrallocMem.getMatchBufIndex(object);
324}
325
326/*===========================================================================
327 * FUNCTION   : getBufferHandle
328 *
329 * DESCRIPTION: return framework pointer
330 *
331 * PARAMETERS :
332 *   @index   : index of the buffer
333 *
334 * RETURN     : buffer ptr if match found
335                NULL if failed
336 *==========================================================================*/
337void *QCamera3StreamMem::getBufferHandle(uint32_t index)
338{
339    Mutex::Autolock lock(mLock);
340    return mGrallocMem.getBufferHandle(index);
341}
342
343/*===========================================================================
344 * FUNCTION   : unregisterBuffers
345 *
346 * DESCRIPTION: unregister buffers
347 *
348 * PARAMETERS : none
349 *
350 * RETURN     : none
351 *==========================================================================*/
352void QCamera3StreamMem::unregisterBuffers()
353{
354    Mutex::Autolock lock(mLock);
355    mGrallocMem.unregisterBuffers();
356}
357
358
359/*===========================================================================
360 * FUNCTION   : allocate
361 *
362 * DESCRIPTION: allocate requested number of buffers of certain size
363 *
364 * PARAMETERS :
365 *   @count   : number of buffers to be allocated
366 *   @size    : lenght of the buffer to be allocated
367 *
368 * RETURN     : int32_t type of status
369 *              NO_ERROR  -- success
370 *              none-zero failure code
371 *==========================================================================*/
372int QCamera3StreamMem::allocateAll(size_t size)
373{
374    Mutex::Autolock lock(mLock);
375    return mHeapMem.allocate(size);
376}
377
378int QCamera3StreamMem::allocateOne(size_t size)
379{
380    Mutex::Autolock lock(mLock);
381    return mHeapMem.allocateOne(size);
382}
383
384/*===========================================================================
385 * FUNCTION   : deallocate
386 *
387 * DESCRIPTION: deallocate heap buffers
388 *
389 * PARAMETERS : none
390 *
391 * RETURN     : none
392 *==========================================================================*/
393void QCamera3StreamMem::deallocate()
394{
395    Mutex::Autolock lock(mLock);
396    mHeapMem.deallocate();
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 *==========================================================================*/
415int32_t QCamera3StreamMem::markFrameNumber(uint32_t index, uint32_t frameNumber)
416{
417    Mutex::Autolock lock(mLock);
418    if (index < mMaxHeapBuffers)
419        return mHeapMem.markFrameNumber(index, frameNumber);
420    else
421        return mGrallocMem.markFrameNumber(index, frameNumber);
422}
423
424/*===========================================================================
425 * FUNCTION   : getFrameNumber
426 *
427 * DESCRIPTION: We use this to fetch the frameNumber for the request with which
428 *              this buffer was given to HAL
429 *
430 *
431 * PARAMETERS :
432 *   @index   : index of the buffer
433 *
434 * RETURN     : int32_t frameNumber
435 *              positive/zero  -- success
436 *              negative failure
437 *==========================================================================*/
438int32_t QCamera3StreamMem::getFrameNumber(uint32_t index)
439{
440    Mutex::Autolock lock(mLock);
441    if (index < mMaxHeapBuffers)
442        return mHeapMem.getFrameNumber(index);
443    else
444        return mGrallocMem.getFrameNumber(index);
445}
446
447/*===========================================================================
448 * FUNCTION   : getGrallocBufferIndex
449 *
450 * DESCRIPTION: We use this to fetch the gralloc buffer index based on frameNumber
451 *
452 * PARAMETERS :
453 *   @frameNumber : frame Number
454 *
455 * RETURN     : int32_t buffer index
456 *              positive/zero  -- success
457 *              negative failure
458 *==========================================================================*/
459int32_t QCamera3StreamMem::getGrallocBufferIndex(uint32_t frameNumber)
460{
461    Mutex::Autolock lock(mLock);
462    int32_t index = mGrallocMem.getBufferIndex(frameNumber);
463    return index;
464}
465
466/*===========================================================================
467 * FUNCTION   : getHeapBufferIndex
468 *
469 * DESCRIPTION: We use this to fetch the heap buffer index based on frameNumber
470 *
471 * PARAMETERS :
472 *   @frameNumber : frame Number
473 *
474 * RETURN     : int32_t buffer index
475 *              positive/zero  -- success
476 *              negative failure
477 *==========================================================================*/
478int32_t QCamera3StreamMem::getHeapBufferIndex(uint32_t frameNumber)
479{
480    Mutex::Autolock lock(mLock);
481    int32_t index = mHeapMem.getBufferIndex(frameNumber);
482    return index;
483}
484
485}; //namespace qcamera
486