diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2010-09-06 06:58:18 (GMT) |
---|---|---|
committer | Samuel Rødal <samuel.rodal@nokia.com> | 2010-09-10 10:44:54 (GMT) |
commit | 1c109b9e504b4b51707c97f443be49c88720b386 (patch) | |
tree | e7c73083f428930113c6ad90bd1470e329d06afa /src/plugins/graphicssystems/meego | |
parent | a9bf68d69d30fc44264f09a75f5e33431bdf4616 (diff) | |
download | Qt-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/graphicssystems/meego')
-rw-r--r-- | src/plugins/graphicssystems/meego/meegographicssystem.pro | 12 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mextensions.cpp | 102 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mextensions.h | 62 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mgraphicssystem.cpp | 221 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mgraphicssystem.h | 58 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mgraphicssystemplugin.cpp | 31 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mgraphicssystemplugin.h | 27 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mpixmapdata.cpp | 179 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/mpixmapdata.h | 46 |
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 |