MemoryManager.cpp revision 1f1f957cc6768d24b09fd96f76aaec3884e1623e
1/*
2 * Copyright (C) Texas Instruments - http://www.ti.com/
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18
19#define LOG_TAG "CameraHAL"
20
21
22#include "CameraHal.h"
23#include "TICameraParameters.h"
24
25extern "C" {
26
27#include "memmgr.h"
28#include "tiler.h"
29//#include <timm_osal_interfaces.h>
30//#include <timm_osal_trace.h>
31
32
33};
34
35namespace android {
36
37///@todo Move these constants to a common header file, preferably in tiler.h
38#define STRIDE_8BIT (4 * 1024)
39#define STRIDE_16BIT (4 * 1024)
40
41#define ALLOCATION_2D 2
42
43///Utility Macro Declarations
44
45/*--------------------MemoryManager Class STARTS here-----------------------------*/
46void* MemoryManager::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs)
47{
48    LOG_FUNCTION_NAME;
49    ///We allocate numBufs+1 because the last entry will be marked NULL to indicate end of array, which is used when freeing
50    ///the buffers
51    const uint numArrayEntriesC = (uint)(numBufs+1);
52
53    MemAllocBlock tMemBlock[ALLOCATION_2D];
54    memset(tMemBlock, 0, sizeof(MemAllocBlock));
55
56    ///Allocate a buffer array
57    uint32_t *bufsArr = new uint32_t [numArrayEntriesC];
58    if(!bufsArr)
59        {
60        CAMHAL_LOGEB("Allocation failed when creating buffers array of %d uint32_t elements", numArrayEntriesC);
61        LOG_FUNCTION_NAME_EXIT;
62        return NULL;
63        }
64
65    ///Initialize the array with zeros - this will help us while freeing the array in case of error
66    ///If a value of an array element is NULL, it means we didnt allocate it
67    memset(bufsArr, 0, sizeof(*bufsArr) * numArrayEntriesC);
68
69    ///If the bytes field is not zero, it means it is a 1-D tiler buffer request (possibly for image capture bit stream buffer)
70    if(bytes!=0)
71        {
72        ///1D buffers
73        for (int i = 0; i < numBufs; i++)
74            {
75            tMemBlock->dim.len = bytes;
76            tMemBlock->fmt = PIXEL_FMT_PAGE;
77            tMemBlock->stride = 0;
78            CAMHAL_LOGDB("requested bytes = %d", bytes);
79            CAMHAL_LOGDB("tMemBlock.dim.len = %d", tMemBlock->dim.len);
80            bufsArr[i] = (uint32_t)MemMgr_Alloc(tMemBlock, 1);
81            if(!bufsArr[i])
82                {
83                LOGE("Buffer allocation failed for iteration %d", i);
84                goto error;
85                }
86            else
87                {
88                CAMHAL_LOGDB("Allocated Tiler PAGED mode buffer address[%x]", bufsArr[i]);
89                }
90            }
91
92        }
93    else ///If bytes is not zero, then it is a 2-D tiler buffer request
94        {
95        ///2D buffers
96
97        for (int i = 0; i < numBufs; i++)
98            {
99            int numAllocs = 1;
100            pixel_fmt_t pixelFormat[ALLOCATION_2D];
101            int stride[ALLOCATION_2D];
102
103            if(!strcmp(format,(const char *) CameraParameters::PIXEL_FORMAT_YUV422I))
104                {
105                ///YUV422I format
106                pixelFormat[0] = PIXEL_FMT_16BIT;
107                stride[0] = STRIDE_16BIT;
108                }
109            else if(!strcmp(format,(const char *) CameraParameters::PIXEL_FORMAT_YUV420SP))
110                {
111                ///YUV420 NV12 format
112                pixelFormat[0] = PIXEL_FMT_8BIT;
113                pixelFormat[1] = PIXEL_FMT_16BIT;
114                stride[0] = STRIDE_8BIT;
115                stride[1] = STRIDE_16BIT;
116                numAllocs = 2;
117                }
118            else if(!strcmp(format,(const char *) CameraParameters::PIXEL_FORMAT_RGB565))
119                {
120                ///RGB 565 format
121                pixelFormat[0] = PIXEL_FMT_16BIT;
122                stride[0] = STRIDE_16BIT;
123                }
124            else if(!strcmp(format,(const char *) TICameraParameters::PIXEL_FORMAT_RAW))
125                {
126                ///RAW format
127                pixelFormat[0] = PIXEL_FMT_16BIT;
128                stride[0] = STRIDE_16BIT;
129                }
130            else
131                {
132                ///By default assume YUV420 NV12 format
133                ///YUV420 NV12 format
134                pixelFormat[0] = PIXEL_FMT_8BIT;
135                pixelFormat[1] = PIXEL_FMT_16BIT;
136                stride[0] = STRIDE_8BIT;
137                stride[1] = STRIDE_16BIT;
138                numAllocs = 2;
139                }
140
141            for(int index=0;index<numAllocs;index++)
142                {
143                tMemBlock[index].fmt = pixelFormat[index];
144                tMemBlock[index].stride = stride[index];
145                tMemBlock[index].dim.area.width=  width;/*width*/
146                tMemBlock[index].dim.area.height=  height;/*height*/
147                }
148
149            bufsArr[i] = (uint32_t)MemMgr_Alloc(tMemBlock, numAllocs);
150            if(!bufsArr[i])
151                {
152                CAMHAL_LOGEB("Buffer allocation failed for iteration %d", i);
153                goto error;
154                }
155            else
156                {
157                CAMHAL_LOGDB("Allocated Tiler PAGED mode buffer address[%x]", bufsArr[i]);
158                }
159            }
160        }
161
162        LOG_FUNCTION_NAME_EXIT;
163
164        return (void*)bufsArr;
165
166    error:
167        LOGE("Freeing buffers already allocated after error occurred");
168        freeBuffer(bufsArr);
169        free(tMemBlock);
170
171        if ( NULL != mErrorNotifier.get() )
172            {
173            mErrorNotifier->errorNotify(-ENOMEM);
174            }
175
176        LOG_FUNCTION_NAME_EXIT;
177        return NULL;
178}
179
180//TODO: Get needed data to map tiler buffers
181//Return dummy data for now
182uint32_t * MemoryManager::getOffsets()
183{
184    LOG_FUNCTION_NAME;
185
186    LOG_FUNCTION_NAME_EXIT;
187
188    return NULL;
189}
190
191int MemoryManager::getFd()
192{
193    LOG_FUNCTION_NAME;
194
195    LOG_FUNCTION_NAME_EXIT;
196
197    return -1;
198}
199
200int MemoryManager::freeBuffer(void* buf)
201{
202    status_t ret = NO_ERROR;
203    LOG_FUNCTION_NAME;
204
205    uint32_t *bufEntry = (uint32_t*)buf;
206
207    if(!bufEntry)
208        {
209        CAMHAL_LOGEA("NULL pointer passed to freebuffer");
210        LOG_FUNCTION_NAME_EXIT;
211        return BAD_VALUE;
212        }
213
214    while(*bufEntry)
215        {
216        ret |= MemMgr_Free((void*)*bufEntry++);
217        }
218
219    ///@todo Check if this way of deleting array is correct, else use malloc/free
220    uint32_t * bufArr = (uint32_t*)buf;
221    delete [] bufArr;
222
223    LOG_FUNCTION_NAME_EXIT;
224    return ret;
225}
226
227status_t MemoryManager::setErrorHandler(ErrorNotifier *errorNotifier)
228{
229    status_t ret = NO_ERROR;
230
231    LOG_FUNCTION_NAME;
232
233    if ( NULL == errorNotifier )
234        {
235        CAMHAL_LOGEA("Invalid Error Notifier reference");
236        ret = -EINVAL;
237        }
238
239    if ( NO_ERROR == ret )
240        {
241        mErrorNotifier = errorNotifier;
242        }
243
244    LOG_FUNCTION_NAME_EXIT;
245
246    return ret;
247}
248
249};
250
251
252/*--------------------MemoryManager Class ENDS here-----------------------------*/
253