11 |
11 |
12 //#include <QtOpenGL> |
12 //#include <QtOpenGL> |
13 #include <QWidget> |
13 #include <QWidget> |
14 #include <QPainter> |
14 #include <QPainter> |
15 #include <QPaintEngine> |
15 #include <QPaintEngine> |
|
16 #include <fbs.h> |
|
17 #include <coemain.h> |
16 #include "windowsurfaceimpl_symbian.h" |
18 #include "windowsurfaceimpl_symbian.h" |
17 #include "gfxlog.h" |
19 #include "gfxlog.h" |
18 |
20 |
19 namespace Java { namespace GFX { |
21 namespace Java { namespace GFX { |
20 |
22 |
21 WindowSurfaceImpl::WindowSurfaceImpl(QPaintDevice* aSurface, WindowSurfaceType aType) |
23 WindowSurfaceImpl::WindowSurfaceImpl(QPaintDevice* aSurface, WindowSurfaceType aType) |
22 : mIsBound(false), |
24 : mIsBound(false), |
23 mBufferedRendering(false), |
25 mBufferedRendering(false), |
|
26 mPreserveLocalSurface(false), |
24 mAutoRefresh(false), |
27 mAutoRefresh(false), |
25 mPaintingStarted(false) |
28 mPaintingStarted(false) |
26 { |
29 { |
27 GFX_LOG_FUNC_CALL(); |
30 GFX_LOG_FUNC_CALL(); |
28 mMainSurface.device = aSurface; |
31 mMainSurface.device = aSurface; |
30 } |
33 } |
31 |
34 |
32 WindowSurfaceImpl::WindowSurfaceImpl(QWidget* aWidget, bool aAutoRefresh) |
35 WindowSurfaceImpl::WindowSurfaceImpl(QWidget* aWidget, bool aAutoRefresh) |
33 : mIsBound(false), |
36 : mIsBound(false), |
34 mBufferedRendering(false), |
37 mBufferedRendering(false), |
|
38 mPreserveLocalSurface(false), |
35 mAutoRefresh(false), |
39 mAutoRefresh(false), |
36 mPaintingStarted(false) |
40 mPaintingStarted(false) |
37 { |
41 { |
38 GFX_LOG_FUNC_CALL(); |
42 GFX_LOG_FUNC_CALL(); |
39 if(aWidget == NULL) |
43 if(aWidget == NULL) |
47 |
51 |
48 |
52 |
49 WindowSurfaceImpl::~WindowSurfaceImpl() |
53 WindowSurfaceImpl::~WindowSurfaceImpl() |
50 { |
54 { |
51 GFX_LOG_FUNC_CALL(); |
55 GFX_LOG_FUNC_CALL(); |
52 if(mMainSurface.localSurface != NULL) |
56 deleteLocalSurface(); |
53 { |
|
54 delete mMainSurface.localSurface; |
|
55 mMainSurface.localSurface = NULL; |
|
56 } |
|
57 } |
57 } |
58 |
58 |
59 void WindowSurfaceImpl::beginPaint(int aX, int aY, int aWidth, int aHeight) |
59 void WindowSurfaceImpl::beginPaint(int aX, int aY, int aWidth, int aHeight) |
60 { |
60 { |
61 if(mAutoRefresh && (mMainSurface.widget != NULL)) |
61 if(mAutoRefresh && (mMainSurface.widget != NULL)) |
66 { |
66 { |
67 QRegion region(aX, aY, aWidth, aHeight); |
67 QRegion region(aX, aY, aWidth, aHeight); |
68 mMainSurface.qSurface->beginPaint(region); |
68 mMainSurface.qSurface->beginPaint(region); |
69 // In case local surface was used last round |
69 // In case local surface was used last round |
70 // and we now have Qt's window surface again |
70 // and we now have Qt's window surface again |
71 // delete the local surface to save memory |
71 // delete the local surface to save memory, |
72 if(mMainSurface.localSurface != NULL) |
72 if(!mPreserveLocalSurface) |
73 { |
73 { |
74 delete mMainSurface.localSurface; |
74 deleteLocalSurface(); |
75 mMainSurface.localSurface = NULL; |
|
76 } |
75 } |
77 } |
76 } |
78 mPaintingStarted = true; |
77 mPaintingStarted = true; |
79 } |
78 } |
80 |
79 |
100 { |
99 { |
101 GFX_LOG_FUNC_CALL(); |
100 GFX_LOG_FUNC_CALL(); |
102 // Bind is not allowed if beginPaint has not been called |
101 // Bind is not allowed if beginPaint has not been called |
103 if(!mPaintingStarted) |
102 if(!mPaintingStarted) |
104 { |
103 { |
105 throw GfxException(EGfxErrorIllegalState, "beginPaint() not called before bind()"); |
104 return; |
106 } |
105 } |
107 |
106 |
108 switch (mMainSurface.type) |
107 switch (mMainSurface.type) |
109 { |
108 { |
110 case WsTypeQtImage: |
109 case WsTypeQtImage: |
111 { |
110 { |
112 mBufferedRendering = true; |
|
113 break; |
111 break; |
114 } |
112 } |
115 |
|
116 case WsTypeEglSurface: |
113 case WsTypeEglSurface: |
117 { |
114 { |
118 // If caller does not support EGL surface |
115 // If caller does not support EGL surface |
119 // create temp buffer to be used as target and |
116 // create local surface to be used as target and |
120 // copy pixels from window surface to temp buffer |
117 // copy pixels from window surface to local surface |
121 if ((aCapabilies & WsTypeEglSurface) == 0) { |
118 if ((aCapabilies & WsTypeEglSurface) == 0) { |
|
119 if(!isLocalSurfaceValid()) |
|
120 { |
|
121 createLocalSurface(); |
|
122 } |
|
123 mBufferedRendering = true; |
|
124 mPreserveLocalSurface = true; |
122 // TODO copy pixels from EGL surface to |
125 // TODO copy pixels from EGL surface to |
123 // QImage created here |
126 // QImage created here |
124 |
127 |
125 } else { |
128 } else { |
126 // Caller supports EGL surface, so just |
129 // Caller supports EGL surface, so just |
142 } |
145 } |
143 |
146 |
144 int WindowSurfaceImpl::getType() |
147 int WindowSurfaceImpl::getType() |
145 { |
148 { |
146 GFX_LOG_FUNC_CALL(); |
149 GFX_LOG_FUNC_CALL(); |
147 return mMainSurface.type; |
150 if(mBufferedRendering) |
|
151 { |
|
152 // only supported local buffer is QImage |
|
153 return WsTypeQtImage; |
|
154 } |
|
155 else |
|
156 { |
|
157 return mMainSurface.type; |
|
158 } |
148 } |
159 } |
149 |
160 |
150 QPaintDevice* WindowSurfaceImpl::getDevice() |
161 QPaintDevice* WindowSurfaceImpl::getDevice() |
151 { |
162 { |
152 return mMainSurface.device; |
163 return mMainSurface.device; |
184 if (!mIsBound) |
195 if (!mIsBound) |
185 { |
196 { |
186 return; |
197 return; |
187 } |
198 } |
188 |
199 |
|
200 // this means that we are using localSurface |
|
201 // as intermediate buffer for caller due to |
|
202 // lacking support for the actual surface type |
189 if (mBufferedRendering) |
203 if (mBufferedRendering) |
190 { |
204 { |
191 // TODO draw QImage with painter to actual target |
205 mPainter.begin(mMainSurface.device); |
|
206 mPainter.drawImage(QPoint(0,0),*mMainSurface.localSurface); |
|
207 mPainter.end(); |
|
208 mBufferedRendering = false; |
192 } |
209 } |
193 else |
210 else |
194 { |
211 { |
195 if(mMainSurface.type == WsTypeEglSurface) |
212 if(mMainSurface.type == WsTypeEglSurface) |
196 { |
213 { |
204 |
221 |
205 void WindowSurfaceImpl::dispose() |
222 void WindowSurfaceImpl::dispose() |
206 { |
223 { |
207 GFX_LOG_FUNC_CALL(); |
224 GFX_LOG_FUNC_CALL(); |
208 delete this; |
225 delete this; |
|
226 } |
|
227 |
|
228 void WindowSurfaceImpl::handleSymbianWindowVisibilityChange(bool aVisible) |
|
229 { |
|
230 if(mPaintingStarted) |
|
231 { |
|
232 // TODO window getting invisible in the middle of paint |
|
233 return; |
|
234 } |
|
235 |
|
236 if (!aVisible) |
|
237 { |
|
238 // Switch to sw rendering |
|
239 if(!isLocalSurfaceValid()) |
|
240 { |
|
241 if(mMainSurface.localSurfaceInUse) |
|
242 { |
|
243 deleteLocalSurface(); |
|
244 } |
|
245 |
|
246 CFbsBitmap* bitmap = new(ELeave) CFbsBitmap; |
|
247 CleanupStack::PushL(bitmap); |
|
248 int err = bitmap->Create(TSize(mMainSurface.widget->width(), mMainSurface.widget->height()), |
|
249 CCoeEnv::Static()->ScreenDevice()->DisplayMode()); |
|
250 eglCopyBuffers(mEgl.display, mEgl.readSurface, bitmap); |
|
251 mMainSurface.localSurface = new QImage(QPixmap::fromSymbianCFbsBitmap(bitmap).toImage()); |
|
252 CleanupStack::Pop(bitmap); |
|
253 |
|
254 mMainSurface.qSurface = NULL; |
|
255 mMainSurface.device = mMainSurface.localSurface; |
|
256 mMainSurface.type = WsTypeQtImage; |
|
257 mMainSurface.localSurfaceInUse = true; |
|
258 } |
|
259 } |
|
260 |
|
261 // Otherwise updateSurfaceData() will switch back to hw rendering |
209 } |
262 } |
210 |
263 |
211 void WindowSurfaceImpl::saveEglState() |
264 void WindowSurfaceImpl::saveEglState() |
212 { |
265 { |
213 // Some painter needs to be active on the device |
266 // Some painter needs to be active on the device |
237 } |
290 } |
238 } |
291 } |
239 |
292 |
240 // Private methods |
293 // Private methods |
241 |
294 |
242 void WindowSurfaceImpl::createLocalSurface(int aWidth, int aHeight) |
295 void WindowSurfaceImpl::createLocalSurface() |
243 { |
296 { |
244 mMainSurface.localSurface = new QImage(aWidth, aHeight, QImage::Format_ARGB32); |
297 mMainSurface.localSurface = new QImage(mMainSurface.widget->width(), mMainSurface.widget->height(), QImage::Format_RGB32/*QImage::Format_ARGB32*/); |
245 if(mMainSurface.localSurface->isNull()) |
298 if(mMainSurface.localSurface->isNull()) |
246 { |
299 { |
247 throw GfxException(EGfxErrorNoMemory, "Local Surface creation failed"); |
300 throw GfxException(EGfxErrorNoMemory, "Local Surface creation failed"); |
248 } |
301 } |
249 } |
302 } |
279 // If painting is active, i.e. beginPaint has been called |
332 // If painting is active, i.e. beginPaint has been called |
280 // surface data is not updated |
333 // surface data is not updated |
281 if(mPaintingStarted) |
334 if(mPaintingStarted) |
282 { |
335 { |
283 return; |
336 return; |
284 } |
337 } |
285 QWindowSurface* surface = mMainSurface.widget->windowSurface(); |
338 QWindowSurface* surface = mMainSurface.widget->windowSurface(); |
286 |
339 |
287 // If window surface is null it means that the widget has been |
340 // If window surface is null it means that the widget has been |
288 // sent to background and widget's window surface has been deleted, |
341 // sent to background and widget's window surface has been deleted, |
289 // in such case create own QImage as local surface in order to support |
342 // in such case create own QImage as local surface in order to support |
290 // rendering in background |
343 // rendering in background |
291 if(surface == NULL || surface == 0) |
344 if(surface == NULL) |
292 { |
345 { |
293 // check if we already have local surface with valid size |
346 // check if we already have local surface with valid size |
294 if(!isLocalSurfaceValid()) |
347 if(!isLocalSurfaceValid()) |
295 { |
348 { |
296 // incase we have invalid surface delete the current one |
349 // incase we have invalid surface delete the current one |
297 // and create new |
350 // and create new |
298 if(mMainSurface.localSurfaceInUse) |
351 if(mMainSurface.localSurfaceInUse) |
299 { |
352 { |
300 deleteLocalSurface(); |
353 deleteLocalSurface(); |
301 } |
354 } |
302 createLocalSurface(mMainSurface.widget->width(), mMainSurface.widget->height()); |
355 createLocalSurface(); |
303 // set info |
356 // set info |
304 mMainSurface.qSurface = NULL; |
357 mMainSurface.qSurface = NULL; |
305 mMainSurface.device = mMainSurface.localSurface; |
358 mMainSurface.device = mMainSurface.localSurface; |
306 mMainSurface.type = WsTypeQtImage; |
359 mMainSurface.type = WsTypeQtImage; |
307 mMainSurface.localSurfaceInUse = true; |
360 mMainSurface.localSurfaceInUse = true; |
317 { |
370 { |
318 // We got Qt's window surface, so in case we had local surface in use |
371 // We got Qt's window surface, so in case we had local surface in use |
319 // delete it as it's not used anymore |
372 // delete it as it's not used anymore |
320 if(mMainSurface.localSurfaceInUse) |
373 if(mMainSurface.localSurfaceInUse) |
321 { |
374 { |
322 deleteLocalSurface(); |
375 // in case we have needed the local surface as temp |
|
376 // buffer for a client, it is not deleted as we most likely |
|
377 // will need it again. In any case the local surface |
|
378 // stops to be the main surface and is atleast demoted to |
|
379 // temp surface. |
|
380 if(!mPreserveLocalSurface) |
|
381 { |
|
382 deleteLocalSurface(); |
|
383 } |
323 } |
384 } |
324 } |
385 } |
325 |
386 |
326 // We got window surface so extract information |
387 // We got window surface so extract information |
327 QPaintDevice* device = surface->paintDevice(); |
388 QPaintDevice* device = surface->paintDevice(); |