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