blob: f9a7f1e1ec5547f54dcc9db83c3a0a6bbd52c7bd [file] [log] [blame]
codeworkx62f02ba2012-05-20 12:00:36 +02001/*
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
Daniel Hillenbrand353fecb2012-07-22 16:14:08 +020020#define LOG_NDEBUG 0
21#define LOG_TAG "FimgExynos4"
codeworkx62f02ba2012-05-20 12:00:36 +020022#include <utils/Log.h>
23
24#include "FimgExynos4.h"
25
26namespace android
27{
28Mutex FimgV4x::m_instanceLock;
29unsigned FimgV4x::m_curFimgV4xIndex = 0;
30int FimgV4x::m_numOfInstance = 0;
31FimgApi * FimgV4x::m_ptrFimgApiList[NUMBER_FIMG_LIST] = {NULL, };
32
33//---------------------------------------------------------------------------//
34
35FimgV4x::FimgV4x()
36 : m_g2dFd(0),
37 m_g2dVirtAddr(NULL),
38 m_g2dSize(0),
39 m_g2dSrcVirtAddr(NULL),
40 m_g2dSrcSize(0),
41 m_g2dDstVirtAddr(NULL),
42 m_g2dDstSize(0)
43{
44 memset(&(m_g2dPoll), 0, sizeof(struct pollfd));
45 m_lock = new Mutex(Mutex::SHARED, "FimgV4x");
46}
47
48FimgV4x::~FimgV4x()
49{
50 delete m_lock;
51}
52
53FimgApi *FimgV4x::CreateInstance()
54{
55 Mutex::Autolock autolock(m_instanceLock);
56
57 FimgApi *ptrFimg = NULL;
58
59 for(unsigned int i = m_curFimgV4xIndex; i < NUMBER_FIMG_LIST; i++) {
60 if (m_ptrFimgApiList[i] == NULL)
61 m_ptrFimgApiList[i] = new FimgV4x;
62
63 if (m_ptrFimgApiList[i]->FlagCreate() == false) {
64 if (m_ptrFimgApiList[i]->Create() == false) {
65 PRINT("%s::Create(%d) fail\n", __func__, i);
66 goto CreateInstance_End;
67 }
68 else
69 m_numOfInstance++;
70 }
71
72 if (i < NUMBER_FIMG_LIST - 1)
73 m_curFimgV4xIndex = i + 1;
74 else
75 m_curFimgV4xIndex = 0;
76
77 ptrFimg = m_ptrFimgApiList[i];
78 goto CreateInstance_End;
79 }
80
81CreateInstance_End :
82
83 return ptrFimg;
84}
85
86void FimgV4x::DestroyInstance(FimgApi * ptrFimgApi)
87{
88 Mutex::Autolock autolock(m_instanceLock);
89
90 for(int i = 0; i < NUMBER_FIMG_LIST; i++) {
91 if (m_ptrFimgApiList[i] != NULL && m_ptrFimgApiList[i] == ptrFimgApi) {
92 if (m_ptrFimgApiList[i]->FlagCreate() == true && m_ptrFimgApiList[i]->Destroy() == false) {
93 PRINT("%s::Destroy() fail\n", __func__);
94 } else {
95 FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i];
96 delete tempFimgV4x;
97 m_ptrFimgApiList[i] = NULL;
98
99 m_numOfInstance--;
100 }
101
102 break;
103 }
104 }
105}
106
107void FimgV4x::DestroyAllInstance(void)
108{
109 Mutex::Autolock autolock(m_instanceLock);
110
111 for(int i = 0; i < NUMBER_FIMG_LIST; i++) {
112 if (m_ptrFimgApiList[i] != NULL) {
113 if (m_ptrFimgApiList[i]->FlagCreate() == true
114 && m_ptrFimgApiList[i]->Destroy() == false) {
115 PRINT("%s::Destroy() fail\n", __func__);
116 } else {
117 FimgV4x * tempFimgV4x = (FimgV4x *)m_ptrFimgApiList[i];
118 delete tempFimgV4x;
119 m_ptrFimgApiList[i] = NULL;
120 }
121 }
122 }
123}
124
125bool FimgV4x::t_Create(void)
126{
127 bool ret = true;
128
129 if (m_CreateG2D() == false) {
130 PRINT("%s::m_CreateG2D() fail \n", __func__);
131
132 if (m_DestroyG2D() == false)
133 PRINT("%s::m_DestroyG2D() fail \n", __func__);
134
135 ret = false;
136 }
137
138 return ret;
139}
140
141bool FimgV4x::t_Destroy(void)
142{
143 bool ret = true;
144
145 if (m_DestroyG2D() == false) {
146 PRINT("%s::m_DestroyG2D() fail \n", __func__);
147 ret = false;
148 }
149
150 return ret;
151}
152
153bool FimgV4x::t_Stretch(struct fimg2d_blit *cmd)
154{
155#ifdef CHECK_FIMGV4x_PERFORMANCE
156#define NUM_OF_STEP (10)
157 StopWatch stopWatch("CHECK_FIMGV4x_PERFORMANCE");
158 const char *stopWatchName[NUM_OF_STEP];
159 nsecs_t stopWatchTime[NUM_OF_STEP];
160 int stopWatchIndex = 0;
161#endif // CHECK_FIMGV4x_PERFORMANCE
162
163 if (m_DoG2D(cmd) == false) {
164 goto STRETCH_FAIL;
165 }
166
167#ifdef G2D_NONE_BLOCKING_MODE
168 if (m_PollG2D(&m_g2dPoll) == false)
169 {
170 PRINT("%s::m_PollG2D() fail\n", __func__);
171 goto STRETCH_FAIL;
172 }
173#endif
174
175 #ifdef CHECK_FIMGV4x_PERFORMANCE
176 m_PrintFimgV4xPerformance(src, dst, stopWatchIndex, stopWatchName, stopWatchTime);
177 #endif // CHECK_FIMGV4x_PERFORMANCE
178
179 return true;
180
181STRETCH_FAIL:
182 return false;
183
184}
185
186bool FimgV4x::t_Sync(void)
187{
188 if (m_PollG2D(&m_g2dPoll) == false)
189 {
190 PRINT("%s::m_PollG2D() fail\n", __func__);
191 goto SYNC_FAIL;
192 }
193 return true;
194
195SYNC_FAIL:
196 return false;
197
198}
199
200bool FimgV4x::t_Lock(void)
201{
202 m_lock->lock();
203 return true;
204}
205
206bool FimgV4x::t_UnLock(void)
207{
208 m_lock->unlock();
209 return true;
210}
211
212bool FimgV4x::m_CreateG2D(void)
213{
214 void * mmap_base;
215
216 if (m_g2dFd != 0) {
217 PRINT("%s::m_g2dFd(%d) is not 0 fail\n", __func__, m_g2dFd);
218 return false;
219 }
220
221#ifdef G2D_NONE_BLOCKING_MODE
222 m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR | O_NONBLOCK);
223#else
224 m_g2dFd = open(SEC_G2D_DEV_NAME, O_RDWR);
225#endif
226 if (m_g2dFd < 0) {
227 PRINT("%s::open(%s) fail(%s)\n", __func__, SEC_G2D_DEV_NAME, strerror(errno));
228 m_g2dFd = 0;
229 return false;
230 }
231
232 memset(&m_g2dPoll, 0, sizeof(m_g2dPoll));
233 m_g2dPoll.fd = m_g2dFd;
234 m_g2dPoll.events = POLLOUT | POLLERR;
235
236 return true;
237}
238
239bool FimgV4x::m_DestroyG2D(void)
240{
241 if (m_g2dVirtAddr != NULL) {
242 munmap(m_g2dVirtAddr, m_g2dSize);
243 m_g2dVirtAddr = NULL;
244 m_g2dSize = 0;
245 }
246
247 if (0 < m_g2dFd) {
248 close(m_g2dFd);
249 }
250 m_g2dFd = 0;
251
252 return true;
253}
254
255bool FimgV4x::m_DoG2D(struct fimg2d_blit *cmd)
256{
257
258 if (ioctl(m_g2dFd, FIMG2D_BITBLT_BLIT, cmd) < 0)
259 return false;
260
261 return true;
262}
263
264inline bool FimgV4x::m_PollG2D(struct pollfd * events)
265{
266#define G2D_POLL_TIME (1000)
267
268 int ret;
269
270 ret = poll(events, 1, G2D_POLL_TIME);
271
272 if (ret < 0) {
273 PRINT("%s::poll fail \n", __func__);
274 return false;
275 }
276 else if (ret == 0) {
277 PRINT("%s::No data in %d milli secs..\n", __func__, G2D_POLL_TIME);
278 return false;
279 }
280
281 return true;
282}
283
284//---------------------------------------------------------------------------//
285// extern function
286//---------------------------------------------------------------------------//
287extern "C" struct FimgApi * createFimgApi()
288{
289 if (fimgApiAutoFreeThread == 0)
290 fimgApiAutoFreeThread = new FimgApiAutoFreeThread();
291 else
292 fimgApiAutoFreeThread->SetOneMoreSleep();
293
294 return FimgV4x::CreateInstance();
295}
296
297extern "C" void destroyFimgApi(FimgApi * ptrFimgApi)
298{
299 // Dont' call DestroyInstance.
300}
301
302}; // namespace android