src/openvg/qpixmapdata_vg.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 19 fcece45ef507
equal deleted inserted replaced
3:41300fa6a67c 18:2f34d5167611
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtOpenVG module of the Qt Toolkit.
     7 ** This file is part of the QtOpenVG module of the Qt Toolkit.
     8 **
     8 **
    37 **
    37 **
    38 ** $QT_END_LICENSE$
    38 ** $QT_END_LICENSE$
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
       
    42 #include "../src/gui/egl/qegl_p.h"
    42 #include "qpixmapdata_vg_p.h"
    43 #include "qpixmapdata_vg_p.h"
    43 #include "qpaintengine_vg_p.h"
    44 #include "qpaintengine_vg_p.h"
    44 #include <QtGui/private/qdrawhelper_p.h>
    45 #include <QtGui/private/qdrawhelper_p.h>
    45 #include "qvg_p.h"
    46 #include "qvg_p.h"
    46 #include "qvgimagepool_p.h"
    47 #include "qvgimagepool_p.h"
    47 
    48 
       
    49 #include <private/qt_s60_p.h>
       
    50 #include <fbs.h>
    48 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
    51 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
    49 #include <graphics/sgimage.h>
    52 #include <sgresource/sgimage.h>
    50 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
    53 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
    51 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
    54 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
    52 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
    55 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
    53 #endif
    56 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE
    54 
    57 
    55 QT_BEGIN_NAMESPACE
    58 QT_BEGIN_NAMESPACE
    56 
    59 
    57 static int qt_vg_pixmap_serial = 0;
    60 static int qt_vg_pixmap_serial = 0;
    58 
    61 
   230 }
   233 }
   231 
   234 
   232 // This function works around QImage::bits() making a deep copy if the
   235 // This function works around QImage::bits() making a deep copy if the
   233 // QImage is not const.  We force it to be const and then get the bits.
   236 // QImage is not const.  We force it to be const and then get the bits.
   234 // XXX: Should add a QImage::constBits() in the future to replace this.
   237 // XXX: Should add a QImage::constBits() in the future to replace this.
   235 static inline const uchar *qt_vg_imageBits(const QImage& image)
   238 const uchar *qt_vg_imageBits(const QImage& image)
   236 {
   239 {
   237     return image.bits();
   240     return image.bits();
   238 }
   241 }
   239 
   242 
   240 VGImage QVGPixmapData::toVGImage()
   243 VGImage QVGPixmapData::toVGImage()
   423     }
   426     }
   424     return VG_INVALID_HANDLE;
   427     return VG_INVALID_HANDLE;
   425 }
   428 }
   426 
   429 
   427 #if defined(Q_OS_SYMBIAN)
   430 #if defined(Q_OS_SYMBIAN)
       
   431 
       
   432 static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap)
       
   433 {
       
   434       CFbsBitmap *copy = q_check_ptr(new CFbsBitmap);
       
   435       if(!copy)
       
   436         return 0;
       
   437 
       
   438       if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) {
       
   439           delete copy;
       
   440           copy = 0;
       
   441 
       
   442           return 0;
       
   443       }
       
   444 
       
   445       CFbsBitmapDevice* bitmapDevice = 0;
       
   446       CFbsBitGc *bitmapGc = 0;
       
   447       QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy));
       
   448       QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL());
       
   449       bitmapGc->Activate(bitmapDevice);
       
   450 
       
   451       bitmapGc->BitBlt(TPoint(), bitmap);
       
   452 
       
   453       delete bitmapGc;
       
   454       delete bitmapDevice;
       
   455 
       
   456       return copy;
       
   457 }
       
   458 
   428 void QVGPixmapData::cleanup()
   459 void QVGPixmapData::cleanup()
   429 {
   460 {
   430     is_null = w = h = 0;
   461     is_null = w = h = 0;
   431     recreate = false;
   462     recreate = false;
   432     source = QImage();
   463     source = QImage();
   445         destroyImages();
   476         destroyImages();
   446         prevSize = QSize();
   477         prevSize = QSize();
   447 
   478 
   448         TInt err = 0;
   479         TInt err = 0;
   449 
   480 
   450         err = SgDriver::Open();
   481         RSgDriver driver;
   451         if(err != KErrNone) {
   482         err = driver.Open();
       
   483         if (err != KErrNone) {
   452             cleanup();
   484             cleanup();
   453             return;
   485             return;
   454         }
   486         }
   455 
   487 
   456         if(sgImage->IsNull()) {
   488         if (sgImage->IsNull()) {
   457             cleanup();
   489             cleanup();
   458             SgDriver::Close();
   490             driver.Close();
   459             return;
   491             return;
   460         }
   492         }
   461 
   493 
   462         TSgImageInfo sgImageInfo;
   494         TSgImageInfo sgImageInfo;
   463         err = sgImage->GetInfo(sgImageInfo);
   495         err = sgImage->GetInfo(sgImageInfo);
   464         if(err != KErrNone) {
   496         if (err != KErrNone) {
   465             cleanup();
   497             cleanup();
   466             SgDriver::Close();
   498             driver.Close();
   467             return;
   499             return;
   468         }
   500         }
   469 
   501 
   470         pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
   502         pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
   471         pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
   503         pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
   472         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   504         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   473 
   505 
   474         if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
   506         if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
   475             cleanup();
   507             cleanup();
   476             SgDriver::Close();
   508             driver.Close();
   477             return;
   509             return;
   478         }
   510         }
   479 
   511 
   480         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   512         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   481         EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
   513         EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
   482                 EGL_NO_CONTEXT,
   514                 EGL_NO_CONTEXT,
   483                 EGL_NATIVE_PIXMAP_KHR,
   515                 EGL_NATIVE_PIXMAP_KHR,
   484                 (EGLClientBuffer)sgImage,
   516                 (EGLClientBuffer)sgImage,
   485                 (EGLint*)KEglImageAttribs);
   517                 (EGLint*)KEglImageAttribs);
   486 
   518 
   487         if(eglGetError() != EGL_SUCCESS) {
   519         if (eglGetError() != EGL_SUCCESS) {
   488             cleanup();
   520             cleanup();
   489             SgDriver::Close();
   521             driver.Close();
   490             return;
   522             return;
   491         }
   523         }
   492 
   524 
   493         vgImage = vgCreateEGLImageTargetKHR(eglImage);
   525         vgImage = vgCreateEGLImageTargetKHR(eglImage);
   494         if(vgGetError() != VG_NO_ERROR) {
   526         if (vgGetError() != VG_NO_ERROR) {
   495             cleanup();
   527             cleanup();
   496             eglDestroyImageKHR(context->display(), eglImage);
   528             eglDestroyImageKHR(QEglContext::display(), eglImage);
   497             SgDriver::Close();
   529             driver.Close();
   498             return;
   530             return;
   499         }
   531         }
   500 
   532 
   501         w = sgImageInfo.iSizeInPixels.iWidth;
   533         w = sgImageInfo.iSizeInPixels.iWidth;
   502         h = sgImageInfo.iSizeInPixels.iHeight;
   534         h = sgImageInfo.iSizeInPixels.iHeight;
   505         source = QImage();
   537         source = QImage();
   506         recreate = false;
   538         recreate = false;
   507         prevSize = QSize(w, h);
   539         prevSize = QSize(w, h);
   508         setSerialNumber(++qt_vg_pixmap_serial);
   540         setSerialNumber(++qt_vg_pixmap_serial);
   509         // release stuff
   541         // release stuff
   510         eglDestroyImageKHR(context->display(), eglImage);
   542         eglDestroyImageKHR(QEglContext::display(), eglImage);
   511         SgDriver::Close();
   543         driver.Close();
   512     } else if (type == QPixmapData::FbsBitmap) {
   544     } else if (type == QPixmapData::FbsBitmap) {
   513 
   545         CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
       
   546 
       
   547         bool deleteSourceBitmap = false;
       
   548 
       
   549 #ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
       
   550 
       
   551         // Rasterize extended bitmaps
       
   552 
       
   553         TUid extendedBitmapType = bitmap->ExtendedBitmapType();
       
   554         if (extendedBitmapType != KNullUid) {
       
   555             bitmap = createBlitCopy(bitmap);
       
   556             deleteSourceBitmap = true;
       
   557         }
       
   558 #endif
       
   559 
       
   560         if (bitmap->IsCompressedInRAM()) {
       
   561             bitmap = createBlitCopy(bitmap);
       
   562             deleteSourceBitmap = true;
       
   563         }
       
   564 
       
   565         TDisplayMode displayMode = bitmap->DisplayMode();
       
   566         QImage::Format format = qt_TDisplayMode2Format(displayMode);
       
   567 
       
   568         TSize size = bitmap->SizeInPixels();
       
   569 
       
   570         bitmap->BeginDataAccess();
       
   571         uchar *bytes = (uchar*)bitmap->DataAddress();
       
   572         QImage img = QImage(bytes, size.iWidth, size.iHeight, format);
       
   573         img = img.copy();
       
   574         bitmap->EndDataAccess();
       
   575 
       
   576         if(displayMode == EGray2) {
       
   577             //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid
       
   578             //So invert mono bitmaps so that masks work correctly.
       
   579             img.invertPixels();
       
   580         } else if(displayMode == EColor16M) {
       
   581             img = img.rgbSwapped(); // EColor16M is BGR
       
   582         }
       
   583 
       
   584         fromImage(img, Qt::AutoColor);
       
   585 
       
   586         if(deleteSourceBitmap)
       
   587             delete bitmap;
   514     }
   588     }
   515 #else
   589 #else
   516     Q_UNUSED(pixmap);
   590     Q_UNUSED(pixmap);
   517     Q_UNUSED(type);
   591     Q_UNUSED(type);
   518 #endif
   592 #endif
   522 {
   596 {
   523 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
   597 #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL)
   524     if (type == QPixmapData::SgImage) {
   598     if (type == QPixmapData::SgImage) {
   525         toVGImage();
   599         toVGImage();
   526 
   600 
   527         if(!isValid() || vgImage == VG_INVALID_HANDLE)
   601         if (!isValid() || vgImage == VG_INVALID_HANDLE)
   528             return 0;
   602             return 0;
   529 
   603 
   530         TInt err = 0;
   604         TInt err = 0;
   531 
   605 
   532         err = SgDriver::Open();
   606         RSgDriver driver;
   533         if(err != KErrNone)
   607         err = driver.Open();
       
   608         if (err != KErrNone)
   534             return 0;
   609             return 0;
   535 
   610 
   536         TSgImageInfo sgInfo;
   611         TSgImageInfo sgInfo;
   537         sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
   612         sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE;
   538         sgInfo.iSizeInPixels.SetSize(w, h);
   613         sgInfo.iSizeInPixels.SetSize(w, h);
   539         sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget;
   614         sgInfo.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
   540         sgInfo.iShareable = ETrue;
       
   541         sgInfo.iCpuAccess = ESgCpuAccessNone;
       
   542         sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny;
       
   543         sgInfo.iUserAttributes = NULL;
       
   544         sgInfo.iUserAttributeCount = 0;
       
   545 
   615 
   546         RSgImage *sgImage = q_check_ptr(new RSgImage());
   616         RSgImage *sgImage = q_check_ptr(new RSgImage());
   547         err = sgImage->Create(sgInfo, NULL, NULL);
   617         err = sgImage->Create(sgInfo, NULL, NULL);
   548         if(err != KErrNone) {
   618         if (err != KErrNone) {
   549             SgDriver::Close();
   619             driver.Close();
   550             return 0;
   620             return 0;
   551         }
   621         }
   552 
   622 
   553         pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
   623         pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
   554         pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
   624         pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
   555         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   625         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   556 
   626 
   557         if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
   627         if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
   558             SgDriver::Close();
   628             driver.Close();
   559             return 0;
   629             return 0;
   560         }
   630         }
   561 
   631 
   562         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   632         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   563         EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
   633         EGLImageKHR eglImage = eglCreateImageKHR(context->display(),
   564                 EGL_NO_CONTEXT,
   634                 EGL_NO_CONTEXT,
   565                 EGL_NATIVE_PIXMAP_KHR,
   635                 EGL_NATIVE_PIXMAP_KHR,
   566                 (EGLClientBuffer)sgImage,
   636                 (EGLClientBuffer)sgImage,
   567                 (EGLint*)KEglImageAttribs);
   637                 (EGLint*)KEglImageAttribs);
   568         if(eglGetError() != EGL_SUCCESS) {
   638         if (eglGetError() != EGL_SUCCESS) {
   569             sgImage->Close();
   639             sgImage->Close();
   570             SgDriver::Close();
   640             driver.Close();
   571             return 0;
   641             return 0;
   572         }
   642         }
   573 
   643 
   574         VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
   644         VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
   575         if(vgGetError() != VG_NO_ERROR) {
   645         if (vgGetError() != VG_NO_ERROR) {
   576             eglDestroyImageKHR(context->display(), eglImage);
   646             eglDestroyImageKHR(QEglContext::display(), eglImage);
   577             sgImage->Close();
   647             sgImage->Close();
   578             SgDriver::Close();
   648             driver.Close();
   579             return 0;
   649             return 0;
   580         }
   650         }
   581 
   651 
   582         vgCopyImage(dstVgImage, 0, 0,
   652         vgCopyImage(dstVgImage, 0, 0,
   583                 vgImage, 0, 0,
   653                 vgImage, 0, 0,
   584                 w, h, VG_FALSE);
   654                 w, h, VG_FALSE);
   585 
   655 
   586         if(vgGetError() != VG_NO_ERROR) {
   656         if (vgGetError() != VG_NO_ERROR) {
   587             sgImage->Close();
   657             sgImage->Close();
   588             sgImage = 0;
   658             sgImage = 0;
   589         }
   659         }
   590         // release stuff
   660         // release stuff
   591         vgDestroyImage(dstVgImage);
   661         vgDestroyImage(dstVgImage);
   592         eglDestroyImageKHR(context->display(), eglImage);
   662         eglDestroyImageKHR(QEglContext::display(), eglImage);
   593         SgDriver::Close();
   663         driver.Close();
   594         return reinterpret_cast<void*>(sgImage);
   664         return reinterpret_cast<void*>(sgImage);
   595     } else if (type == QPixmapData::FbsBitmap) {
   665     } else if (type == QPixmapData::FbsBitmap) {
   596         return 0;
   666         CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
       
   667 
       
   668         if (bitmap) {
       
   669             if (bitmap->Create(TSize(source.width(), source.height()),
       
   670                               EColor16MAP) == KErrNone) {
       
   671                 const uchar *sptr = qt_vg_imageBits(source);
       
   672                 bitmap->BeginDataAccess();
       
   673 
       
   674                 uchar *dptr = (uchar*)bitmap->DataAddress();
       
   675                 Mem::Copy(dptr, sptr, source.byteCount());
       
   676 
       
   677                 bitmap->EndDataAccess();
       
   678             } else {
       
   679                 delete bitmap;
       
   680                 bitmap = 0;
       
   681             }
       
   682         }
       
   683 
       
   684         return reinterpret_cast<void*>(bitmap);
   597     }
   685     }
   598 #else
   686 #else
   599     Q_UNUSED(type);
   687     Q_UNUSED(type);
   600     return 0;
   688     return 0;
   601 #endif
   689 #endif