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