blob: 129acaec3f04abcbbbd6e82693a1c5005956e5c7 [file] [log] [blame]
codeworkxf1be2fe2012-03-24 17:38:29 +01001/*
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///////////////////////////////////////////////////
21// include
22///////////////////////////////////////////////////
Daniel Hillenbrand353fecb2012-07-22 16:14:08 +020023#define LOG_NDEBUG 0
24#define LOG_TAG "FimgC210"
codeworkxf1be2fe2012-03-24 17:38:29 +010025#include <utils/Log.h>
26
27#include "FimgC210.h"
28
29namespace android
30{
31
32//---------------------------------------------------------------------------//
33// FimgC210
34//---------------------------------------------------------------------------//
35
36Mutex FimgC210::m_instanceLock;
37int FimgC210::m_curFimgC210Index = 0;
38int FimgC210::m_numOfInstance = 0;
39FimgApi * FimgC210::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, };
40
41//---------------------------------------------------------------------------//
42
43FimgC210::FimgC210()
44 : m_g2dFd(0),
45 m_g2dVirtAddr(NULL),
46 m_g2dSize(0),
47 m_g2dSrcVirtAddr(NULL),
48 m_g2dSrcSize(0),
49 m_g2dDstVirtAddr(NULL),
50 m_g2dDstSize(0)
51{
52 m_lock = new Mutex(Mutex::SHARED, "FimgC210");
53}
54
55FimgC210::~FimgC210()
56{
57 delete m_lock;
58}
59
60FimgApi * FimgC210::CreateInstance()
61{
62 Mutex::Autolock autolock(m_instanceLock);
63
64 FimgApi * ptrFimg = NULL;
65
66 // Using List like RingBuffer...
67 for(int i = m_curFimgC210Index; i < NUMBER_FIMG_LIST; i++) {
68 if(m_ptrFimgApiList[i] == NULL)
69 m_ptrFimgApiList[i] = new FimgC210;
70
71 if(m_ptrFimgApiList[i]->FlagCreate() == false) {
72 if(m_ptrFimgApiList[i]->Create() == false) {
73 PRINT("%s::Create(%d) fail\n", __func__, i);
74 goto CreateInstance_End;
75 }
76 else
77 m_numOfInstance++;
78 }
79
80 if(i < NUMBER_FIMG_LIST - 1)
81 m_curFimgC210Index = i + 1;
82 else
83 m_curFimgC210Index = 0;
84
85 ptrFimg = m_ptrFimgApiList[i];
86 goto CreateInstance_End;
87 }
88
89CreateInstance_End :
90
91 return ptrFimg;
92}
93
94void FimgC210::DestroyInstance(FimgApi * ptrFimgApi)
95{
96 Mutex::Autolock autolock(m_instanceLock);
97
98 for(int i = 0; i < NUMBER_FIMG_LIST; i++) {
99 if(m_ptrFimgApiList[i] != NULL
100 && m_ptrFimgApiList[i] == ptrFimgApi) {
101 if(m_ptrFimgApiList[i]->FlagCreate() == true
102 && m_ptrFimgApiList[i]->Destroy() == false) {
103 PRINT("%s::Destroy() fail\n", __func__);
104 } else {
105 FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i];
106 delete tempFimgC210;
107 m_ptrFimgApiList[i] = NULL;
108
109 m_numOfInstance--;
110 }
111
112 break;
113 }
114 }
115}
116
117void FimgC210::DestroyAllInstance(void)
118{
119 Mutex::Autolock autolock(m_instanceLock);
120
121 for(int i = 0; i < NUMBER_FIMG_LIST; i++) {
122 if(m_ptrFimgApiList[i] != NULL) {
123 if(m_ptrFimgApiList[i]->FlagCreate() == true
124 && m_ptrFimgApiList[i]->Destroy() == false) {
125 PRINT("%s::Destroy() fail\n", __func__);
126 } else {
127 FimgC210 * tempFimgC210 = (FimgC210 *)m_ptrFimgApiList[i];
128 delete tempFimgC210;
129 m_ptrFimgApiList[i] = NULL;
130 }
131 }
132 }
133}
134
135
136bool FimgC210::t_Create(void)
137{
138 bool ret = true;
139
140 if(m_CreateG2D() == false) {
141 PRINT("%s::m_CreateG2D() fail \n", __func__);
142
143 if(m_DestroyG2D() == false)
144 PRINT("%s::m_DestroyG2D() fail \n", __func__);
145
146 ret = false;
147 }
148
149 return ret;
150}
151
152bool FimgC210::t_Destroy(void)
153{
154 bool ret = true;
155
156 if(m_DestroyG2D() == false) {
157 PRINT("%s::m_DestroyG2D() fail \n", __func__);
158 ret = false;
159 }
160
161 return ret;
162}
163
164bool FimgC210::t_Stretch(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag)
165{
166 #ifdef CHECK_FIMGC210_PERFORMANCE
167 #define NUM_OF_STEP (10)
168 StopWatch stopWatch("CHECK_FIMGC210_PERFORMANCE");
169 const char * stopWatchName[NUM_OF_STEP];
170 nsecs_t stopWatchTime[NUM_OF_STEP];
171 int stopWatchIndex = 0;
172 #endif // CHECK_FIMGC210_PERFORMANCE
173
174 if(m_DoG2D(src, dst, clip, flag) == false) {
175 goto STRETCH_FAIL;
176 }
177
178#ifdef G2D_NONE_BLOCKING_MODE
179 if(m_PollG2D(&m_g2dPoll) == false)
180 {
181 PRINT("%s::m_PollG2D() fail\n", __func__);
182 goto STRETCH_FAIL;
183 }
184#endif
185
186 #ifdef CHECK_FIMGC210_PERFORMANCE
187 m_PrintFimgC210Performance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime);
188 #endif // CHECK_FIMGC210_PERFORMANCE
189
190 return true;
191
192STRETCH_FAIL:
193 return false;
194
195}
196
197bool FimgC210::t_Sync(void)
198{
199#if 0
200 if(ioctl(m_g2dFd, G2D_SYNC) < 0) {
201 PRINT("%s::G2D_Sync fail\n", __func__);
202 goto SYNC_FAIL;
203 }
204#else
205 if(m_PollG2D(&m_g2dPoll) == false)
206 {
207 PRINT("%s::m_PollG2D() fail\n", __func__);
208 goto SYNC_FAIL;
209 }
210#endif
211 return true;
212
213SYNC_FAIL:
214 return false;
215
216}
217
218bool FimgC210::t_Lock(void)
219{
220 m_lock->lock();
221 return true;
222}
223
224bool FimgC210::t_UnLock(void)
225{
226 m_lock->unlock();
227 return true;
228}
229
230bool FimgC210::m_CreateG2D(void)
231{
232 void * mmap_base;
233
234 if(m_g2dFd != 0) {
235 PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd);
236 return false;
237 }
238
239#ifdef G2D_NONE_BLOCKING_MODE
240 m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK);
241#else
242 m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR);
243#endif
244 if(m_g2dFd < 0) {
245 PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno));
246 m_g2dFd = 0;
247 return false;
248 }
249
250 memset(&m_g2dPoll, 0, sizeof(m_g2dPoll));
251 m_g2dPoll.fd = m_g2dFd;
252 m_g2dPoll.events = POLLOUT | POLLERR;
253
254 return true;
255}
256
257bool FimgC210::m_DestroyG2D(void)
258{
259 if(m_g2dVirtAddr != NULL) {
260 munmap(m_g2dVirtAddr, m_g2dSize);
261 m_g2dVirtAddr = NULL;
262 m_g2dSize = 0;
263 }
264
265 if(0 < m_g2dFd) {
266 close(m_g2dFd);
267 }
268 m_g2dFd = 0;
269
270 return true;
271}
272
273//bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, int rotateValue, int alphaValue, int colorKey)
274bool FimgC210::m_DoG2D(FimgRect * src, FimgRect * dst, FimgClip * clip, FimgFlag * flag)
275{
276 g2d_params params;
277
278 memcpy(&params.src_rect, src, sizeof(FimgRect));
279 memcpy(&params.dst_rect, dst, sizeof(FimgRect));
280 memcpy(&params.clip, clip, sizeof(FimgClip));
281 memcpy(&params.flag, flag, sizeof(FimgFlag));
282
283 if(ioctl(m_g2dFd, G2D_BLIT, &params) < 0) {
284 #if 0
285 {
286 PRINT("---------------------------------------\n");
287 PRINT("src.color_format : %d \n", src->color_format);
288 PRINT("src.full_w : %d \n", src->full_w);
289 PRINT("src.full_h : %d \n", src->full_h);
290 PRINT("src.x : %d \n", src->x);
291 PRINT("src.y : %d \n", src->y);
292 PRINT("src.w : %d \n", src->w);
293 PRINT("src.h : %d \n", src->h);
294
295 PRINT("dst.color_format : %d \n", dst->color_format);
296 PRINT("dst.full_w : %d \n", dst->full_w);
297 PRINT("dst.full_h : %d \n", dst->full_h);
298 PRINT("dst.x : %d \n", dst->x);
299 PRINT("dst.y : %d \n", dst->y);
300 PRINT("dst.w : %d \n", dst->w);
301 PRINT("dst.h : %d \n", dst->h);
302
303 PRINT("flag.rotate_val : %d \n", flag->rotate_val);
304 PRINT("flag.alpha_val : %d(%d) \n", flag->alpha_val);
305 PRINT("flag.color_key_mode : %d(%d) \n", flag->color_key_mode, flag->color_key_val);
306 PRINT("---------------------------------------\n");
307 }
308 #endif
309
310 return false;
311 }
312
313 return true;
314}
315
316inline bool FimgC210::m_PollG2D(struct pollfd * events)
317{
318 #define G2D_POLL_TIME (1000)
319
320 int ret;
321
322 ret = poll(events, 1, G2D_POLL_TIME);
323
324 if (ret < 0) {
325 if(ioctl(m_g2dFd, G2D_RESET) < 0) {
326 PRINT("%s::G2D_RESET fail\n", __func__);
327 }
328 PRINT("%s::poll fail \n", __func__);
329 return false;
330 }
331 else if (ret == 0) {
332 if(ioctl(m_g2dFd, G2D_RESET) < 0) {
333 PRINT("%s::G2D_RESET fail\n", __func__);
334 }
335 PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME);
336 return false;
337 }
338
339 return true;
340}
341
342inline bool FimgC210::m_CleanG2D(unsigned int virtAddr, unsigned int size)
343{
344 g2d_dma_info dma_info = { virtAddr, size };
345
346 if(ioctl(m_g2dFd, G2D_DMA_CACHE_CLEAN, &dma_info) < 0) {
347 PRINT("%s::G2D_DMA_CACHE_CLEAN(%d, %d) fail\n", __func__, virtAddr, size);
348 return false;
349 }
350 return true;
351}
352
353inline bool FimgC210::m_FlushG2D (unsigned int virtAddr, unsigned int size)
354{
355 g2d_dma_info dma_info = { virtAddr, size };
356
357 if(ioctl(m_g2dFd, G2D_DMA_CACHE_FLUSH, &dma_info) < 0) {
358 PRINT("%s::G2D_DMA_CACHE_FLUSH(%d, %d) fail\n", __func__, virtAddr, size);
359 return false;
360 }
361 return true;
362}
363
364inline int FimgC210::m_RotateValueFimgApi2FimgHw(int rotateValue)
365{
366 switch (rotateValue) {
367 case ROTATE_0: return G2D_ROT_0;
368 case ROTATE_90: return G2D_ROT_90;
369 case ROTATE_180: return G2D_ROT_180;
370 case ROTATE_270: return G2D_ROT_270;
371 case ROTATE_X_FLIP: return G2D_ROT_X_FLIP;
372 case ROTATE_Y_FLIP: return G2D_ROT_Y_FLIP;
373 }
374
375 return -1;
376}
377
378
379#ifdef CHECK_FIMGC210_PERFORMANCE
380void FimgC210::m_PrintFimgC210Performance(FimgRect * src,
381 FimgRect * dst,
382 int stopWatchIndex,
383 const char * stopWatchName[],
384 nsecs_t stopWatchTime[])
385{
386 char * srcColorFormat = "UNKNOW_COLOR_FORMAT";
387 char * dstColorFormat = "UNKNOW_COLOR_FORMAT";
388
389 switch(src->color_format)
390 {
391 case COLOR_FORMAT_RGB_565 :
392 srcColorFormat = "RGB_565";
393 break;
394 case COLOR_FORMAT_RGBA_8888 :
395 srcColorFormat = "RGBA_8888";
396 break;
397 case COLOR_FORMAT_RGBX_8888 :
398 srcColorFormat = "RGBX_8888";
399 break;
400 default :
401 srcColorFormat = "UNKNOW_COLOR_FORMAT";
402 break;
403 }
404
405 switch(dst->color_format)
406 {
407 case COLOR_FORMAT_RGB_565 :
408 dstColorFormat = "RGB_565";
409 break;
410 case COLOR_FORMAT_RGBA_8888 :
411 dstColorFormat = "RGBA_8888";
412 break;
413 case COLOR_FORMAT_RGBX_8888 :
414 dstColorFormat = "RGBX_8888";
415 break;
416 default :
417 dstColorFormat = "UNKNOW_COLOR_FORMAT";
418 break;
419 }
420
421
422#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE
423#else
424 PRINT("===============================================\n");
425 PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n",
426 src->w, src->h, srcColorFormat,
427 dst->w, dst->h, dstColorFormat);
428#endif
429
430 nsecs_t totalTime = stopWatchTime[stopWatchIndex - 1];
431
432 for(int i = 0 ; i < stopWatchIndex; i++) {
433 nsecs_t sectionTime;
434
435 if(i != 0)
436 sectionTime = stopWatchTime[i] - stopWatchTime[i-1];
437 else
438 sectionTime = stopWatchTime[i];
439
440#ifdef CHECK_FIMGC210_CRITICAL_PERFORMANCE
441 if(1500 < (sectionTime / 1000)) // check 1.5 mille second..
442#endif
443 {
444 PRINT("===============================================\n");
445 PRINT("src[%3d, %3d | %10s] -> dst[%3d, %3d | %10s]\n",
446 src->w, src->h, srcColorFormat,
447 dst->w, dst->h, dstColorFormat);
448
449 PRINT("%20s : %5lld msec(%5.2f %%)\n",
450 stopWatchName[i],
451 sectionTime / 1000,
452 ((float)sectionTime / (float)totalTime) * 100.0f);
453 }
454 }
455
456}
457#endif // CHECK_FIMGC210_PERFORMANCE
458
459//---------------------------------------------------------------------------//
460// extern function
461//---------------------------------------------------------------------------//
462extern "C" struct FimgApi * createFimgApi()
463{
464 if (fimgApiAutoFreeThread == 0)
465 fimgApiAutoFreeThread = new FimgApiAutoFreeThread();
466 else
467 fimgApiAutoFreeThread->SetOneMoreSleep();
468
469 return FimgC210::CreateInstance();
470}
471
472extern "C" void destroyFimgApi(FimgApi * ptrFimgApi)
473{
474 // Dont' call DestrotInstance..
475 // return FimgC210::DestroyInstance(ptrFimgApi);
476}
477
478}; // namespace android