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