diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/global/qglobal.h | 4 | ||||
-rw-r--r-- | src/gui/egl/qegl_symbian.cpp | 3 | ||||
-rw-r--r-- | src/gui/gui.pro | 2 | ||||
-rw-r--r-- | src/gui/image/image.pri | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap.h | 5 | ||||
-rw-r--r-- | src/gui/image/qpixmap_s60.cpp | 58 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata.cpp | 11 | ||||
-rw-r--r-- | src/gui/image/qpixmapdata_p.h | 9 | ||||
-rw-r--r-- | src/openvg/qpixmapdata_vg.cpp | 178 | ||||
-rw-r--r-- | src/openvg/qpixmapdata_vg_p.h | 14 |
10 files changed, 281 insertions, 5 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 79a253a..e722268 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -820,7 +820,6 @@ namespace QT_NAMESPACE {} # define Q_WS_WIN #endif - QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -2390,8 +2389,11 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); //RWsPointerCursor is fixed, so don't use low performance sprites #define Q_SYMBIAN_FIXED_POINTER_CURSORS #define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE +//enabling new graphics resources +#define QT_SYMBIAN_SUPPORTS_SGIMAGE #endif + //Symbian does not support data imports from a DLL #define Q_NO_DATA_RELOCATION diff --git a/src/gui/egl/qegl_symbian.cpp b/src/gui/egl/qegl_symbian.cpp index 3355f0e..fa0b5cb 100644 --- a/src/gui/egl/qegl_symbian.cpp +++ b/src/gui/egl/qegl_symbian.cpp @@ -98,6 +98,9 @@ EGLDisplay QEglContext::getDisplay(QPaintDevice *device) // Set pixel format and other properties based on a paint device. void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev) { + if(!dev) + return; + int devType = dev->devType(); if (devType == QInternal::Image) setPixelFormat(static_cast<QImage *>(dev)->format()); diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 7c24002..83ac5fe 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -54,4 +54,4 @@ DEFINES += Q_INTERNAL_QAPP_SRC symbian:TARGET.UID3=0x2001B2DD # ro-section in gui can exceed default allocated space, so more rw-section little further -symbian-sbsv2: MMP_RULES += "LINKEROPTION armcc --rw-base 0x800000" +symbian-sbsv2: MMP_RULES += "LINKEROPTION armcc --rw-base 0x800000"
\ No newline at end of file diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri index f365f66..b67be55 100644 --- a/src/gui/image/image.pri +++ b/src/gui/image/image.pri @@ -24,7 +24,7 @@ HEADERS += \ image/qpixmap.h \ image/qpixmap_raster_p.h \ image/qpixmapcache.h \ - image/qpixmapcache_p.h \ + image/qpixmapcache_p.h \ image/qpixmapdata_p.h \ image/qpixmapdatafactory_p.h \ image/qpixmapfilter_p.h \ diff --git a/src/gui/image/qpixmap.h b/src/gui/image/qpixmap.h index 4a8a876..54e89ff 100644 --- a/src/gui/image/qpixmap.h +++ b/src/gui/image/qpixmap.h @@ -54,6 +54,7 @@ QT_BEGIN_HEADER #if defined(Q_OS_SYMBIAN) class CFbsBitmap; +class RSgImage; #endif QT_BEGIN_NAMESPACE @@ -158,9 +159,11 @@ public: #if defined(Q_OS_SYMBIAN) enum ConversionMode { CopyData, DuplicateHandle }; - + CFbsBitmap *toSymbianCFbsBitmap(ConversionMode mode = DuplicateHandle) const; static QPixmap fromSymbianCFbsBitmap(CFbsBitmap *bitmap, ConversionMode mode = DuplicateHandle); + RSgImage* toSymbianRSgImage() const; + static QPixmap fromSymbianRSgImage(RSgImage *sgImage); #endif inline QPixmap copy(int x, int y, int width, int height) const; diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 8a6ecb0..0a81ebd 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -42,6 +42,8 @@ #include <w32std.h> #include <fbs.h> +#include <private/qapplication_p.h> +#include <private/qgraphicssystem_p.h> #include <private/qt_s60_p.h> #include <private/qpaintengine_s60_p.h> @@ -895,5 +897,61 @@ void QS60PixmapData::endDataAccess(bool readOnly) const symbianBitmapDataAccess->endDataAccess(cfbsBitmap); } +/*! + \since 4.6 + + Returns a QPixmap that wraps given \c RSgImage \a graphics resource. + The data should be valid even when original RSgImage handle has been + closed. + + \warning This function is only available on Symbian OS. + + \sa toSymbianRSgImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion} +*/ + +QPixmap QPixmap::fromSymbianRSgImage(RSgImage *sgImage) +{ + // It is expected that RSgImage will + // CURRENTLY be used in conjuction with + // OpenVG graphics system + // + // Surely things might change in future + + if (!sgImage) + return QPixmap(); + + QPixmap pixmap; + pixmap.pixmapData()->fromRSgImage(sgImage); + + return pixmap; +} + +/*! +\since 4.6 + +Returns a \c RSgImage that is equivalent to the QPixmap by copying the data. + +It is the caller's responsibility to close/delete the \c RSgImage after use. + +\warning This function is only available on Symbian OS. + +\sa fromSymbianRSgImage() +*/ + +RSgImage *QPixmap::toSymbianRSgImage() const +{ + // It is expected that RSgImage will + // CURRENTLY be used in conjuction with + // OpenVG graphics system + // + // Surely things might change in future + + if (isNull()) + return 0; + + RSgImage *sgImage = pixmapData()->toRSgImage(); + + return sgImage; +} QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index 8ce5447..65899a4 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -223,4 +223,15 @@ QImage* QPixmapData::buffer() return 0; } +#if defined(Q_OS_SYMBIAN) +RSgImage* QPixmapData::toRSgImage() +{ + return 0; +} + +void QPixmapData::fromRSgImage(RSgImage* rsgImage) +{ + return; +} +#endif QT_END_NAMESPACE diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index 0af2af8..bac5065 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -56,6 +56,10 @@ #include <QtGui/qpixmap.h> #include <QtCore/qatomic.h> +#if defined(Q_OS_SYMBIAN) +class RSgImage; +#endif + QT_BEGIN_NAMESPACE class Q_GUI_EXPORT QPixmapData @@ -109,6 +113,11 @@ public: inline int depth() const { return d; } inline bool isNull() const { return is_null; } +#if defined(Q_OS_SYMBIAN) + virtual RSgImage* toRSgImage(); + virtual void fromRSgImage(RSgImage* rsgImage); +#endif + protected: void setSerialNumber(int serNo); int w; diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index 03e4a35..53975d7 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -44,6 +44,13 @@ #include <QtGui/private/qdrawhelper_p.h> #include "qvg_p.h" +#ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE +#include <graphics/sgimage.h> +typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); +typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); +typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); +#endif + QT_BEGIN_NAMESPACE static int qt_vg_pixmap_serial = 0; @@ -366,4 +373,175 @@ Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap) return VG_INVALID_HANDLE; } +#if defined(Q_OS_SYMBIAN) +void QVGPixmapData::cleanup() +{ + is_null = w = h = 0; + recreate = false; + source = QImage(); +} + +void QVGPixmapData::fromRSgImage(RSgImage* sgImage) +{ + Q_UNUSED(sgImage); +#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) + // when "0" used as argument then + // default display, context are used + if (!context) + context = qt_vg_create_context(0); + + if (vgImage != VG_INVALID_HANDLE) { + vgDestroyImage(vgImage); + vgImage = VG_INVALID_HANDLE; + } + if (vgImageOpacity != VG_INVALID_HANDLE) { + vgDestroyImage(vgImageOpacity); + vgImageOpacity = VG_INVALID_HANDLE; + } + + TInt err = 0; + + err = SgDriver::Open(); + if(err != KErrNone) { + cleanup(); + return; + } + + if(sgImage->IsNull()) { + cleanup(); + SgDriver::Close(); + return; + } + + TSgImageInfo sgImageInfo; + err = sgImage->GetInfo(sgImageInfo); + if(err != KErrNone) { + cleanup(); + SgDriver::Close(); + return; + } + + pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); + pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); + pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); + + if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + cleanup(); + SgDriver::Close(); + return; + } + + const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; + EGLImageKHR eglImage = eglCreateImageKHR(context->display(), + EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)sgImage, + (EGLint*)KEglImageAttribs); + + if(eglGetError() != EGL_SUCCESS) { + cleanup(); + SgDriver::Close(); + return; + } + + vgImage = vgCreateEGLImageTargetKHR(eglImage); + if(vgGetError() != VG_NO_ERROR) { + cleanup(); + eglDestroyImageKHR(context->display(), eglImage); + SgDriver::Close(); + return; + } + + w = sgImageInfo.iSizeInPixels.iWidth; + h = sgImageInfo.iSizeInPixels.iHeight; + d = 32; // We always use ARGB_Premultiplied for VG pixmaps. + is_null = (w <= 0 || h <= 0); + source = QImage(); + recreate = false; + setSerialNumber(++qt_vg_pixmap_serial); + // release stuff + eglDestroyImageKHR(context->display(), eglImage); + SgDriver::Close(); +#else +#endif +} + +RSgImage* QVGPixmapData::toRSgImage() +{ +#if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) + toVGImage(); + + if(!isValid() || vgImage == VG_INVALID_HANDLE) + return 0; + + TInt err = 0; + + err = SgDriver::Open(); + if(err != KErrNone) + return 0; + + TSgImageInfo sgInfo; + sgInfo.iPixelFormat = EUidPixelFormatARGB_8888_PRE; + sgInfo.iSizeInPixels.SetSize(w, h); + sgInfo.iUsage = ESgUsageOpenVgImage | ESgUsageOpenVgTarget; + sgInfo.iShareable = ETrue; + sgInfo.iCpuAccess = ESgCpuAccessNone; + sgInfo.iScreenId = KSgScreenIdMain; //KSgScreenIdAny; + sgInfo.iUserAttributes = NULL; + sgInfo.iUserAttributeCount = 0; + + RSgImage *sgImage = q_check_ptr(new RSgImage()); + err = sgImage->Create(sgInfo, NULL, NULL); + if(err != KErrNone) { + SgDriver::Close(); + return 0; + } + + pfnEglCreateImageKHR eglCreateImageKHR = (pfnEglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR"); + pfnEglDestroyImageKHR eglDestroyImageKHR = (pfnEglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR"); + pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); + + if(eglGetError() != EGL_SUCCESS || !eglCreateImageKHR || !eglDestroyImageKHR || !vgCreateEGLImageTargetKHR) { + SgDriver::Close(); + return 0; + } + + const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; + EGLImageKHR eglImage = eglCreateImageKHR(context->display(), + EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer)sgImage, + (EGLint*)KEglImageAttribs); + if(eglGetError() != EGL_SUCCESS) { + sgImage->Close(); + SgDriver::Close(); + return 0; + } + + VGImage dstVgImage = vgCreateEGLImageTargetKHR(eglImage); + if(vgGetError() != VG_NO_ERROR) { + eglDestroyImageKHR(context->display(), eglImage); + sgImage->Close(); + SgDriver::Close(); + return 0; + } + + vgCopyImage(dstVgImage, 0, 0, + vgImage, 0, 0, + w, h, VG_FALSE); + + if(vgGetError() != VG_NO_ERROR) { + sgImage->Close(); + sgImage = 0; + } + // release stuff + vgDestroyImage(dstVgImage); + eglDestroyImageKHR(context->display(), eglImage); + SgDriver::Close(); + return sgImage; +#else + return 0; +#endif +} +#endif //Q_OS_SYMBIAN QT_END_NAMESPACE diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h index 9bb701b..122f596 100644 --- a/src/openvg/qpixmapdata_vg_p.h +++ b/src/openvg/qpixmapdata_vg_p.h @@ -56,7 +56,10 @@ #include <QtGui/private/qpixmap_raster_p.h> #include <private/qvg_p.h> #if !defined(QT_NO_EGL) -#include <QtGui/private/qegl_p.h> +#endif + +#if defined(Q_OS_SYMBIAN) +class RSGImage; #endif QT_BEGIN_NAMESPACE @@ -91,9 +94,18 @@ public: QSize size() const { return QSize(w, h); } +#if defined(Q_OS_SYMBIAN) + RSgImage* toRSgImage(); + void fromRSgImage(RSgImage* sgImage); +#endif + protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; +#if defined(Q_OS_SYMBIAN) + void cleanup(); +#endif + private: VGImage vgImage; VGImage vgImageOpacity; |