Commit | Line | Data |
---|---|---|
5763fb39 T |
1 | /* |
2 | ** | |
3 | ** Copyright 2009 Samsung Electronics Co, Ltd. | |
4 | ** | |
5 | ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | ** you may not use this file except in compliance with the License. | |
7 | ** You may obtain a copy of the License at | |
8 | ** | |
9 | ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 | ** | |
11 | ** Unless required by applicable law or agreed to in writing, software | |
12 | ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | ** See the License for the specific language governing permissions and | |
15 | ** limitations under the License. | |
16 | ** | |
17 | ** | |
18 | */ | |
19 | ||
20 | #define LOG_NDEBUG 0 | |
21 | #define LOG_TAG "FimgExynos5" | |
22 | #include <utils/Log.h> | |
23 | ||
233cfa3d | 24 | #ifdef FIMG2D_USE_M2M1SHOT2 |
5763fb39 | 25 | #include <linux/m2m1shot2.h> |
233cfa3d CH |
26 | #endif |
27 | ||
5763fb39 T |
28 | #include "FimgExynos5.h" |
29 | ||
30 | extern pthread_mutex_t s_g2d_lock; | |
31 | ||
32 | namespace android | |
33 | { | |
34 | unsigned FimgV4x::m_curFimgV4xIndex = 0; | |
35 | int FimgV4x::m_numOfInstance = 0; | |
36 | FimgApi * FimgV4x::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, }; | |
37 | ||
38 | //---------------------------------------------------------------------------// | |
39 | ||
40 | FimgV4x::FimgV4x() | |
41 | : m_g2dFd(0), | |
42 | m_g2dVirtAddr(NULL), | |
43 | m_g2dSize(0), | |
44 | m_g2dSrcVirtAddr(NULL), | |
45 | m_g2dSrcSize(0), | |
46 | m_g2dDstVirtAddr(NULL), | |
47 | m_g2dDstSize(0) | |
48 | { | |
49 | memset(&(m_g2dPoll), 0, sizeof(struct pollfd)); | |
50 | } | |
51 | ||
52 | FimgV4x::~FimgV4x() | |
53 | { | |
54 | } | |
55 | ||
56 | FimgApi *FimgV4x::CreateInstance() | |
57 | { | |
58 | FimgApi *ptrFimg = NULL; | |
59 | ||
60 | for(int i = m_curFimgV4xIndex; i < NUMBER_FIMG_LIST; i++) { | |
61 | if (m_ptrFimgApiList[i] == NULL) | |
62 | m_ptrFimgApiList[i] = new FimgV4x; | |
63 | ||
64 | if (m_ptrFimgApiList[i]->FlagCreate() == false) { | |
65 | if (m_ptrFimgApiList[i]->Create() == false) { | |
66 | PRINT("%s::Create(%d) fail\n", __func__, i); | |
67 | goto CreateInstance_End; | |
68 | } | |
69 | else | |
70 | m_numOfInstance++; | |
71 | } | |
72 | ||
73 | if (i < NUMBER_FIMG_LIST - 1) | |
74 | m_curFimgV4xIndex = i + 1; | |
75 | else | |
76 | m_curFimgV4xIndex = 0; | |
77 | ||
78 | ptrFimg = m_ptrFimgApiList[i]; | |
79 | goto CreateInstance_End; | |
80 | } | |
81 | ||
82 | CreateInstance_End : | |
83 | ||
84 | return ptrFimg; | |
85 | } | |
86 | ||
87 | void FimgV4x::DestroyInstance(FimgApi * ptrFimgApi) | |
88 | { | |
89 | pthread_mutex_lock(&s_g2d_lock); | |
90 | ||
91 | for(int i = 0; i < NUMBER_FIMG_LIST; i++) { | |
92 | if (m_ptrFimgApiList[i] != NULL && m_ptrFimgApiList[i] == ptrFimgApi) { | |
93 | if (m_ptrFimgApiList[i]->FlagCreate() == true && m_ptrFimgApiList[i]->Destroy() == false) { | |
94 | PRINT("%s::Destroy() fail\n", __func__); | |
95 | } else { | |
96 | FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i]; | |
97 | delete tempFimgV4x; | |
98 | m_ptrFimgApiList[i] = NULL; | |
99 | ||
100 | m_numOfInstance--; | |
101 | } | |
102 | ||
103 | break; | |
104 | } | |
105 | } | |
106 | pthread_mutex_unlock(&s_g2d_lock); | |
107 | } | |
108 | ||
109 | void FimgV4x::DestroyAllInstance(void) | |
110 | { | |
111 | pthread_mutex_lock(&s_g2d_lock); | |
112 | ||
113 | for (int i = 0; i < NUMBER_FIMG_LIST; i++) { | |
114 | if (m_ptrFimgApiList[i] != NULL) { | |
115 | if (m_ptrFimgApiList[i]->FlagCreate() == true | |
116 | && m_ptrFimgApiList[i]->Destroy() == false) { | |
117 | PRINT("%s::Destroy() fail\n", __func__); | |
118 | } else { | |
119 | FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i]; | |
120 | delete tempFimgV4x; | |
121 | m_ptrFimgApiList[i] = NULL; | |
122 | } | |
123 | } | |
124 | } | |
125 | pthread_mutex_unlock(&s_g2d_lock); | |
126 | } | |
127 | ||
128 | bool FimgV4x::t_Create(void) | |
129 | { | |
130 | bool ret = true; | |
131 | ||
132 | if (m_CreateG2D() == false) { | |
133 | PRINT("%s::m_CreateG2D() fail \n", __func__); | |
134 | ||
135 | if (m_DestroyG2D() == false) | |
136 | PRINT("%s::m_DestroyG2D() fail \n", __func__); | |
137 | ||
138 | ret = false; | |
139 | } | |
140 | ||
141 | return ret; | |
142 | } | |
143 | ||
144 | bool FimgV4x::t_Destroy(void) | |
145 | { | |
146 | bool ret = true; | |
147 | ||
148 | if (m_DestroyG2D() == false) { | |
149 | PRINT("%s::m_DestroyG2D() fail \n", __func__); | |
150 | ret = false; | |
151 | } | |
152 | ||
153 | return ret; | |
154 | } | |
155 | #ifdef FIMG2D_USE_M2M1SHOT2 | |
156 | bool FimgV4x::t_Stretch_v5(struct m2m1shot2 *cmd) | |
157 | { | |
158 | #ifdef CHECK_FIMGV4x_PERFORMANCE | |
159 | #define NUM_OF_STEP (10) | |
160 | StopWatch stopWatch("CHECK_FIMGV4x_PERFORMANCE"); | |
161 | const char *stopWatchName[NUM_OF_STEP]; | |
162 | nsecs_t stopWatchTime[NUM_OF_STEP]; | |
163 | int stopWatchIndex = 0; | |
164 | #endif // CHECK_FIMGV4x_PERFORMANCE | |
165 | ||
166 | if (m_DoG2D_v5(cmd) == false) | |
167 | goto STRETCH_FAIL; | |
168 | ||
169 | #ifdef G2D_NONE_BLOCKING_MODE | |
170 | if (m_PollG2D(&m_g2dPoll) == false) { | |
171 | PRINT("%s::m_PollG2D() fail\n", __func__); | |
172 | goto STRETCH_FAIL; | |
173 | } | |
174 | #endif | |
175 | ||
176 | #ifdef CHECK_FIMGV4x_PERFORMANCE | |
177 | m_PrintFimgV4xPerformance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime); | |
178 | #endif // CHECK_FIMGV4x_PERFORMANCE | |
179 | ||
180 | return true; | |
181 | ||
182 | STRETCH_FAIL: | |
183 | return false; | |
184 | ||
185 | } | |
186 | #endif | |
187 | bool FimgV4x::t_Stretch(struct fimg2d_blit *cmd) | |
188 | { | |
189 | #ifdef CHECK_FIMGV4x_PERFORMANCE | |
190 | #define NUM_OF_STEP (10) | |
191 | StopWatch stopWatch("CHECK_FIMGV4x_PERFORMANCE"); | |
192 | const char *stopWatchName[NUM_OF_STEP]; | |
193 | nsecs_t stopWatchTime[NUM_OF_STEP]; | |
194 | int stopWatchIndex = 0; | |
195 | #endif // CHECK_FIMGV4x_PERFORMANCE | |
196 | ||
197 | if (m_DoG2D(cmd) == false) | |
198 | goto STRETCH_FAIL; | |
199 | ||
200 | #ifdef G2D_NONE_BLOCKING_MODE | |
201 | if (m_PollG2D(&m_g2dPoll) == false) { | |
202 | PRINT("%s::m_PollG2D() fail\n", __func__); | |
203 | goto STRETCH_FAIL; | |
204 | } | |
205 | #endif | |
206 | ||
207 | #ifdef CHECK_FIMGV4x_PERFORMANCE | |
208 | m_PrintFimgV4xPerformance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime); | |
209 | #endif // CHECK_FIMGV4x_PERFORMANCE | |
210 | ||
211 | return true; | |
212 | ||
213 | STRETCH_FAIL: | |
214 | return false; | |
215 | ||
216 | } | |
217 | ||
218 | bool FimgV4x::t_Sync(void) | |
219 | { | |
220 | if (m_PollG2D(&m_g2dPoll) == false) { | |
221 | PRINT("%s::m_PollG2D() fail\n", __func__); | |
222 | goto SYNC_FAIL; | |
223 | } | |
224 | return true; | |
225 | ||
226 | SYNC_FAIL: | |
227 | return false; | |
228 | ||
229 | } | |
230 | ||
231 | bool FimgV4x::t_Lock(void) | |
232 | { | |
e9cb1cae | 233 | return m_lock.lock(); |
5763fb39 T |
234 | } |
235 | ||
236 | bool FimgV4x::t_UnLock(void) | |
237 | { | |
e9cb1cae CH |
238 | m_lock.unlock(); |
239 | return true; | |
5763fb39 T |
240 | } |
241 | ||
242 | bool FimgV4x::m_CreateG2D(void) | |
243 | { | |
244 | void * mmap_base; | |
245 | int val = 0; | |
246 | ||
247 | if (m_g2dFd != 0) { | |
248 | PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd); | |
249 | return false; | |
250 | } | |
251 | ||
252 | #ifdef G2D_NONE_BLOCKING_MODE | |
253 | m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK); | |
254 | #else | |
255 | m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR); | |
256 | #endif | |
257 | if (m_g2dFd < 0) { | |
258 | PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno)); | |
259 | m_g2dFd = 0; | |
260 | return false; | |
261 | } | |
262 | val = fcntl(m_g2dFd, F_GETFD, 0); | |
263 | if (val < 0) { | |
264 | PRINT("%s::GETFD(%s) fail\n", __func__, SEC_G2D_DEV_NAME); | |
265 | close(m_g2dFd); | |
266 | m_g2dFd = 0; | |
267 | return false; | |
268 | } | |
269 | val = fcntl(m_g2dFd, F_SETFD, val | FD_CLOEXEC); | |
270 | if (val < 0) { | |
271 | PRINT("%s::SETFD(%s) fail\n", __func__, SEC_G2D_DEV_NAME); | |
272 | close(m_g2dFd); | |
273 | m_g2dFd = 0; | |
274 | return false; | |
275 | } | |
276 | ||
277 | memset(&m_g2dPoll, 0, sizeof(m_g2dPoll)); | |
278 | m_g2dPoll.fd = m_g2dFd; | |
279 | m_g2dPoll.events = POLLOUT | POLLERR; | |
280 | ||
281 | return true; | |
282 | } | |
283 | ||
284 | bool FimgV4x::m_DestroyG2D(void) | |
285 | { | |
286 | if (m_g2dVirtAddr != NULL) { | |
287 | munmap(m_g2dVirtAddr, m_g2dSize); | |
288 | m_g2dVirtAddr = NULL; | |
289 | m_g2dSize = 0; | |
290 | } | |
291 | ||
292 | if (0 < m_g2dFd) | |
293 | close(m_g2dFd); | |
294 | ||
295 | m_g2dFd = 0; | |
296 | ||
297 | return true; | |
298 | } | |
299 | #ifdef FIMG2D_USE_M2M1SHOT2 | |
300 | bool FimgV4x::m_DoG2D_v5(struct m2m1shot2 *cmd) | |
301 | { | |
302 | if (ioctl(m_g2dFd, M2M1SHOT2_IOC_PROCESS, cmd) < 0) | |
303 | return false; | |
304 | /* support the error handling */ | |
305 | if (cmd->flags & M2M1SHOT2_FLAG_ERROR) { | |
306 | ALOGE("%s: hardware operation failed", __func__); | |
307 | return false; | |
308 | } | |
309 | return true; | |
310 | } | |
311 | #endif | |
312 | bool FimgV4x::m_DoG2D(struct fimg2d_blit *cmd) | |
313 | { | |
314 | if (ioctl(m_g2dFd, FIMG2D_BITBLT_BLIT, cmd) < 0) | |
315 | return false; | |
316 | ||
317 | /* wait to complte the blit */ | |
318 | ioctl(m_g2dFd, FIMG2D_BITBLT_SYNC); | |
319 | ||
320 | return true; | |
321 | } | |
322 | ||
323 | inline bool FimgV4x::m_PollG2D(struct pollfd * events) | |
324 | { | |
325 | #define G2D_POLL_TIME (1000) | |
326 | ||
327 | int ret; | |
328 | ||
329 | ret = poll(events, 1, G2D_POLL_TIME); | |
330 | ||
331 | if (ret < 0) { | |
332 | PRINT("%s::poll fail \n", __func__); | |
333 | return false; | |
334 | } | |
335 | else if (ret == 0) { | |
336 | PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME); | |
337 | return false; | |
338 | } | |
339 | ||
340 | return true; | |
341 | } | |
342 | ||
343 | //---------------------------------------------------------------------------// | |
344 | // extern function | |
345 | //---------------------------------------------------------------------------// | |
346 | extern "C" struct FimgApi * createFimgApi() | |
347 | { | |
348 | if (fimgApiAutoFreeThread == 0) | |
349 | fimgApiAutoFreeThread = new FimgApiAutoFreeThread(); | |
350 | else | |
351 | fimgApiAutoFreeThread->SetOneMoreSleep(); | |
352 | ||
353 | return FimgV4x::CreateInstance(); | |
354 | } | |
355 | ||
356 | extern "C" void destroyFimgApi(__attribute__((__unused__)) FimgApi * ptrFimgApi) | |
357 | { | |
358 | // Dont' call DestroyInstance. | |
359 | } | |
360 | ||
361 | extern "C" bool checkScaleFimgApi(Fimg *fimg) | |
362 | { | |
363 | unsigned int i; | |
364 | for (i = 0; i < sizeof(compare_size) / sizeof(compare_size[0]); i++) { | |
365 | if ((fimg->srcW == compare_size[i][0]) && (fimg->srcH == compare_size[i][1]) && | |
366 | (fimg->dstW == compare_size[i][2]) && (fimg->dstH == compare_size[i][3])) | |
367 | return true; | |
368 | } | |
369 | return false; | |
370 | } | |
371 | ||
372 | }; // namespace android |