summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qglobal.h4
-rw-r--r--src/gui/egl/qegl_symbian.cpp3
-rw-r--r--src/gui/gui.pro2
-rw-r--r--src/gui/image/image.pri2
-rw-r--r--src/gui/image/qpixmap.h5
-rw-r--r--src/gui/image/qpixmap_s60.cpp58
-rw-r--r--src/gui/image/qpixmapdata.cpp11
-rw-r--r--src/gui/image/qpixmapdata_p.h9
-rw-r--r--src/openvg/qpixmapdata_vg.cpp178
-rw-r--r--src/openvg/qpixmapdata_vg_p.h14
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;