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