summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2010-09-06 06:58:18 (GMT)
committerSamuel Rødal <samuel.rodal@nokia.com>2010-09-10 10:44:54 (GMT)
commit1c109b9e504b4b51707c97f443be49c88720b386 (patch)
treee7c73083f428930113c6ad90bd1470e329d06afa /src/plugins
parenta9bf68d69d30fc44264f09a75f5e33431bdf4616 (diff)
downloadQt-1c109b9e504b4b51707c97f443be49c88720b386.zip
Qt-1c109b9e504b4b51707c97f443be49c88720b386.tar.gz
Qt-1c109b9e504b4b51707c97f443be49c88720b386.tar.bz2
Imported meego graphics system sources.
From http://www.gitorious.com/meego-graphics/meego-graphics
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/graphicssystems/meego/meegographicssystem.pro12
-rw-r--r--src/plugins/graphicssystems/meego/mextensions.cpp102
-rw-r--r--src/plugins/graphicssystems/meego/mextensions.h62
-rw-r--r--src/plugins/graphicssystems/meego/mgraphicssystem.cpp221
-rw-r--r--src/plugins/graphicssystems/meego/mgraphicssystem.h58
-rw-r--r--src/plugins/graphicssystems/meego/mgraphicssystemplugin.cpp31
-rw-r--r--src/plugins/graphicssystems/meego/mgraphicssystemplugin.h27
-rw-r--r--src/plugins/graphicssystems/meego/mpixmapdata.cpp179
-rw-r--r--src/plugins/graphicssystems/meego/mpixmapdata.h46
9 files changed, 738 insertions, 0 deletions
diff --git a/src/plugins/graphicssystems/meego/meegographicssystem.pro b/src/plugins/graphicssystems/meego/meegographicssystem.pro
new file mode 100644
index 0000000..80a974e
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/meegographicssystem.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+QT += gui opengl
+INCLUDEPATH += '../'
+HEADERS = mgraphicssystem.h mpixmapdata.h mextensions.h
+SOURCES = mgraphicssystem.cpp mgraphicssystem.h mgraphicssystemplugin.h mgraphicssystemplugin.cpp mpixmapdata.h mpixmapdata.cpp mextensions.h mextensions.cpp
+CONFIG += GLESv2 EGL X11 debug plugin
+LIBS += -lGLESv2
+TARGET = meegographicssystem
+
+target.path = $$[QT_INSTALL_PLUGINS]/graphicssystems
+
+INSTALLS += target
diff --git a/src/plugins/graphicssystems/meego/mextensions.cpp b/src/plugins/graphicssystems/meego/mextensions.cpp
new file mode 100644
index 0000000..814532f
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mextensions.cpp
@@ -0,0 +1,102 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include "mextensions.h"
+#include "../private/qeglcontext_p.h"
+#include "../private/qpixmapdata_gl_p.h"
+
+bool MExtensions::initialized = false;
+bool MExtensions::hasImageShared = false;
+bool MExtensions::hasSurfaceScaling = false;
+
+/* Extension funcs */
+
+typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint, EGLint*);
+typedef EGLNativeSharedImageTypeNOK (EGLAPIENTRY *eglCreateSharedImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint*);
+typedef EGLBoolean (EGLAPIENTRY *eglDestroySharedImageNOKFunc)(EGLDisplay, EGLNativeSharedImageTypeNOK);
+typedef EGLBoolean (EGLAPIENTRY *eglSetSurfaceScalingNOKFunc)(EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint);
+
+static eglQueryImageNOKFunc _eglQueryImageNOK = 0;
+static eglCreateSharedImageNOKFunc _eglCreateSharedImageNOK = 0;
+static eglDestroySharedImageNOKFunc _eglDestroySharedImageNOK = 0;
+static eglSetSurfaceScalingNOKFunc _eglSetSurfaceScalingNOK = 0;
+
+/* Public */
+
+void MExtensions::ensureInitialized()
+{
+ if (!initialized)
+ initialize();
+
+ initialized = true;
+}
+
+EGLNativeSharedImageTypeNOK MExtensions::eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props)
+{
+ if (! hasImageShared)
+ qFatal("EGL_NOK_image_shared not found but trying to use capability!");
+
+ return _eglCreateSharedImageNOK(dpy, image, props);
+}
+
+bool MExtensions::eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v)
+{
+ if (! hasImageShared)
+ qFatal("EGL_NOK_image_shared not found but trying to use capability!");
+
+ return _eglQueryImageNOK(dpy, image, prop, v);
+}
+
+bool MExtensions::eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img)
+{
+ if (! hasImageShared)
+ qFatal("EGL_NOK_image_shared not found but trying to use capability!");
+
+ return _eglDestroySharedImageNOK(dpy, img);
+}
+
+bool MExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height)
+{
+ if (! hasSurfaceScaling)
+ qFatal("EGL_NOK_surface_scaling not found but trying to use capability!");
+
+ return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height);
+}
+
+/* Private */
+
+void MExtensions::initialize()
+{
+ QGLContext *ctx = (QGLContext *) QGLContext::currentContext();
+ qt_resolve_eglimage_gl_extensions(ctx);
+
+ if (QEgl::hasExtension("EGL_NOK_image_shared")) {
+ qDebug("MeegoGraphics: found EGL_NOK_image_shared");
+ _eglQueryImageNOK = (eglQueryImageNOKFunc) eglGetProcAddress("eglQueryImageNOK");
+ _eglCreateSharedImageNOK = (eglCreateSharedImageNOKFunc) eglGetProcAddress("eglCreateSharedImageNOK");
+ _eglDestroySharedImageNOK = (eglDestroySharedImageNOKFunc) eglGetProcAddress("eglDestroySharedImageNOK");
+
+ Q_ASSERT(_eglQueryImageNOK && _eglCreateSharedImageNOK && _eglDestroySharedImageNOK);
+ hasImageShared = true;
+ }
+
+ if (QEgl::hasExtension("EGL_NOK_surface_scaling")) {
+ qDebug("MeegoGraphics: found EGL_NOK_surface_scaling");
+ _eglSetSurfaceScalingNOK = (eglSetSurfaceScalingNOKFunc) eglGetProcAddress("eglSetSurfaceScalingNOK");
+
+ Q_ASSERT(_eglSetSurfaceScalingNOK);
+ hasSurfaceScaling = true;
+ }
+}
+
diff --git a/src/plugins/graphicssystems/meego/mextensions.h b/src/plugins/graphicssystems/meego/mextensions.h
new file mode 100644
index 0000000..9506c50
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mextensions.h
@@ -0,0 +1,62 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef MEXTENSIONS_H
+#define MEXTENSIONS_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include "../private/qgl_p.h"
+#include "../private/qeglcontext_p.h"
+#include "../private/qpixmapdata_gl_p.h"
+
+/* Extensions decls */
+
+#ifndef EGL_SHARED_IMAGE_NOK
+#define EGL_SHARED_IMAGE_NOK 0x30DA
+typedef void* EGLNativeSharedImageTypeNOK;
+#endif
+
+#ifndef EGL_GL_TEXTURE_2D_KHR
+#define EGL_GL_TEXTURE_2D_KHR 0x30B1
+#endif
+
+#ifndef EGL_FIXED_WIDTH_NOK
+#define EGL_FIXED_WIDTH_NOK 0x30DB
+#define EGL_FIXED_HEIGHT_NOK 0x30DC
+#endif
+
+/* Class */
+
+class MExtensions
+{
+public:
+ static void ensureInitialized();
+
+ static EGLNativeSharedImageTypeNOK eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props);
+ static bool eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v);
+ static bool eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img);
+ static bool eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height);
+
+private:
+ static void initialize();
+
+ static bool initialized;
+ static bool hasImageShared;
+ static bool hasSurfaceScaling;
+};
+
+#endif
diff --git a/src/plugins/graphicssystems/meego/mgraphicssystem.cpp b/src/plugins/graphicssystems/meego/mgraphicssystem.cpp
new file mode 100644
index 0000000..e4a8210
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mgraphicssystem.cpp
@@ -0,0 +1,221 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include <QDebug>
+#include "../private/qpixmap_raster_p.h"
+#include "../private/qwindowsurface_gl_p.h"
+#include "../private/qegl_p.h"
+#include "../private/qglextensions_p.h"
+#include "../private/qgl_p.h"
+#include "../private/qimagepixmapcleanuphooks_p.h"
+#include "../private/qapplication_p.h"
+#include "../private/qgraphicssystem_runtime_p.h"
+#include "../private/qimage_p.h"
+#include "../private/qeglproperties_p.h"
+#include "../private/qeglcontext_p.h"
+
+#include "mpixmapdata.h"
+#include "mgraphicssystem.h"
+#include "mextensions.h"
+
+bool MGraphicsSystem::surfaceWasCreated = false;
+
+MGraphicsSystem::MGraphicsSystem()
+{
+ qDebug("Using the meego graphics system");
+}
+
+MGraphicsSystem::~MGraphicsSystem()
+{
+ qDebug("Meego graphics system destroyed");
+ qt_destroy_gl_share_widget();
+}
+
+QWindowSurface* MGraphicsSystem::createWindowSurface(QWidget *widget) const
+{
+ MGraphicsSystem::surfaceWasCreated = true;
+ QWindowSurface *surface = new QGLWindowSurface(widget);
+ surface->window()->setAttribute(Qt::WA_NoSystemBackground);
+ return surface;
+}
+
+QPixmapData *MGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
+{
+ // Long story short: without this it's possible to hit an
+ // unitialized paintDevice due to a Qt bug too complex to even
+ // explain here... not to mention fix without going crazy.
+ // MDK
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+
+ return new QRasterPixmapData(type);
+}
+
+QPixmapData *MGraphicsSystem::createPixmapData(QPixmapData *origin)
+{
+ // If the pixmap is a raster type...
+ // and if the pixmap pointer matches our mapping...
+ // create a shared image instead with the given handle.
+
+ if (origin->classId() == QPixmapData::RasterClass) {
+ QRasterPixmapData *rasterClass = static_cast <QRasterPixmapData *> (origin);
+ void *rawResource = static_cast <void *> (rasterClass->buffer()->data_ptr()->data);
+
+ if (MPixmapData::sharedImagesMap.contains(rawResource))
+ return new MPixmapData();
+ }
+
+ return new QRasterPixmapData(origin->pixelType());
+}
+
+QPixmapData* MGraphicsSystem::wrapPixmapData(QPixmapData *pmd)
+{
+ QString name = QApplicationPrivate::instance()->graphics_system_name;
+ if (name == "runtime") {
+ QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
+ QRuntimePixmapData *rt = new QRuntimePixmapData(rsystem, pmd->pixelType());;
+ rt->m_data = pmd;
+ rt->readBackInfo();
+ rsystem->m_pixmapDatas << rt;
+ return rt;
+ } else
+ return pmd;
+}
+
+void MGraphicsSystem::setSurfaceFixedSize(int /*width*/, int /*height*/)
+{
+ if (MGraphicsSystem::surfaceWasCreated)
+ qWarning("Trying to set surface fixed size but surface already created!");
+
+#ifdef QT_WAS_PATCHED
+ QEglProperties *properties = new QEglProperties();
+ properties->setValue(EGL_FIXED_WIDTH_NOK, width);
+ properties->setValue(EGL_FIXED_HEIGHT_NOK, height);
+ QGLContextPrivate::setExtraWindowSurfaceCreationProps(properties);
+#endif
+}
+
+void MGraphicsSystem::setSurfaceScaling(int x, int y, int width, int height)
+{
+ MExtensions::ensureInitialized();
+ MExtensions::eglSetSurfaceScalingNOK(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->currentSurface, x, y, width, height);
+}
+
+void MGraphicsSystem::setTranslucent(bool translucent)
+{
+ QGLWindowSurface::surfaceFormat.setSampleBuffers(false);
+ QGLWindowSurface::surfaceFormat.setSamples(0);
+ QGLWindowSurface::surfaceFormat.setAlpha(translucent);
+}
+
+QPixmapData *MGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
+{
+ if (softImage.format() != QImage::Format_ARGB32_Premultiplied &&
+ softImage.format() != QImage::Format_ARGB32) {
+ qFatal("For egl shared images, the soft image has to be ARGB32 or ARGB32_Premultiplied");
+ return NULL;
+ }
+
+ if (MGraphicsSystem::meegoRunning()) {
+ MPixmapData *pmd = new MPixmapData;
+ pmd->fromEGLSharedImage(handle, softImage);
+ return MGraphicsSystem::wrapPixmapData(pmd);
+ } else {
+ QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType);
+ pmd->fromImage(softImage, Qt::NoOpaqueDetection);
+
+ // Make sure that the image was not converted in any way
+ if (pmd->buffer()->data_ptr()->data !=
+ const_cast<QImage &>(softImage).data_ptr()->data)
+ qFatal("Iternal misalignment of raster data detected. Prolly a QImage copy fail.");
+
+ MPixmapData::registerSharedImage(handle, softImage);
+ return MGraphicsSystem::wrapPixmapData(pmd);
+ }
+}
+
+void MGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap)
+{
+ MPixmapData *pmd = (MPixmapData *) pixmap->pixmapData();
+
+ // Basic sanity check to make sure this is really a MPixmapData...
+ if (pmd->classId() != QPixmapData::OpenGLClass)
+ qFatal("Trying to updated EGLSharedImage pixmap but it's not really a shared image pixmap!");
+
+ pmd->updateFromSoftImage();
+}
+
+QPixmapData *MGraphicsSystem::pixmapDataWithGLTexture(int w, int h)
+{
+ QGLPixmapData *pmd = new QGLPixmapData(QPixmapData::PixmapType);
+ pmd->resize(w, h);
+ return MGraphicsSystem::wrapPixmapData(pmd);
+}
+
+bool MGraphicsSystem::meegoRunning()
+{
+ if (! QApplicationPrivate::instance()) {
+ qWarning("Application not running just yet... hard to know what system running!");
+ return false;
+ }
+
+ QString name = QApplicationPrivate::instance()->graphics_system_name;
+ if (name == "runtime") {
+ QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
+ name = rsystem->graphicsSystemName();
+ }
+
+ return (name == "meego");
+}
+
+/* C API */
+
+int m_image_to_egl_shared_image(const QImage &image)
+{
+ return MPixmapData::imageToEGLSharedImage(image);
+}
+
+QPixmapData* m_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage)
+{
+ return MGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage);
+}
+
+QPixmapData* m_pixmapdata_with_gl_texture(int w, int h)
+{
+ return MGraphicsSystem::pixmapDataWithGLTexture(w, h);
+}
+
+bool m_destroy_egl_shared_image(Qt::HANDLE handle)
+{
+ return MPixmapData::destroyEGLSharedImage(handle);
+}
+
+void m_set_surface_fixed_size(int width, int height)
+{
+ MGraphicsSystem::setSurfaceFixedSize(width, height);
+}
+
+void m_set_surface_scaling(int x, int y, int width, int height)
+{
+ MGraphicsSystem::setSurfaceScaling(x, y, width, height);
+}
+
+void m_set_translucent(bool translucent)
+{
+ MGraphicsSystem::setTranslucent(translucent);
+}
+
+void m_update_egl_shared_image_pixmap(QPixmap *pixmap)
+{
+ MGraphicsSystem::updateEGLSharedImagePixmap(pixmap);
+}
diff --git a/src/plugins/graphicssystems/meego/mgraphicssystem.h b/src/plugins/graphicssystems/meego/mgraphicssystem.h
new file mode 100644
index 0000000..c95d7ae
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mgraphicssystem.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef MGRAPHICSSYSTEM_H
+#define MGRAPHICSSYSTEM_H
+
+#include "../private/qgraphicssystem_p.h"
+
+class MGraphicsSystem : public QGraphicsSystem
+{
+public:
+ MGraphicsSystem();
+ ~MGraphicsSystem();
+
+ virtual QWindowSurface *createWindowSurface(QWidget *widget) const;
+ virtual QPixmapData *createPixmapData(QPixmapData::PixelType) const;
+ virtual QPixmapData *createPixmapData(QPixmapData *origin);
+
+ static QPixmapData *wrapPixmapData(QPixmapData *pmd);
+ static void setSurfaceFixedSize(int width, int height);
+ static void setSurfaceScaling(int x, int y, int width, int height);
+ static void setTranslucent(bool translucent);
+
+ static QPixmapData *pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+ static QPixmapData *pixmapDataWithGLTexture(int w, int h);
+ static void updateEGLSharedImagePixmap(QPixmap *pixmap);
+
+private:
+ static bool meegoRunning();
+
+ static bool surfaceWasCreated;
+};
+
+/* C api */
+
+extern "C" {
+ int m_image_to_egl_shared_image(const QImage &image);
+ QPixmapData* m_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage);
+ QPixmapData* m_pixmapdata_with_gl_texture(int w, int h);
+ void m_update_egl_shared_image_pixmap(QPixmap *pixmap);
+ bool m_destroy_egl_shared_image(Qt::HANDLE handle);
+ void m_set_surface_fixed_size(int width, int height);
+ void m_set_surface_scaling(int x, int y, int width, int height);
+ void m_set_translucent(bool translucent);
+}
+
+#endif
diff --git a/src/plugins/graphicssystems/meego/mgraphicssystemplugin.cpp b/src/plugins/graphicssystems/meego/mgraphicssystemplugin.cpp
new file mode 100644
index 0000000..3bb7ffb
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mgraphicssystemplugin.cpp
@@ -0,0 +1,31 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include <QDebug>
+#include "mgraphicssystemplugin.h"
+#include "mgraphicssystem.h"
+
+QStringList MGraphicsSystemPlugin::keys() const
+{
+ QStringList list;
+ list << "meego";
+ return list;
+}
+
+QGraphicsSystem *MGraphicsSystemPlugin::create(const QString&)
+{
+ return new MGraphicsSystem;
+}
+
+Q_EXPORT_PLUGIN2(meego, MGraphicsSystemPlugin)
diff --git a/src/plugins/graphicssystems/meego/mgraphicssystemplugin.h b/src/plugins/graphicssystems/meego/mgraphicssystemplugin.h
new file mode 100644
index 0000000..84d4427
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mgraphicssystemplugin.h
@@ -0,0 +1,27 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef MGRAPHICSSYSTEMPLUGIN_H
+#define MGRAPHICSSYSTEMPLUGIN_H
+
+#include "../private/qgraphicssystemplugin_p.h"
+
+class MGraphicsSystemPlugin : public QGraphicsSystemPlugin
+{
+public:
+ virtual QStringList keys() const;
+ virtual QGraphicsSystem *create(const QString&);
+};
+
+#endif
diff --git a/src/plugins/graphicssystems/meego/mpixmapdata.cpp b/src/plugins/graphicssystems/meego/mpixmapdata.cpp
new file mode 100644
index 0000000..b17adf3
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mpixmapdata.cpp
@@ -0,0 +1,179 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#include "mpixmapdata.h"
+#include "mextensions.h"
+#include "../private/qimage_p.h"
+#include "../private/qwindowsurface_gl_p.h"
+#include "../private/qeglcontext_p.h"
+#include "../private/qapplication_p.h"
+#include "../private/qgraphicssystem_runtime_p.h"
+
+static EGLint preserved_image_attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
+
+QHash <void*, MImageInfo*> MPixmapData::sharedImagesMap;
+
+/* Public */
+
+MPixmapData::MPixmapData() : QGLPixmapData(QPixmapData::PixmapType)
+{
+}
+
+void MPixmapData::fromTexture(GLuint textureId, int w, int h, bool alpha)
+{
+ resize(w, h);
+ texture()->id = textureId;
+ m_hasAlpha = alpha;
+ softImage = QImage();
+}
+
+QImage MPixmapData::toImage() const
+{
+ return softImage;
+}
+
+void MPixmapData::fromImage(const QImage &image,
+ Qt::ImageConversionFlags flags)
+{
+ void *rawResource = static_cast <void *> (((QImage &) image).data_ptr()->data);
+
+ if (sharedImagesMap.contains(rawResource)) {
+ MImageInfo *info = sharedImagesMap.value(rawResource);
+ fromEGLSharedImage(info->handle, image);
+ } else {
+ // This should *never* happen since the graphics system should never
+ // create a MPixmapData for an origin that doesn't contain a raster
+ // image we know about. But...
+ qWarning("MPixmapData::fromImage called on non-know resource. Falling back...");
+ QGLPixmapData::fromImage(image, flags);
+ }
+}
+
+void MPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
+{
+ if (si.isNull())
+ qFatal("Trying to build pixmap with an empty/null softimage!");
+
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+
+ MExtensions::ensureInitialized();
+
+ bool textureIsBound = false;
+ GLuint newTextureId;
+ GLint newWidth, newHeight;
+
+ glGenTextures(1, &newTextureId);
+ glBindTexture(GL_TEXTURE_2D, newTextureId);
+
+ glFinish();
+ EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_SHARED_IMAGE_NOK,
+ (EGLClientBuffer)handle, preserved_image_attribs);
+
+ if (image != EGL_NO_IMAGE_KHR) {
+ glFinish();
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+ GLint err = glGetError();
+ if (err == GL_NO_ERROR)
+ textureIsBound = true;
+
+ MExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_WIDTH, &newWidth);
+ MExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_HEIGHT, &newHeight);
+
+ QEgl::eglDestroyImageKHR(QEgl::display(), image);
+ glFinish();
+ }
+
+ if (textureIsBound) {
+ // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix
+ // for QGLPixmapData.
+ fromTexture(newTextureId, newWidth, newHeight,
+ (si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels()));
+ softImage = si;
+ MPixmapData::registerSharedImage(handle, softImage);
+ } else {
+ qWarning("Failed to create a texture from a shared image!");
+ glDeleteTextures(1, &newTextureId);
+ }
+}
+
+Qt::HANDLE MPixmapData::imageToEGLSharedImage(const QImage &image)
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+
+ MExtensions::ensureInitialized();
+
+ glFinish();
+ QGLPixmapData pixmapData(QPixmapData::PixmapType);
+ pixmapData.fromImage(image, 0);
+ GLuint textureId = pixmapData.bind();
+
+ glFinish();
+ EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(),
+ EGL_GL_TEXTURE_2D_KHR,
+ (EGLClientBuffer) textureId,
+ preserved_image_attribs);
+ glFinish();
+
+ if (eglimage) {
+ EGLNativeSharedImageTypeNOK handle = MExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL);
+ QEgl::eglDestroyImageKHR(QEgl::display(), eglimage);
+ glFinish();
+ return (Qt::HANDLE) handle;
+ } else {
+ qWarning("Failed to create shared image from pixmap/texture!");
+ return 0;
+ }
+}
+
+void MPixmapData::updateFromSoftImage()
+{
+ m_dirty = true;
+ m_source = softImage;
+ ensureCreated();
+
+ if (softImage.width() != w || softImage.height() != h)
+ qWarning("Ooops, looks like softImage changed dimensions since last updated! Corruption ahead?!");
+}
+
+bool MPixmapData::destroyEGLSharedImage(Qt::HANDLE h)
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ MExtensions::ensureInitialized();
+
+ QMutableHashIterator <void*, MImageInfo*> i(sharedImagesMap);
+ while (i.hasNext()) {
+ i.next();
+ if (i.value()->handle == h)
+ i.remove();
+ }
+
+ return MExtensions::eglDestroySharedImageNOK(QEgl::display(), (EGLNativeSharedImageTypeNOK) h);
+}
+
+void MPixmapData::registerSharedImage(Qt::HANDLE handle, const QImage &si)
+{
+ void *raw = static_cast <void *> (((QImage) si).data_ptr()->data);
+ MImageInfo *info;
+
+ if (! sharedImagesMap.contains(raw)) {
+ info = new MImageInfo;
+ info->handle = handle;
+ info->rawFormat = si.format();
+ sharedImagesMap.insert(raw, info);
+ } else {
+ info = sharedImagesMap.value(raw);
+ if (info->handle != handle || info->rawFormat != si.format())
+ qWarning("Inconsistency detected: overwriting entry in sharedImagesMap but handle/format different");
+ }
+}
diff --git a/src/plugins/graphicssystems/meego/mpixmapdata.h b/src/plugins/graphicssystems/meego/mpixmapdata.h
new file mode 100644
index 0000000..ae4ed6b
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/mpixmapdata.h
@@ -0,0 +1,46 @@
+/***************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation
+** and appearing in the file LICENSE.LGPL included in the packaging
+** of this file.
+**
+****************************************************************************/
+
+#ifndef MPIXMAPDATA_H
+#define MPIXMAPDATA_H
+
+#include "../private/qpixmapdata_gl_p.h"
+
+struct MImageInfo
+{
+ Qt::HANDLE handle;
+ QImage::Format rawFormat;
+};
+
+class MPixmapData : public QGLPixmapData
+{
+public:
+ MPixmapData();
+ void fromTexture(GLuint textureId, int w, int h, bool alpha);
+
+ virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+ virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags);
+ virtual QImage toImage() const;
+ virtual void updateFromSoftImage();
+
+ QImage softImage;
+
+ static QHash <void*, MImageInfo*> sharedImagesMap;
+
+ static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
+ static bool destroyEGLSharedImage(Qt::HANDLE h);
+ static void registerSharedImage(Qt::HANDLE handle, const QImage &si);
+};
+
+#endif