--- a/javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/windowsurfaceimpl_symbian.cpp Wed Jun 23 18:07:10 2010 +0300
+++ b/javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/windowsurfaceimpl_symbian.cpp Tue Jul 06 14:10:26 2010 +0300
@@ -13,6 +13,8 @@
#include <QWidget>
#include <QPainter>
#include <QPaintEngine>
+#include <fbs.h>
+#include <coemain.h>
#include "windowsurfaceimpl_symbian.h"
#include "gfxlog.h"
@@ -21,6 +23,7 @@
WindowSurfaceImpl::WindowSurfaceImpl(QPaintDevice* aSurface, WindowSurfaceType aType)
: mIsBound(false),
mBufferedRendering(false),
+ mPreserveLocalSurface(false),
mAutoRefresh(false),
mPaintingStarted(false)
{
@@ -32,6 +35,7 @@
WindowSurfaceImpl::WindowSurfaceImpl(QWidget* aWidget, bool aAutoRefresh)
: mIsBound(false),
mBufferedRendering(false),
+ mPreserveLocalSurface(false),
mAutoRefresh(false),
mPaintingStarted(false)
{
@@ -49,11 +53,7 @@
WindowSurfaceImpl::~WindowSurfaceImpl()
{
GFX_LOG_FUNC_CALL();
- if(mMainSurface.localSurface != NULL)
- {
- delete mMainSurface.localSurface;
- mMainSurface.localSurface = NULL;
- }
+ deleteLocalSurface();
}
void WindowSurfaceImpl::beginPaint(int aX, int aY, int aWidth, int aHeight)
@@ -68,11 +68,10 @@
mMainSurface.qSurface->beginPaint(region);
// In case local surface was used last round
// and we now have Qt's window surface again
- // delete the local surface to save memory
- if(mMainSurface.localSurface != NULL)
- {
- delete mMainSurface.localSurface;
- mMainSurface.localSurface = NULL;
+ // delete the local surface to save memory,
+ if(!mPreserveLocalSurface)
+ {
+ deleteLocalSurface();
}
}
mPaintingStarted = true;
@@ -102,23 +101,27 @@
// Bind is not allowed if beginPaint has not been called
if(!mPaintingStarted)
{
- throw GfxException(EGfxErrorIllegalState, "beginPaint() not called before bind()");
+ return;
}
switch (mMainSurface.type)
{
case WsTypeQtImage:
{
- mBufferedRendering = true;
break;
}
-
case WsTypeEglSurface:
{
// If caller does not support EGL surface
- // create temp buffer to be used as target and
- // copy pixels from window surface to temp buffer
+ // create local surface to be used as target and
+ // copy pixels from window surface to local surface
if ((aCapabilies & WsTypeEglSurface) == 0) {
+ if(!isLocalSurfaceValid())
+ {
+ createLocalSurface();
+ }
+ mBufferedRendering = true;
+ mPreserveLocalSurface = true;
// TODO copy pixels from EGL surface to
// QImage created here
@@ -144,7 +147,15 @@
int WindowSurfaceImpl::getType()
{
GFX_LOG_FUNC_CALL();
- return mMainSurface.type;
+ if(mBufferedRendering)
+ {
+ // only supported local buffer is QImage
+ return WsTypeQtImage;
+ }
+ else
+ {
+ return mMainSurface.type;
+ }
}
QPaintDevice* WindowSurfaceImpl::getDevice()
@@ -186,9 +197,15 @@
return;
}
+ // this means that we are using localSurface
+ // as intermediate buffer for caller due to
+ // lacking support for the actual surface type
if (mBufferedRendering)
{
- // TODO draw QImage with painter to actual target
+ mPainter.begin(mMainSurface.device);
+ mPainter.drawImage(QPoint(0,0),*mMainSurface.localSurface);
+ mPainter.end();
+ mBufferedRendering = false;
}
else
{
@@ -208,6 +225,42 @@
delete this;
}
+void WindowSurfaceImpl::handleSymbianWindowVisibilityChange(bool aVisible)
+{
+ if(mPaintingStarted)
+ {
+ // TODO window getting invisible in the middle of paint
+ return;
+ }
+
+ if (!aVisible)
+ {
+ // Switch to sw rendering
+ if(!isLocalSurfaceValid())
+ {
+ if(mMainSurface.localSurfaceInUse)
+ {
+ deleteLocalSurface();
+ }
+
+ CFbsBitmap* bitmap = new(ELeave) CFbsBitmap;
+ CleanupStack::PushL(bitmap);
+ int err = bitmap->Create(TSize(mMainSurface.widget->width(), mMainSurface.widget->height()),
+ CCoeEnv::Static()->ScreenDevice()->DisplayMode());
+ eglCopyBuffers(mEgl.display, mEgl.readSurface, bitmap);
+ mMainSurface.localSurface = new QImage(QPixmap::fromSymbianCFbsBitmap(bitmap).toImage());
+ CleanupStack::Pop(bitmap);
+
+ mMainSurface.qSurface = NULL;
+ mMainSurface.device = mMainSurface.localSurface;
+ mMainSurface.type = WsTypeQtImage;
+ mMainSurface.localSurfaceInUse = true;
+ }
+ }
+
+ // Otherwise updateSurfaceData() will switch back to hw rendering
+}
+
void WindowSurfaceImpl::saveEglState()
{
// Some painter needs to be active on the device
@@ -239,9 +292,9 @@
// Private methods
-void WindowSurfaceImpl::createLocalSurface(int aWidth, int aHeight)
+void WindowSurfaceImpl::createLocalSurface()
{
- mMainSurface.localSurface = new QImage(aWidth, aHeight, QImage::Format_ARGB32);
+ mMainSurface.localSurface = new QImage(mMainSurface.widget->width(), mMainSurface.widget->height(), QImage::Format_RGB32/*QImage::Format_ARGB32*/);
if(mMainSurface.localSurface->isNull())
{
throw GfxException(EGfxErrorNoMemory, "Local Surface creation failed");
@@ -281,14 +334,14 @@
if(mPaintingStarted)
{
return;
- }
+ }
QWindowSurface* surface = mMainSurface.widget->windowSurface();
// If window surface is null it means that the widget has been
// sent to background and widget's window surface has been deleted,
// in such case create own QImage as local surface in order to support
// rendering in background
- if(surface == NULL || surface == 0)
+ if(surface == NULL)
{
// check if we already have local surface with valid size
if(!isLocalSurfaceValid())
@@ -299,7 +352,7 @@
{
deleteLocalSurface();
}
- createLocalSurface(mMainSurface.widget->width(), mMainSurface.widget->height());
+ createLocalSurface();
// set info
mMainSurface.qSurface = NULL;
mMainSurface.device = mMainSurface.localSurface;
@@ -319,7 +372,15 @@
// delete it as it's not used anymore
if(mMainSurface.localSurfaceInUse)
{
- deleteLocalSurface();
+ // in case we have needed the local surface as temp
+ // buffer for a client, it is not deleted as we most likely
+ // will need it again. In any case the local surface
+ // stops to be the main surface and is atleast demoted to
+ // temp surface.
+ if(!mPreserveLocalSurface)
+ {
+ deleteLocalSurface();
+ }
}
}
@@ -357,7 +418,6 @@
break;
default:
throw GfxException(EGfxErrorIllegalArgument, "Unsupported widget window surface type");
- break;
}
// release painter