diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-10-07 21:40:10 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-10-07 21:40:10 (GMT) |
commit | 558acd8c8ff94c6fd1e96514a2dffb587a66bb2f (patch) | |
tree | dc11d87ae4982458b78d10337afbc03fcb88382d /src | |
parent | 161f15e1e79ec5f23244da68340ba1e78f3ac4bb (diff) | |
parent | df61814c228e6f2badf378e25b69daf9941c646b (diff) | |
download | Qt-558acd8c8ff94c6fd1e96514a2dffb587a66bb2f.zip Qt-558acd8c8ff94c6fd1e96514a2dffb587a66bb2f.tar.gz Qt-558acd8c8ff94c6fd1e96514a2dffb587a66bb2f.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-2: (26 commits)
Live texture updates to meegographicssystem helper.
Live texture updates to meegographicssystem plugin.
Revert the integration of the merge request 2286.
Fix text rendering in GL when using the broken-fbo-fallback
ActiveQt: also make the designer plugin for qaxwidget build in the opensource versions
Fix compilation
Code cleaning with the merge request 2286
Fix a pending issue with the merge request 2286
Doc: fix description of the expected behavior for QGraphicsItem::cursor
Fixed the build error in qtconfig
Resolved a little code style issue in qtconfig
Renamed controls in qtconfig's MainWindow
Removed inheritance from UI file in qtconfig's MainWindow
Fixed a bug and resolved some translation issues in qtconfig
Fixed some problems in qtconfig's PreviewWidget
Removed the inheritance from ui file in qtconfig's PaletteEditorAdvanced
Replaced the unnecessary include with declaration
Resolved some code style issues and fixed the broken copyright year
Finally removed the qtconfig dependency from qt3support
Modified previewwidget's ui file in qtconfig
...
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 2 | ||||
-rw-r--r-- | src/gui/graphicsview/qgraphicsscene.cpp | 76 | ||||
-rw-r--r-- | src/gui/image/qpixmap_x11_p.h | 1 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp | 2 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/qmeegoextensions.cpp | 32 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/qmeegoextensions.h | 15 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/qmeegographicssystem.cpp | 203 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/qmeegographicssystem.h | 21 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp | 30 | ||||
-rw-r--r-- | src/plugins/graphicssystems/meego/qmeegopixmapdata.h | 1 |
10 files changed, 363 insertions, 20 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index fc44a44..60cd020 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2125,7 +2125,7 @@ void QGraphicsItem::setToolTip(const QString &toolTip) \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 2 - If no cursor has been set, the parent's cursor is used. + If no cursor has been set, the cursor of the item beneath is used. \sa setCursor(), hasCursor(), unsetCursor(), QWidget::cursor, QApplication::overrideCursor() diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index e58b93c..a0015dc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -4362,6 +4362,50 @@ static void _q_paintIntoCache(QPixmap *pix, QGraphicsItem *item, const QRegion & } } +// Copied from qpaintengine_vg.cpp +// Returns true for 90, 180, and 270 degree rotations. +static inline bool transformIsSimple(const QTransform& transform) +{ + QTransform::TransformationType type = transform.type(); + if (type == QTransform::TxNone || type == QTransform::TxTranslate) { + return true; + } else if (type == QTransform::TxScale) { + // Check for 0 and 180 degree rotations. + // (0 might happen after 4 rotations of 90 degrees). + qreal m11 = transform.m11(); + qreal m12 = transform.m12(); + qreal m21 = transform.m21(); + qreal m22 = transform.m22(); + if (m12 == 0.0f && m21 == 0.0f) { + if (m11 == 1.0f && m22 == 1.0f) + return true; // 0 degrees + else if (m11 == -1.0f && m22 == -1.0f) + return true; // 180 degrees. + if(m11 == 1.0f && m22 == -1.0f) + return true; // 0 degrees inverted y. + else if(m11 == -1.0f && m22 == 1.0f) + return true; // 180 degrees inverted y. + } + } else if (type == QTransform::TxRotate) { + // Check for 90, and 270 degree rotations. + qreal m11 = transform.m11(); + qreal m12 = transform.m12(); + qreal m21 = transform.m21(); + qreal m22 = transform.m22(); + if (m11 == 0.0f && m22 == 0.0f) { + if (m12 == 1.0f && m21 == -1.0f) + return true; // 90 degrees. + else if (m12 == -1.0f && m21 == 1.0f) + return true; // 270 degrees. + else if (m12 == -1.0f && m21 == -1.0f) + return true; // 90 degrees inverted y. + else if (m12 == 1.0f && m21 == 1.0f) + return true; // 270 degrees inverted y. + } + } + return false; +} + /*! \internal @@ -4530,32 +4574,28 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte if (invertable) diff *= painter->worldTransform(); deviceData->lastTransform = painter->worldTransform(); - if (!invertable - || diff.type() > QTransform::TxTranslate - || painter->worldTransform().type() > QTransform::TxScale) { + bool allowPartialCacheExposure = false; + bool simpleTransform = invertable && diff.type() <= QTransform::TxTranslate + && transformIsSimple(painter->worldTransform()); + if (!simpleTransform) { pixModified = true; itemCache->allExposed = true; itemCache->exposed.clear(); + deviceData->cacheIndent = QPoint(); pix = QPixmap(); + } else { + allowPartialCacheExposure = deviceData->cacheIndent != QPoint(); } - // ### This is a pretty bad way to determine when to start partial - // exposure for DeviceCoordinateCache but it's the least intrusive - // approach for now. -#if 0 - // Only if the device rect isn't fully contained. - bool allowPartialCacheExposure = !viewRect.contains(deviceRect); -#else - // Only if deviceRect is 20% taller or wider than the desktop. - bool allowPartialCacheExposure = false; - if (widget) { - QRect desktopRect = QApplication::desktop()->availableGeometry(widget); - allowPartialCacheExposure = (desktopRect.width() * 1.2 < deviceRect.width() - || desktopRect.height() * 1.2 < deviceRect.height()); + // Allow partial cache exposure if the device rect isn't fully contained and + // deviceRect is 20% taller or wider than the viewRect. + if (!allowPartialCacheExposure && !viewRect.contains(deviceRect)) { + allowPartialCacheExposure = (viewRect.width() * 1.2 < deviceRect.width()) + || (viewRect.height() * 1.2 < deviceRect.height()); } -#endif + QRegion scrollExposure; - if (deviceData->cacheIndent != QPoint() || allowPartialCacheExposure) { + if (allowPartialCacheExposure) { // Part of pixmap is drawn. Either device contains viewrect (big // item covers whole screen) or parts of device are outside the // viewport. In either case the device rect must be the intersect diff --git a/src/gui/image/qpixmap_x11_p.h b/src/gui/image/qpixmap_x11_p.h index 821fb69..f171281 100644 --- a/src/gui/image/qpixmap_x11_p.h +++ b/src/gui/image/qpixmap_x11_p.h @@ -115,6 +115,7 @@ private: friend class QEglContext; // Needs gl_surface friend class QGLContext; // Needs gl_surface friend class QX11GLPixmapData; // Needs gl_surface + friend class QMeeGoGraphicsSystem; // Needs gl_surface and flags friend bool qt_createEGLSurfaceForPixmap(QPixmapData*, bool); // Needs gl_surface void release(); diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 9a5bac0..919c542 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -137,7 +137,7 @@ void QGLTextureGlyphCache::resizeTextureData(int width, int height) if (ctx->d_ptr->workaround_brokenFBOReadBack) { QImageTextureGlyphCache::resizeTextureData(width, height); Q_ASSERT(image().depth() == 8); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, oldWidth, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, oldHeight, GL_ALPHA, GL_UNSIGNED_BYTE, image().constBits()); glDeleteTextures(1, &oldTexture); return; } diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp index e7f6439..611c962 100644 --- a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp +++ b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp @@ -46,6 +46,7 @@ bool QMeeGoExtensions::initialized = false; bool QMeeGoExtensions::hasImageShared = false; bool QMeeGoExtensions::hasSurfaceScaling = false; +bool QMeeGoExtensions::hasLockSurface = false; /* Extension funcs */ @@ -53,11 +54,15 @@ typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR, typedef EGLNativeSharedImageTypeNOK (EGLAPIENTRY *eglCreateSharedImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint*); typedef EGLBoolean (EGLAPIENTRY *eglDestroySharedImageNOKFunc)(EGLDisplay, EGLNativeSharedImageTypeNOK); typedef EGLBoolean (EGLAPIENTRY *eglSetSurfaceScalingNOKFunc)(EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglLockSurfaceKHRFunc)(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHRFunc)(EGLDisplay display, EGLSurface surface); static eglQueryImageNOKFunc _eglQueryImageNOK = 0; static eglCreateSharedImageNOKFunc _eglCreateSharedImageNOK = 0; static eglDestroySharedImageNOKFunc _eglDestroySharedImageNOK = 0; static eglSetSurfaceScalingNOKFunc _eglSetSurfaceScalingNOK = 0; +static eglLockSurfaceKHRFunc _eglLockSurfaceKHR = 0; +static eglUnlockSurfaceKHRFunc _eglUnlockSurfaceKHR = 0; /* Public */ @@ -101,6 +106,22 @@ bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surfac return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height); } +bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) +{ + if (! hasLockSurface) + qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!"); + + return _eglLockSurfaceKHR(display, surface, attrib_list); +} + +bool QMeeGoExtensions::eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) +{ + if (! hasLockSurface) + qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!"); + + return _eglUnlockSurfaceKHR(display, surface); +} + /* Private */ void QMeeGoExtensions::initialize() @@ -113,6 +134,8 @@ void QMeeGoExtensions::initialize() _eglQueryImageNOK = (eglQueryImageNOKFunc) eglGetProcAddress("eglQueryImageNOK"); _eglCreateSharedImageNOK = (eglCreateSharedImageNOKFunc) eglGetProcAddress("eglCreateSharedImageNOK"); _eglDestroySharedImageNOK = (eglDestroySharedImageNOKFunc) eglGetProcAddress("eglDestroySharedImageNOK"); + _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR"); + _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR"); Q_ASSERT(_eglQueryImageNOK && _eglCreateSharedImageNOK && _eglDestroySharedImageNOK); hasImageShared = true; @@ -125,5 +148,14 @@ void QMeeGoExtensions::initialize() Q_ASSERT(_eglSetSurfaceScalingNOK); hasSurfaceScaling = true; } + + if (QEgl::hasExtension("EGL_KHR_lock_surface2")) { + qDebug("MeegoGraphics: found EGL_KHR_lock_surface2"); + _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR"); + _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR"); + + Q_ASSERT(_eglLockSurfaceKHR && _eglUnlockSurfaceKHR); + hasLockSurface = true; + } } diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.h b/src/plugins/graphicssystems/meego/qmeegoextensions.h index ee20bd8..9e78caf 100644 --- a/src/plugins/graphicssystems/meego/qmeegoextensions.h +++ b/src/plugins/graphicssystems/meego/qmeegoextensions.h @@ -65,6 +65,18 @@ typedef void* EGLNativeSharedImageTypeNOK; #define EGL_FIXED_HEIGHT_NOK 0x30DC #endif +#ifndef EGL_BITMAP_POINTER_KHR +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#endif + +#ifndef EGL_MAP_PRESERVE_PIXELS_KHR +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#endif + /* Class */ class QMeeGoExtensions @@ -76,6 +88,8 @@ public: 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); + static bool eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); + static bool eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface); private: static void initialize(); @@ -83,6 +97,7 @@ private: static bool initialized; static bool hasImageShared; static bool hasSurfaceScaling; + static bool hasLockSurface; }; #endif diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp index 2a64d49..f8b228c 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp @@ -51,6 +51,7 @@ #include <private/qimage_p.h> #include <private/qeglproperties_p.h> #include <private/qeglcontext_p.h> +#include <private/qpixmap_x11_p.h> #include "qmeegopixmapdata.h" #include "qmeegographicssystem.h" @@ -58,6 +59,8 @@ bool QMeeGoGraphicsSystem::surfaceWasCreated = false; +QHash <Qt::HANDLE, QPixmap*> QMeeGoGraphicsSystem::liveTexturePixmaps; + QMeeGoGraphicsSystem::QMeeGoGraphicsSystem() { qDebug("Using the meego graphics system"); @@ -170,6 +173,22 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl } } +QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLImage(Qt::HANDLE handle) +{ + if (QMeeGoGraphicsSystem::meeGoRunning()) { + QMeeGoPixmapData *pmd = new QMeeGoPixmapData; + pmd->fromEGLImage(handle); + + // FIXME Ok. This is a bit BAD BAD BAD. We're abusing here the fact that we KNOW + // that this function is used for the live pixmap... + pmd->texture()->options &= ~QGLContext::InvertedYBindOption; + return QMeeGoGraphicsSystem::wrapPixmapData(pmd); + } else { + qFatal("Can't create from EGL image when not running meego graphics system!"); + return NULL; + } +} + void QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap) { QMeeGoPixmapData *pmd = (QMeeGoPixmapData *) pixmap->pixmapData(); @@ -188,6 +207,109 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h) return QMeeGoGraphicsSystem::wrapPixmapData(pmd); } +Qt::HANDLE QMeeGoGraphicsSystem::createLiveTexture(int w, int h, QImage::Format format) +{ + // No need to wrap the QPixmapData here. This QPixmap(Data) is a + // internal implementation and we don't migrate it between + // graphics system switching. + + // We use a bit ugly way of enforcing a color format on the X pixmap -- we create + // a local QImage and fromImage from there. This is quite redundant (extra overhead of creating + // the useless image only to delete it) but shouldn't be too bad for now... you're not expected + // to call createLiveTexture too often anyways. Would be great if QX11PixmapData had a way to + // force the X format upon creation or resize. + + QImage image(w, h, format); + QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType); + pmd->fromImage(image, Qt::NoOpaqueDetection); + QPixmap *p = new QPixmap(pmd); + + liveTexturePixmaps.insert(p->handle(), p); + return p->handle(); +} + +void QMeeGoGraphicsSystem::destroyLiveTexture(Qt::HANDLE h) +{ + if (liveTexturePixmaps.contains(h)) { + QPixmap *p = liveTexturePixmaps.value(h); + delete p; + liveTexturePixmaps.remove(h); + } else + qWarning("Trying to destroy live texture %ld which was not found!", h); +} + +bool QMeeGoGraphicsSystem::lockLiveTexture(Qt::HANDLE h) +{ + if (! liveTexturePixmaps.contains(h)) { + qWarning("Trying to lock live texture %ld which was not found!", h); + return false; + } + + EGLint attribs[] = { + EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE, + EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR, + EGL_NONE + }; + + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h)); + return QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, attribs); +} + +bool QMeeGoGraphicsSystem::unlockLiveTexture(Qt::HANDLE h) +{ + if (! liveTexturePixmaps.contains(h)) { + qWarning("Trying to lock live texture %ld which was not found!", h); + return false; + } + + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + + EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h)); + if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface)) { + glFinish(); + return true; + } else { + return false; + } +} + +void QMeeGoGraphicsSystem::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch) +{ + // FIXME Only allow this on locked surfaces + if (! liveTexturePixmaps.contains(h)) { + qWarning("Trying to query live texture %ld which was not found!", h); + return; + } + + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + + EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h)); + eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) data); + eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) pitch); +} + +Qt::HANDLE QMeeGoGraphicsSystem::liveTextureToEGLImage(Qt::HANDLE h) +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + + EGLint attribs[] = { + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, + EGL_NONE + }; + + EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, + (EGLClientBuffer) h, attribs); + + if (eglImage == EGL_NO_IMAGE_KHR) + qWarning("eglCreateImageKHR failed!"); + + return (Qt::HANDLE) eglImage; +} + bool QMeeGoGraphicsSystem::meeGoRunning() { if (! QApplicationPrivate::instance()) { @@ -204,6 +326,52 @@ bool QMeeGoGraphicsSystem::meeGoRunning() return (name == "meego"); } +void QMeeGoGraphicsSystem::destroySurfaceForLiveTexturePixmap(QPixmapData* pmd) +{ + Q_ASSERT(pmd->classId() == QPixmapData::X11Class); + QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); + if (pixmapData->gl_surface) { + eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface); + pixmapData->gl_surface = 0; + } +} + +EGLSurface QMeeGoGraphicsSystem::getSurfaceForLiveTexturePixmap(QPixmap *pixmap) +{ + // This code is a crative remix of the stuff that can be found in the + // Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap + QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pixmap->data_ptr().data()); + Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class); + bool hasAlpha = pixmapData->hasAlphaChannel(); + + if (pixmapData->gl_surface && + hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha)) + return pixmapData->gl_surface; + + // Check to see if the surface is still valid + if (pixmapData->gl_surface && + hasAlpha != ((pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha) > 0)) { + // Surface is invalid! + QMeeGoGraphicsSystem::destroySurfaceForLiveTexturePixmap(pixmapData); + } + + if (pixmapData->gl_surface == 0) { + EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap, + QEgl::OpenGL, + hasAlpha ? QEgl::Translucent : QEgl::NoOptions); + + pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config); + + if (hasAlpha) + pixmapData->flags = pixmapData->flags | QX11PixmapData::GlSurfaceCreatedWithAlpha; + + if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE) + return NULL; + } + + return pixmapData->gl_surface; +} + /* C API */ int qt_meego_image_to_egl_shared_image(const QImage &image) @@ -216,6 +384,11 @@ QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const return QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage); } +QPixmapData* qt_meego_pixmapdata_from_egl_image(Qt::HANDLE handle) +{ + return QMeeGoGraphicsSystem::pixmapDataFromEGLImage(handle); +} + QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h) { return QMeeGoGraphicsSystem::pixmapDataWithGLTexture(w, h); @@ -245,3 +418,33 @@ void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap) { QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(pixmap); } + +Qt::HANDLE qt_meego_live_texture_create(int w, int h, QImage::Format format) +{ + return QMeeGoGraphicsSystem::createLiveTexture(w, h, format); +} + +void qt_meego_live_texture_destroy(Qt::HANDLE h) +{ + QMeeGoGraphicsSystem::destroyLiveTexture(h); +} + +bool qt_meego_live_texture_lock(Qt::HANDLE h) +{ + return QMeeGoGraphicsSystem::lockLiveTexture(h); +} + +bool qt_meego_live_texture_unlock(Qt::HANDLE h) +{ + return QMeeGoGraphicsSystem::unlockLiveTexture(h); +} + +void qt_meego_live_texture_query(Qt::HANDLE h, void **data, int *pitch) +{ + return QMeeGoGraphicsSystem::queryLiveTexture(h, data, pitch); +} + +Qt::HANDLE qt_meego_live_texture_to_egl_image(Qt::HANDLE h) +{ + return QMeeGoGraphicsSystem::liveTextureToEGLImage(h); +} diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h index 905f0c3..934d32d 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h @@ -43,6 +43,9 @@ #define MGRAPHICSSYSTEM_H #include <private/qgraphicssystem_p.h> +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> class QMeeGoGraphicsSystem : public QGraphicsSystem { @@ -60,13 +63,24 @@ public: static void setTranslucent(bool translucent); static QPixmapData *pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage); + static QPixmapData *pixmapDataFromEGLImage(Qt::HANDLE handle); static QPixmapData *pixmapDataWithGLTexture(int w, int h); static void updateEGLSharedImagePixmap(QPixmap *pixmap); + static Qt::HANDLE createLiveTexture(int w, int h, QImage::Format format); + static void destroyLiveTexture(Qt::HANDLE h); + static bool lockLiveTexture(Qt::HANDLE h); + static bool unlockLiveTexture(Qt::HANDLE h); + static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch); + static Qt::HANDLE liveTextureToEGLImage(Qt::HANDLE h); + private: static bool meeGoRunning(); + static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap); + static void destroySurfaceForLiveTexturePixmap(QPixmapData* pmd); static bool surfaceWasCreated; + static QHash <Qt::HANDLE, QPixmap*> liveTexturePixmaps; }; /* C api */ @@ -74,12 +88,19 @@ private: extern "C" { Q_DECL_EXPORT int qt_meego_image_to_egl_shared_image(const QImage &image); Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage); + Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_image(Qt::HANDLE handle); Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h); Q_DECL_EXPORT void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap); Q_DECL_EXPORT bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle); Q_DECL_EXPORT void qt_meego_set_surface_fixed_size(int width, int height); Q_DECL_EXPORT void qt_meego_set_surface_scaling(int x, int y, int width, int height); Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent); + Q_DECL_EXPORT Qt::HANDLE m_live_texture_create(int w, int h, QImage::Format format); + Q_DECL_EXPORT void m_live_texture_destroy(Qt::HANDLE h); + Q_DECL_EXPORT bool m_live_texture_lock(Qt::HANDLE h); + Q_DECL_EXPORT bool m_live_texture_unlock(Qt::HANDLE h); + Q_DECL_EXPORT void m_live_texture_query(Qt::HANDLE h, void **data, int *pitch); + Q_DECL_EXPORT Qt::HANDLE m_live_texture_to_egl_image(Qt::HANDLE h); } #endif diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp index 33611dc..84fc593 100644 --- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp @@ -87,6 +87,36 @@ void QMeeGoPixmapData::fromImage(const QImage &image, } } +void QMeeGoPixmapData::fromEGLImage(Qt::HANDLE handle) +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + + bool textureIsBound = false; + GLuint newTextureId; + GLint newWidth, newHeight; + + glGenTextures(1, &newTextureId); + glBindTexture(GL_TEXTURE_2D, newTextureId); + + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) handle); + GLint err = glGetError(); + if (err == GL_NO_ERROR) + textureIsBound = true; + + QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_WIDTH, &newWidth); + QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_HEIGHT, &newHeight); + + if (textureIsBound) { + // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix + // for QGLPixmapData. + fromTexture(newTextureId, newWidth, newHeight, true); + } else { + qWarning("Failed to create a texture from an egl image!"); + glDeleteTextures(1, &newTextureId); + } +} + void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si) { if (si.isNull()) diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h index 8af33bd..8b1ae14 100644 --- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h @@ -56,6 +56,7 @@ public: QMeeGoPixmapData(); void fromTexture(GLuint textureId, int w, int h, bool alpha); + virtual void fromEGLImage(Qt::HANDLE handle); virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage); virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags); virtual QImage toImage() const; |