summaryrefslogtreecommitdiffstats
path: root/src/openvg
diff options
context:
space:
mode:
authorAleksandar Sasha Babic <aleksandar.babic@nokia.com>2009-09-18 14:11:05 +0200
committerAleksandar Sasha Babic <aleksandar.babic@nokia.com>2009-09-18 14:16:30 +0200
commitad32d9a2d2c3b1202867f8563a69afb93effecd0 (patch)
tree371f84075a5c21e664a461ccc3f7db2fc7b320a9 /src/openvg
parentdf062a2df4e9a438b6e876801cbd04a7cab7a569 (diff)
Adding support for symbian graphics resources.
This enables us to convert from and to new Symbian type of graphics resource, namely SgImage. This only supported with the OpenVG graphics system. On other graphics systems this will return null QPixmap. Conflicts: src/corelib/global/qglobal.h src/gui/image/qpixmap.h src/gui/image/qpixmap_s60.cpp Reviewed-by: Jason Barron
Diffstat (limited to 'src/openvg')
-rw-r--r--src/openvg/qpixmapdata_vg.cpp178
-rw-r--r--src/openvg/qpixmapdata_vg_p.h14
2 files changed, 191 insertions, 1 deletions
diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp
index 03e4a35c44..53975d739c 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 9bb701bbca..122f596884 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;