src/openvg/qpixmapdata_vg.cpp
changeset 30 5dc02b23752f
parent 22 79de32ba3296
child 33 3e2da88830cd
equal deleted inserted replaced
29:b72c6db6890b 30:5dc02b23752f
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "qpixmapdata_vg_p.h"
    42 #include "qpixmapdata_vg_p.h"
    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 #if !defined(QT_NO_EGL)
       
    46 #include <QtGui/private/qegl_p.h>
       
    47 #endif
    45 #include "qvg_p.h"
    48 #include "qvg_p.h"
    46 #include "qvgimagepool_p.h"
    49 #include "qvgimagepool_p.h"
    47 
    50 
    48 #if defined(Q_OS_SYMBIAN)
    51 #if defined(Q_OS_SYMBIAN)
    49 #include <private/qt_s60_p.h>
    52 #include <private/qt_s60_p.h>
    50 #include <fbs.h>
    53 #include <fbs.h>
    51 #endif
    54 #endif
    52 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
    55 #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE
    53 #include <sgresource/sgimage.h>
    56 #include <sgresource/sgimage.h>
    54 typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*);
       
    55 typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR);
       
    56 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
    57 typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR);
    57 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE
    58 #endif // QT_SYMBIAN_SUPPORTS_SGIMAGE
    58 
    59 
    59 QT_BEGIN_NAMESPACE
    60 QT_BEGIN_NAMESPACE
    60 
    61 
   231     // This is simpler than juggling multiple VG contexts.
   232     // This is simpler than juggling multiple VG contexts.
   232     const_cast<QVGPixmapData *>(this)->forceToImage();
   233     const_cast<QVGPixmapData *>(this)->forceToImage();
   233     return source.paintEngine();
   234     return source.paintEngine();
   234 }
   235 }
   235 
   236 
   236 // This function works around QImage::bits() making a deep copy if the
       
   237 // QImage is not const.  We force it to be const and then get the bits.
       
   238 // XXX: Should add a QImage::constBits() in the future to replace this.
       
   239 const uchar *qt_vg_imageBits(const QImage& image)
       
   240 {
       
   241     return image.bits();
       
   242 }
       
   243 
       
   244 VGImage QVGPixmapData::toVGImage()
   237 VGImage QVGPixmapData::toVGImage()
   245 {
   238 {
   246     if (!isValid())
   239     if (!isValid())
   247         return VG_INVALID_HANDLE;
   240         return VG_INVALID_HANDLE;
   248 
   241 
   271     }
   264     }
   272 
   265 
   273     if (!source.isNull() && recreate) {
   266     if (!source.isNull() && recreate) {
   274         vgImageSubData
   267         vgImageSubData
   275             (vgImage,
   268             (vgImage,
   276              qt_vg_imageBits(source), source.bytesPerLine(),
   269              source.constBits(), source.bytesPerLine(),
   277              VG_sARGB_8888_PRE, 0, 0, w, h);
   270              VG_sARGB_8888_PRE, 0, 0, w, h);
   278     }
   271     }
   279 
   272 
   280     recreate = false;
   273     recreate = false;
   281     prevSize = QSize(w, h);
   274     prevSize = QSize(w, h);
   494             cleanup();
   487             cleanup();
   495             driver.Close();
   488             driver.Close();
   496             return;
   489             return;
   497         }
   490         }
   498 
   491 
   499         pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
       
   500         pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
       
   501         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   492         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   502 
   493 
   503         if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
   494         if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) {
   504             cleanup();
   495             cleanup();
   505             driver.Close();
   496             driver.Close();
   506             return;
   497             return;
   507         }
   498         }
   508 
   499 
   509         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   500         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   510         EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),
   501         EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
   511                 EGL_NO_CONTEXT,
   502                 EGL_NO_CONTEXT,
   512                 EGL_NATIVE_PIXMAP_KHR,
   503                 EGL_NATIVE_PIXMAP_KHR,
   513                 (EGLClientBuffer)sgImage,
   504                 (EGLClientBuffer)sgImage,
   514                 (EGLint*)KEglImageAttribs);
   505                 (EGLint*)KEglImageAttribs);
   515 
   506 
   520         }
   511         }
   521 
   512 
   522         vgImage = vgCreateEGLImageTargetKHR(eglImage);
   513         vgImage = vgCreateEGLImageTargetKHR(eglImage);
   523         if (vgGetError() != VG_NO_ERROR) {
   514         if (vgGetError() != VG_NO_ERROR) {
   524             cleanup();
   515             cleanup();
   525             eglDestroyImageKHR(QEglContext::display(), eglImage);
   516             QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
   526             driver.Close();
   517             driver.Close();
   527             return;
   518             return;
   528         }
   519         }
   529 
   520 
   530         w = sgImageInfo.iSizeInPixels.iWidth;
   521         w = sgImageInfo.iSizeInPixels.iWidth;
   534         source = QImage();
   525         source = QImage();
   535         recreate = false;
   526         recreate = false;
   536         prevSize = QSize(w, h);
   527         prevSize = QSize(w, h);
   537         setSerialNumber(++qt_vg_pixmap_serial);
   528         setSerialNumber(++qt_vg_pixmap_serial);
   538         // release stuff
   529         // release stuff
   539         eglDestroyImageKHR(QEglContext::display(), eglImage);
   530         QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
   540         driver.Close();
   531         driver.Close();
   541 #endif
   532 #endif
   542     } else if (type == QPixmapData::FbsBitmap) {
   533     } else if (type == QPixmapData::FbsBitmap) {
   543         CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
   534         CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap);
   544 
   535 
   612         if (err != KErrNone) {
   603         if (err != KErrNone) {
   613             driver.Close();
   604             driver.Close();
   614             return 0;
   605             return 0;
   615         }
   606         }
   616 
   607 
   617         pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
       
   618         pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
       
   619         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   608         pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR");
   620 
   609 
   621         if (eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) {
   610         if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) {
   622             driver.Close();
   611             driver.Close();
   623             return 0;
   612             return 0;
   624         }
   613         }
   625 
   614 
   626         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   615         const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE};
   627         EGLImageKHR eglImage = eglCreateImageKHR(QEglContext::display(),
   616         EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(),
   628                 EGL_NO_CONTEXT,
   617                 EGL_NO_CONTEXT,
   629                 EGL_NATIVE_PIXMAP_KHR,
   618                 EGL_NATIVE_PIXMAP_KHR,
   630                 (EGLClientBuffer)sgImage,
   619                 (EGLClientBuffer)sgImage,
   631                 (EGLint*)KEglImageAttribs);
   620                 (EGLint*)KEglImageAttribs);
   632         if (eglGetError() != EGL_SUCCESS) {
   621         if (eglGetError() != EGL_SUCCESS) {
   635             return 0;
   624             return 0;
   636         }
   625         }
   637 
   626 
   638         VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
   627         VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage);
   639         if (vgGetError() != VG_NO_ERROR) {
   628         if (vgGetError() != VG_NO_ERROR) {
   640             eglDestroyImageKHR(QEglContext::display(), eglImage);
   629             QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
   641             sgImage->Close();
   630             sgImage->Close();
   642             driver.Close();
   631             driver.Close();
   643             return 0;
   632             return 0;
   644         }
   633         }
   645 
   634 
   651             sgImage->Close();
   640             sgImage->Close();
   652             sgImage = 0;
   641             sgImage = 0;
   653         }
   642         }
   654         // release stuff
   643         // release stuff
   655         vgDestroyImage(dstVgImage);
   644         vgDestroyImage(dstVgImage);
   656         eglDestroyImageKHR(QEglContext::display(), eglImage);
   645         QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
   657         driver.Close();
   646         driver.Close();
   658         return reinterpret_cast<void*>(sgImage);
   647         return reinterpret_cast<void*>(sgImage);
   659 #endif
   648 #endif
   660     } else if (type == QPixmapData::FbsBitmap) {
   649     } else if (type == QPixmapData::FbsBitmap) {
   661         CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
   650         CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap);
   662 
   651 
   663         if (bitmap) {
   652         if (bitmap) {
   664             if (bitmap->Create(TSize(source.width(), source.height()),
   653             if (bitmap->Create(TSize(source.width(), source.height()),
   665                               EColor16MAP) == KErrNone) {
   654                               EColor16MAP) == KErrNone) {
   666                 const uchar *sptr = qt_vg_imageBits(source);
   655                 const uchar *sptr = source.constBits();
   667                 bitmap->BeginDataAccess();
   656                 bitmap->BeginDataAccess();
   668 
   657 
   669                 uchar *dptr = (uchar*)bitmap->DataAddress();
   658                 uchar *dptr = (uchar*)bitmap->DataAddress();
   670                 Mem::Copy(dptr, sptr, source.byteCount());
   659                 Mem::Copy(dptr, sptr, source.byteCount());
   671 
   660