javauis/eswt_qt/org.eclipse.swt/Eclipse_SWT_PI/qt/library/graphics/qt/windowsurfaceimpl_symbian.cpp
changeset 48 e0d6e9bd3ca7
parent 35 85266cc22c7f
child 72 1f0034e370aa
equal deleted inserted replaced
47:f40128debb5d 48:e0d6e9bd3ca7
    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();
   355                 throw GfxException(EGfxErrorIllegalArgument, "Unsupported device type");
   416                 throw GfxException(EGfxErrorIllegalArgument, "Unsupported device type");
   356             }
   417             }
   357             break;
   418             break;
   358         default:
   419         default:
   359             throw GfxException(EGfxErrorIllegalArgument, "Unsupported widget window surface type");
   420             throw GfxException(EGfxErrorIllegalArgument, "Unsupported widget window surface type");
   360             break;
       
   361     }
   421     }
   362     
   422     
   363     // release painter
   423     // release painter
   364     mPainter.end();
   424     mPainter.end();
   365     mMainSurface.qSurface = surface;
   425     mMainSurface.qSurface = surface;