• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
25 extern "C" {
26 
27 #include <ion.h>
28 
29 //#include <timm_osal_interfaces.h>
30 //#include <timm_osal_trace.h>
31 
32 
33 };
34 
35 namespace 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-----------------------------*/
allocateBuffer(int width,int height,const char * format,int & bytes,int numBufs)46 void* MemoryManager::allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs)
47 {
48     LOG_FUNCTION_NAME;
49 
50     if(mIonFd == 0)
51         {
52         mIonFd = ion_open();
53         if(mIonFd == 0)
54             {
55             CAMHAL_LOGEA("ion_open failed!!!");
56             return NULL;
57             }
58         }
59 
60     ///We allocate numBufs+1 because the last entry will be marked NULL to indicate end of array, which is used when freeing
61     ///the buffers
62     const uint numArrayEntriesC = (uint)(numBufs+1);
63 
64     ///Allocate a buffer array
65     uint32_t *bufsArr = new uint32_t [numArrayEntriesC];
66     if(!bufsArr)
67         {
68         CAMHAL_LOGEB("Allocation failed when creating buffers array of %d uint32_t elements", numArrayEntriesC);
69         LOG_FUNCTION_NAME_EXIT;
70         return NULL;
71         }
72 
73     ///Initialize the array with zeros - this will help us while freeing the array in case of error
74     ///If a value of an array element is NULL, it means we didnt allocate it
75     memset(bufsArr, 0, sizeof(*bufsArr) * numArrayEntriesC);
76 
77     //2D Allocations are not supported currently
78     if(bytes != 0)
79         {
80         struct ion_handle *handle;
81         int mmap_fd;
82 
83         ///1D buffers
84         for (int i = 0; i < numBufs; i++)
85             {
86             int ret = ion_alloc(mIonFd, bytes, 0, 1 << ION_HEAP_TYPE_CARVEOUT, &handle);
87             if(ret < 0)
88                 {
89                 CAMHAL_LOGEB("ion_alloc resulted in error %d", ret);
90                 goto error;
91                 }
92 
93             CAMHAL_LOGDB("Before mapping, handle = %x, nSize = %d", handle, bytes);
94             if ((ret = ion_map(mIonFd, handle, bytes, PROT_READ | PROT_WRITE, MAP_SHARED, 0,
95                           (unsigned char**)&bufsArr[i], &mmap_fd)) < 0)
96                 {
97                 CAMHAL_LOGEB("Userspace mapping of ION buffers returned error %d", ret);
98                 ion_free(mIonFd, handle);
99                 goto error;
100                 }
101 
102             mIonHandleMap.add(bufsArr[i], (unsigned int)handle);
103             mIonFdMap.add(bufsArr[i], (unsigned int) mmap_fd);
104             mIonBufLength.add(bufsArr[i], (unsigned int) bytes);
105             }
106 
107         }
108     else // If bytes is not zero, then it is a 2-D tiler buffer request
109         {
110         }
111 
112         LOG_FUNCTION_NAME_EXIT;
113 
114         return (void*)bufsArr;
115 
116 error:
117     LOGE("Freeing buffers already allocated after error occurred");
118     freeBuffer(bufsArr);
119 
120     if ( NULL != mErrorNotifier.get() )
121         {
122         mErrorNotifier->errorNotify(-ENOMEM);
123         }
124 
125     LOG_FUNCTION_NAME_EXIT;
126     return NULL;
127 }
128 
129 //TODO: Get needed data to map tiler buffers
130 //Return dummy data for now
getOffsets()131 uint32_t * MemoryManager::getOffsets()
132 {
133     LOG_FUNCTION_NAME;
134 
135     LOG_FUNCTION_NAME_EXIT;
136 
137     return NULL;
138 }
139 
getFd()140 int MemoryManager::getFd()
141 {
142     LOG_FUNCTION_NAME;
143 
144     LOG_FUNCTION_NAME_EXIT;
145 
146     return -1;
147 }
148 
freeBuffer(void * buf)149 int MemoryManager::freeBuffer(void* buf)
150 {
151     status_t ret = NO_ERROR;
152     LOG_FUNCTION_NAME;
153 
154     uint32_t *bufEntry = (uint32_t*)buf;
155 
156     if(!bufEntry)
157         {
158         CAMHAL_LOGEA("NULL pointer passed to freebuffer");
159         LOG_FUNCTION_NAME_EXIT;
160         return BAD_VALUE;
161         }
162 
163     while(*bufEntry)
164         {
165         unsigned int ptr = (unsigned int) *bufEntry++;
166         if(mIonBufLength.valueFor(ptr))
167             {
168             munmap((void *)ptr, mIonBufLength.valueFor(ptr));
169             close(mIonFdMap.valueFor(ptr));
170             ion_free(mIonFd, (ion_handle*)mIonHandleMap.valueFor(ptr));
171             mIonHandleMap.removeItem(ptr);
172             mIonBufLength.removeItem(ptr);
173             mIonFdMap.removeItem(ptr);
174             }
175         else
176             {
177             CAMHAL_LOGEA("Not a valid Memory Manager buffer");
178             }
179         }
180 
181     ///@todo Check if this way of deleting array is correct, else use malloc/free
182     uint32_t * bufArr = (uint32_t*)buf;
183     delete [] bufArr;
184 
185     if(mIonBufLength.size() == 0)
186         {
187         if(mIonFd)
188             {
189             ion_close(mIonFd);
190             mIonFd = 0;
191             }
192         }
193     LOG_FUNCTION_NAME_EXIT;
194     return ret;
195 }
196 
setErrorHandler(ErrorNotifier * errorNotifier)197 status_t MemoryManager::setErrorHandler(ErrorNotifier *errorNotifier)
198 {
199     status_t ret = NO_ERROR;
200 
201     LOG_FUNCTION_NAME;
202 
203     if ( NULL == errorNotifier )
204         {
205         CAMHAL_LOGEA("Invalid Error Notifier reference");
206         ret = -EINVAL;
207         }
208 
209     if ( NO_ERROR == ret )
210         {
211         mErrorNotifier = errorNotifier;
212         }
213 
214     LOG_FUNCTION_NAME_EXIT;
215 
216     return ret;
217 }
218 
219 };
220 
221 
222 /*--------------------MemoryManager Class ENDS here-----------------------------*/
223