From 6ce6b8a378b0d97ba950240ffb048a4b7e485235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 20 Jun 2011 13:29:26 +0200 Subject: Rename QWindowSurface -> QBackingStore and split into platform / public. Also get rid of GL window surface and related classes. --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 1 - src/opengl/opengl.pro | 22 +- src/opengl/qgl.cpp | 30 - src/opengl/qgl.h | 3 - src/opengl/qgl_egl.cpp | 3 +- src/opengl/qgl_p.h | 6 - src/opengl/qglpaintdevice.cpp | 22 +- src/opengl/qglpixelbuffer.h | 1 - src/opengl/qglpixmapfilter.cpp | 1 - src/opengl/qgltexturepool.cpp | 244 ----- src/opengl/qgltexturepool_p.h | 147 --- src/opengl/qpixmapdata_gl.cpp | 829 --------------- src/opengl/qpixmapdata_gl_p.h | 247 ----- src/opengl/qpixmapdata_poolgl.cpp | 934 ----------------- src/opengl/qpixmapdata_x11gl_egl.cpp | 403 ------- src/opengl/qpixmapdata_x11gl_p.h | 98 -- src/opengl/qwindowsurface_gl.cpp | 1104 -------------------- src/opengl/qwindowsurface_gl_p.h | 127 --- src/opengl/qwindowsurface_x11gl.cpp | 213 ---- src/opengl/qwindowsurface_x11gl_p.h | 83 -- 20 files changed, 7 insertions(+), 4511 deletions(-) delete mode 100644 src/opengl/qgltexturepool.cpp delete mode 100644 src/opengl/qgltexturepool_p.h delete mode 100644 src/opengl/qpixmapdata_gl.cpp delete mode 100644 src/opengl/qpixmapdata_gl_p.h delete mode 100644 src/opengl/qpixmapdata_poolgl.cpp delete mode 100644 src/opengl/qpixmapdata_x11gl_egl.cpp delete mode 100644 src/opengl/qpixmapdata_x11gl_p.h delete mode 100644 src/opengl/qwindowsurface_gl.cpp delete mode 100644 src/opengl/qwindowsurface_gl_p.h delete mode 100644 src/opengl/qwindowsurface_x11gl.cpp delete mode 100644 src/opengl/qwindowsurface_x11gl_p.h (limited to 'src/opengl') diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 0aa2b8b202..b2f4b34b02 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 578ce0f660..efc00a9b66 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -57,8 +57,6 @@ SOURCES += qgl.cpp \ HEADERS += qglshaderprogram.h \ qglpixmapfilter_p.h \ qgraphicsshadereffect_p.h \ - qwindowsurface_gl_p.h \ - qpixmapdata_gl_p.h \ gl2paintengineex/qglgradientcache_p.h \ gl2paintengineex/qglengineshadermanager_p.h \ gl2paintengineex/qgl2pexvertexarray_p.h \ @@ -74,8 +72,6 @@ SOURCES += qgl.cpp \ SOURCES += qglshaderprogram.cpp \ qglpixmapfilter.cpp \ qgraphicsshadereffect.cpp \ - qwindowsurface_gl.cpp \ - qpixmapdata_gl.cpp \ gl2paintengineex/qglgradientcache.cpp \ gl2paintengineex/qglengineshadermanager.cpp \ gl2paintengineex/qgl2pexvertexarray.cpp \ @@ -96,13 +92,9 @@ x11 { contains(QT_CONFIG, egl) { SOURCES += qgl_x11egl.cpp \ qglpixelbuffer_egl.cpp \ - qgl_egl.cpp \ - qpixmapdata_x11gl_egl.cpp \ - qwindowsurface_x11gl.cpp + qgl_egl.cpp - HEADERS += qgl_egl_p.h \ - qpixmapdata_x11gl_p.h \ - qwindowsurface_x11gl_p.h + HEADERS += qgl_egl_p.h } else { SOURCES += qgl_x11.cpp \ @@ -144,16 +136,12 @@ wince*: { } symbian { - DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP - SOURCES -= qpixmapdata_gl.cpp + DEFINES += QGL_NO_PRESERVED_SWAP SOURCES += qgl_symbian.cpp \ - qpixmapdata_poolgl.cpp \ qglpixelbuffer_egl.cpp \ - qgl_egl.cpp \ - qgltexturepool.cpp + qgl_egl.cpp - HEADERS += qgl_egl_p.h \ - qgltexturepool_p.h + HEADERS += qgl_egl_p.h contains(QT_CONFIG, freetype) { DEFINES += QT_NO_FONTCONFIG diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index fdcfeb1864..31a4b77047 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -70,17 +70,12 @@ #if !defined(QT_OPENGL_ES_1) #include "gl2paintengineex/qpaintengineex_opengl2_p.h" -#include #endif #ifndef QT_OPENGL_ES_2 #include #endif -#ifdef Q_WS_QWS -#include -#endif - #ifdef Q_WS_QPA #include #endif @@ -90,7 +85,6 @@ #include #include -#include #include #include #include "qcolormap.h" @@ -101,9 +95,6 @@ #if defined(QT_OPENGL_ES) && !defined(QT_NO_EGL) #include #endif -#ifdef QGL_USE_TEXTURE_POOL -#include -#endif // #define QT_GL_CONTEXT_RESOURCE_DEBUG @@ -2547,18 +2538,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G #endif const QImage &constRef = img; // to avoid detach in bits()... -#ifdef QGL_USE_TEXTURE_POOL - QGLTexturePool::instance()->createPermanentTexture(tx_id, - target, - 0, internalFormat, - img.width(), img.height(), - externalFormat, - pixel_type, - constRef.bits()); -#else glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat, pixel_type, constRef.bits()); -#endif #if defined(QT_OPENGL_ES_2) if (genMipmap) glGenerateMipmap(target); @@ -2602,18 +2583,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, { Q_Q(QGLContext); QPixmapData *pd = pixmap.pixmapData(); -#if !defined(QT_OPENGL_ES_1) - if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { - const QGLPixmapData *data = static_cast(pd); - - if (data->isValidContext(q)) { - data->bind(); - return data->texture(); - } - } -#else Q_UNUSED(pd); -#endif const qint64 key = pixmap.cacheKey(); QGLTexture *texture = textureCacheLookup(key, target); diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 7b0a237e83..f6051fa179 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -444,8 +444,6 @@ private: friend class QGL2PaintEngineEx; friend class QGL2PaintEngineExPrivate; friend class QGLEngineShaderManager; - friend class QGLWindowSurface; - friend class QGLPixmapData; friend class QGLPixmapFilterBase; friend class QGLTextureGlyphCache; friend struct QGLGlyphTexture; @@ -467,7 +465,6 @@ private: friend class QGLFBOGLPaintDevice; friend class QGLPaintDevice; friend class QGLWidgetGLPaintDevice; - friend class QX11GLPixmapData; friend class QX11GLSharedContexts; friend class QGLContextResourceBase; friend class QSGDistanceFieldGlyphCache; diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 4de5122a86..34b448e048 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -261,8 +261,7 @@ void QGLContextPrivate::destroyEglSurfaceForDevice() #if defined(Q_WS_X11) || defined(Q_OS_SYMBIAN) // Make sure we don't call eglDestroySurface on a surface which // was created for a different winId. This applies only to QGLWidget - // paint device, so make sure this is the one we're operating on - // (as opposed to a QGLWindowSurface use case). + // paint device, so make sure this is the one we're operating on. if (paintDevice && paintDevice->devType() == QInternal::Widget) { QWidget *w = static_cast(paintDevice); if (QGLWidget *wgl = qobject_cast(w)) { diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 82b6e91c5d..5b69caeb3e 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -96,10 +96,6 @@ QT_END_INCLUDE_NAMESPACE class QMacWindowChangeEvent; #endif -#ifdef Q_WS_QWS -class QWSGLWindowSurface; -#endif - #ifndef QT_NO_EGL class QEglContext; #endif @@ -212,8 +208,6 @@ public: #elif defined(Q_WS_MAC) QGLContext *olcx; void updatePaintDevice(); -#elif defined(Q_WS_QWS) - QWSGLWindowSurface *wsurf; #endif #ifdef Q_OS_SYMBIAN void recreateEglSurface(); diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp index b4e12d8b7e..08807bdd49 100644 --- a/src/opengl/qglpaintdevice.cpp +++ b/src/opengl/qglpaintdevice.cpp @@ -43,14 +43,6 @@ #include #include #include -#ifdef Q_WS_X11 -#include -#endif - -#if !defined(QT_OPENGL_ES_1) -#include -#include -#endif QT_BEGIN_NAMESPACE @@ -220,19 +212,7 @@ QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd) glpd = &(static_cast(pd)->d_func()->glDevice); break; case QInternal::Pixmap: { -#if !defined(QT_OPENGL_ES_1) - QPixmapData* pmd = static_cast(pd)->pixmapData(); - if (pmd->classId() == QPixmapData::OpenGLClass) - glpd = static_cast(pmd)->glDevice(); -#ifdef Q_WS_X11 - else if (pmd->classId() == QPixmapData::X11Class) - glpd = static_cast(pmd); -#endif - else - qWarning("Pixmap type not supported for GL rendering"); -#else - qWarning("Pixmap render targets not supported on OpenGL ES 1.x"); -#endif + qWarning("Pixmap type not supported for GL rendering"); break; } default: diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h index dcd1a6ca71..1cffb0ec0b 100644 --- a/src/opengl/qglpixelbuffer.h +++ b/src/opengl/qglpixelbuffer.h @@ -109,7 +109,6 @@ private: Q_DISABLE_COPY(QGLPixelBuffer) QScopedPointer d_ptr; friend class QGLDrawable; - friend class QGLWindowSurface; friend class QGLPaintDevice; friend class QGLPBufferGLPaintDevice; friend class QGLContextPrivate; diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index c1318ffa47..c9815ec91a 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "private/qpixmapfilter_p.h" -#include "private/qpixmapdata_gl_p.h" #include "private/qpaintengineex_opengl2_p.h" #include "private/qglengineshadermanager_p.h" #include "private/qpixmapdata_p.h" diff --git a/src/opengl/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp deleted file mode 100644 index d809328725..0000000000 --- a/src/opengl/qgltexturepool.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenVG module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgltexturepool_p.h" -#include "qpixmapdata_gl_p.h" - -QT_BEGIN_NAMESPACE - -Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget(); - -static QGLTexturePool *qt_gl_texture_pool = 0; - -class QGLTexturePoolPrivate -{ -public: - QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {} - - QGLPixmapData *lruFirst; - QGLPixmapData *lruLast; -}; - -QGLTexturePool::QGLTexturePool() - : d_ptr(new QGLTexturePoolPrivate()) -{ -} - -QGLTexturePool::~QGLTexturePool() -{ -} - -QGLTexturePool *QGLTexturePool::instance() -{ - if (!qt_gl_texture_pool) - qt_gl_texture_pool = new QGLTexturePool(); - return qt_gl_texture_pool; -} - -GLuint QGLTexturePool::createTextureForPixmap(GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - QGLPixmapData *data) -{ - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(target, texture); - do { - glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0); - GLenum error = glGetError(); - if (error == GL_NO_ERROR) { - if (data) - moveToHeadOfLRU(data); - return texture; - } else if (error != GL_OUT_OF_MEMORY) { - qWarning("QGLTexturePool: cannot create temporary texture because of invalid params"); - return 0; - } - } while (reclaimSpace(internalformat, width, height, format, type, data)); - qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap", - width, height); - return 0; -} - -bool QGLTexturePool::createPermanentTexture(GLuint texture, - GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid *data) -{ - glBindTexture(target, texture); - do { - glTexImage2D(target, level, internalformat, width, height, 0, format, type, data); - - GLenum error = glGetError(); - if (error == GL_NO_ERROR) { - return true; - } else if (error != GL_OUT_OF_MEMORY) { - qWarning("QGLTexturePool: cannot create permanent texture because of invalid params"); - return false; - } - } while (reclaimSpace(internalformat, width, height, format, type, 0)); - qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap", - width, height); - return 0; -} - -void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture) -{ - // Very simple strategy at the moment: just destroy the texture. - if (data) - removeFromLRU(data); - - QGLWidget *shareWidget = qt_gl_share_widget(); - if (shareWidget) { - QGLShareContextScope ctx(shareWidget->context()); - glDeleteTextures(1, &texture); - } -} - -void QGLTexturePool::useTexture(QGLPixmapData *data) -{ - moveToHeadOfLRU(data); -} - -void QGLTexturePool::detachTexture(QGLPixmapData *data) -{ - removeFromLRU(data); -} - -bool QGLTexturePool::reclaimSpace(GLint internalformat, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - QGLPixmapData *data) -{ - Q_UNUSED(internalformat); // For future use in picking the best texture to eject. - Q_UNUSED(width); - Q_UNUSED(height); - Q_UNUSED(format); - Q_UNUSED(type); - - bool succeeded = false; - bool wasInLRU = false; - if (data) { - wasInLRU = data->inLRU; - moveToHeadOfLRU(data); - } - - QGLPixmapData *lrudata = pixmapLRU(); - if (lrudata && lrudata != data) { - lrudata->reclaimTexture(); - succeeded = true; - } - - if (data && !wasInLRU) - removeFromLRU(data); - - return succeeded; -} - -void QGLTexturePool::hibernate() -{ - Q_D(QGLTexturePool); - QGLPixmapData *pd = d->lruLast; - while (pd) { - QGLPixmapData *prevLRU = pd->prevLRU; - pd->inTexturePool = false; - pd->inLRU = false; - pd->nextLRU = 0; - pd->prevLRU = 0; - pd->hibernate(); - pd = prevLRU; - } - d->lruFirst = 0; - d->lruLast = 0; -} - -void QGLTexturePool::moveToHeadOfLRU(QGLPixmapData *data) -{ - Q_D(QGLTexturePool); - if (data->inLRU) { - if (!data->prevLRU) - return; // Already at the head of the list. - removeFromLRU(data); - } - data->inLRU = true; - data->nextLRU = d->lruFirst; - data->prevLRU = 0; - if (d->lruFirst) - d->lruFirst->prevLRU = data; - else - d->lruLast = data; - d->lruFirst = data; -} - -void QGLTexturePool::removeFromLRU(QGLPixmapData *data) -{ - Q_D(QGLTexturePool); - if (!data->inLRU) - return; - if (data->nextLRU) - data->nextLRU->prevLRU = data->prevLRU; - else - d->lruLast = data->prevLRU; - if (data->prevLRU) - data->prevLRU->nextLRU = data->nextLRU; - else - d->lruFirst = data->nextLRU; - data->inLRU = false; -} - -QGLPixmapData *QGLTexturePool::pixmapLRU() -{ - Q_D(QGLTexturePool); - return d->lruLast; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qgltexturepool_p.h b/src/opengl/qgltexturepool_p.h deleted file mode 100644 index 27b730cbb9..0000000000 --- a/src/opengl/qgltexturepool_p.h +++ /dev/null @@ -1,147 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenVG module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGLTEXTUREPOOL_P_H -#define QGLTEXTUREPOOL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qgl.h" -#include - -QT_BEGIN_NAMESPACE - -class QGLPixmapData; -class QGLTexturePoolPrivate; - -class QGLTexturePool -{ -public: - QGLTexturePool(); - virtual ~QGLTexturePool(); - - static QGLTexturePool *instance(); - - // Create a new texture with the specified parameters and associate - // it with "data". The QGLPixmapData will be notified when the - // texture needs to be reclaimed by the pool. - // - // This function will call reclaimSpace() when texture creation fails. - GLuint createTextureForPixmap(GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - QGLPixmapData *data); - - // Create a permanent texture with the specified parameters. - // If there is insufficient space for the texture, - // then this function will call reclaimSpace() and try again. - // - // The caller is responsible for calling glDeleteTextures() - // when it no longer needs the texture, as the texture is not - // recorded in the texture pool. - bool createPermanentTexture(GLuint texture, - GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - const GLvoid *data); - - // Release a texture that is no longer required. - void releaseTexture(QGLPixmapData *data, GLuint texture); - - // Notify the pool that a QGLPixmapData object is using - // an texture again. This allows the pool to move the texture - // within a least-recently-used list of QGLPixmapData objects. - void useTexture(QGLPixmapData *data); - - // Notify the pool that the texture associated with a - // QGLPixmapData is being detached from the pool. The caller - // will become responsible for calling glDeleteTextures(). - void detachTexture(QGLPixmapData *data); - - // Reclaim space for an image allocation with the specified parameters. - // Returns true if space was reclaimed, or false if there is no - // further space that can be reclaimed. The "data" parameter - // indicates the pixmap that is trying to obtain space which should - // not itself be reclaimed. - bool reclaimSpace(GLint internalformat, - GLsizei width, - GLsizei height, - GLenum format, - GLenum type, - QGLPixmapData *data); - - // Hibernate the image pool because the context is about to be - // destroyed. All textures left in the pool should be released. - void hibernate(); - -protected: - // Helper functions for managing the LRU list of QGLPixmapData objects. - void moveToHeadOfLRU(QGLPixmapData *data); - void removeFromLRU(QGLPixmapData *data); - QGLPixmapData *pixmapLRU(); - -private: - QScopedPointer d_ptr; - - Q_DECLARE_PRIVATE(QGLTexturePool) - Q_DISABLE_COPY(QGLTexturePool) -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp deleted file mode 100644 index e909ff30b9..0000000000 --- a/src/opengl/qpixmapdata_gl.cpp +++ /dev/null @@ -1,829 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmap.h" -#include "qglframebufferobject.h" - -#include - -#include "qpixmapdata_gl_p.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -Q_OPENGL_EXPORT extern const QGLContext* qt_gl_share_context(); - -/*! - \class QGLFramebufferObjectPool - \since 4.6 - - \brief The QGLFramebufferObject class provides a pool of framebuffer - objects for offscreen rendering purposes. - - When requesting an FBO of a given size and format, an FBO of the same - format and a size at least as big as the requested size will be returned. - - \internal -*/ - -static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo) -{ - return qAbs(size.width() * size.height() - fbo->width() * fbo->height()); -} - -extern int qt_next_power_of_two(int v); - -static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz) -{ -#ifdef QT_OPENGL_ES_2 - QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height())); - if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height()) - return rounded; -#endif - return sz; -} - - -QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize) -{ - QGLFramebufferObject *chosen = 0; - QGLFramebufferObject *candidate = 0; - for (int i = 0; !chosen && i < m_fbos.size(); ++i) { - QGLFramebufferObject *fbo = m_fbos.at(i); - - if (strictSize) { - if (fbo->size() == requestSize && fbo->format() == requestFormat) { - chosen = fbo; - break; - } else { - continue; - } - } - - if (fbo->format() == requestFormat) { - // choose the fbo with a matching format and the closest size - if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo)) - candidate = fbo; - } - - if (candidate) { - m_fbos.removeOne(candidate); - - const QSize fboSize = candidate->size(); - QSize sz = fboSize; - - if (sz.width() < requestSize.width()) - sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5))); - if (sz.height() < requestSize.height()) - sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5))); - - // wasting too much space? - if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4) - sz = requestSize; - - if (sz != fboSize) { - delete candidate; - candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat); - } - - chosen = candidate; - } - } - - if (!chosen) { - if (strictSize) - chosen = new QGLFramebufferObject(requestSize, requestFormat); - else - chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat); - } - - if (!chosen->isValid()) { - delete chosen; - chosen = 0; - } - - return chosen; -} - -void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo) -{ - if (fbo) - m_fbos << fbo; -} - - -QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const -{ - return data->paintEngine(); -} - -void QGLPixmapGLPaintDevice::beginPaint() -{ - if (!data->isValid()) - return; - - // QGLPaintDevice::beginPaint will store the current binding and replace - // it with m_thisFBO: - m_thisFBO = data->m_renderFbo->handle(); - QGLPaintDevice::beginPaint(); - - Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2); - - // QPixmap::fill() is deferred until now, where we actually need to do the fill: - if (data->needsFill()) { - const QColor &c = data->fillColor(); - float alpha = c.alphaF(); - glDisable(GL_SCISSOR_TEST); - glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); - glClear(GL_COLOR_BUFFER_BIT); - } - else if (!data->isUninitialized()) { - // If the pixmap (GL Texture) has valid content (it has been - // uploaded from an image or rendered into before), we need to - // copy it from the texture to the render FBO. - - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - -#if !defined(QT_OPENGL_ES_2) - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, data->width(), data->height(), 0, -999999, 999999); -#endif - - glViewport(0, 0, data->width(), data->height()); - - // Pass false to bind so it doesn't copy the FBO into the texture! - context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false)); - } -} - -void QGLPixmapGLPaintDevice::endPaint() -{ - if (!data->isValid()) - return; - - data->copyBackFromRenderFbo(false); - - // Base's endPaint will restore the previous FBO binding - QGLPaintDevice::endPaint(); - - qgl_fbo_pool()->release(data->m_renderFbo); - data->m_renderFbo = 0; -} - -QGLContext* QGLPixmapGLPaintDevice::context() const -{ - data->ensureCreated(); - return data->m_ctx; -} - -QSize QGLPixmapGLPaintDevice::size() const -{ - return data->size(); -} - -bool QGLPixmapGLPaintDevice::alphaRequested() const -{ - return data->m_hasAlpha; -} - -void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d) -{ - data = d; -} - -static int qt_gl_pixmap_serial = 0; - -QGLPixmapData::QGLPixmapData(PixelType type) - : QPixmapData(type, OpenGLClass) - , m_renderFbo(0) - , m_engine(0) - , m_ctx(0) - , m_dirty(false) - , m_hasFillColor(false) - , m_hasAlpha(false) -{ - setSerialNumber(++qt_gl_pixmap_serial); - m_glDevice.setPixmapData(this); -} - -QGLPixmapData::~QGLPixmapData() -{ - const QGLContext *shareContext = qt_gl_share_context(); - if (!shareContext) - return; - - delete m_engine; - - if (m_texture.id) { - QGLShareContextScope ctx(shareContext); - glDeleteTextures(1, &m_texture.id); - } -} - -QPixmapData *QGLPixmapData::createCompatiblePixmapData() const -{ - return new QGLPixmapData(pixelType()); -} - -bool QGLPixmapData::isValid() const -{ - return w > 0 && h > 0; -} - -bool QGLPixmapData::isValidContext(const QGLContext *ctx) const -{ - if (ctx == m_ctx) - return true; - - const QGLContext *share_ctx = qt_gl_share_context(); - return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx); -} - -void QGLPixmapData::resize(int width, int height) -{ - if (width == w && height == h) - return; - - if (width <= 0 || height <= 0) { - width = 0; - height = 0; - } - - w = width; - h = height; - is_null = (w <= 0 || h <= 0); - d = pixelType() == QPixmapData::PixmapType ? 32 : 1; - - if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_context()); - glDeleteTextures(1, &m_texture.id); - m_texture.id = 0; - } - - m_source = QImage(); - m_dirty = isValid(); - setSerialNumber(++qt_gl_pixmap_serial); -} - -void QGLPixmapData::ensureCreated() const -{ - if (!m_dirty) - return; - - m_dirty = false; - - QGLShareContextScope ctx(qt_gl_share_context()); - m_ctx = ctx; - - const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB; -#ifdef QT_OPENGL_ES_2 - const GLenum external_format = internal_format; -#else - const GLenum external_format = qt_gl_preferredTextureFormat(); -#endif - const GLenum target = GL_TEXTURE_2D; - - if (!m_texture.id) { - glGenTextures(1, &m_texture.id); - glBindTexture(target, m_texture.id); - glTexImage2D(target, 0, internal_format, w, h, 0, external_format, GL_UNSIGNED_BYTE, 0); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - if (!m_source.isNull()) { - if (external_format == GL_RGB) { - const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true); - - glBindTexture(target, m_texture.id); - glTexSubImage2D(target, 0, 0, 0, w, h, external_format, - GL_UNSIGNED_BYTE, tx.bits()); - } else { - const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); - - glBindTexture(target, m_texture.id); - glTexSubImage2D(target, 0, 0, 0, w, h, external_format, - GL_UNSIGNED_BYTE, tx.bits()); - } - - if (useFramebufferObjects()) - m_source = QImage(); - } - - m_texture.options &= ~QGLContext::MemoryManagedBindOption; -} - -void QGLPixmapData::fromImage(const QImage &image, - Qt::ImageConversionFlags flags) -{ - QImage img = image; - createPixmapForImage(img, flags, false); -} - -void QGLPixmapData::fromImageReader(QImageReader *imageReader, - Qt::ImageConversionFlags flags) -{ - QImage image = imageReader->read(); - if (image.isNull()) - return; - - createPixmapForImage(image, flags, true); -} - -bool QGLPixmapData::fromFile(const QString &filename, const char *format, - Qt::ImageConversionFlags flags) -{ - if (pixelType() == QPixmapData::BitmapType) - return QPixmapData::fromFile(filename, format, flags); - QFile file(filename); - if (file.open(QIODevice::ReadOnly)) { - QByteArray data = file.peek(64); - bool alpha; - if (m_texture.canBindCompressedTexture - (data.constData(), data.size(), format, &alpha)) { - resize(0, 0); - data = file.readAll(); - file.close(); - QGLShareContextScope ctx(qt_gl_share_context()); - QSize size = m_texture.bindCompressedTexture - (data.constData(), data.size(), format); - if (!size.isEmpty()) { - w = size.width(); - h = size.height(); - is_null = false; - d = 32; - m_hasAlpha = alpha; - m_source = QImage(); - m_dirty = isValid(); - return true; - } - return false; - } - } - - QImage image = QImageReader(filename, format).read(); - if (image.isNull()) - return false; - - createPixmapForImage(image, flags, true); - - return !isNull(); -} - -bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, - Qt::ImageConversionFlags flags) -{ - bool alpha; - const char *buf = reinterpret_cast(buffer); - if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) { - resize(0, 0); - QGLShareContextScope ctx(qt_gl_share_context()); - QSize size = m_texture.bindCompressedTexture(buf, int(len), format); - if (!size.isEmpty()) { - w = size.width(); - h = size.height(); - is_null = false; - d = 32; - m_hasAlpha = alpha; - m_source = QImage(); - m_dirty = isValid(); - return true; - } - } - - QByteArray a = QByteArray::fromRawData(reinterpret_cast(buffer), len); - QBuffer b(&a); - b.open(QIODevice::ReadOnly); - QImage image = QImageReader(&b, format).read(); - if (image.isNull()) - return false; - - createPixmapForImage(image, flags, true); - - return !isNull(); -} - -/*! - out-of-place conversion (inPlace == false) will always detach() - */ -void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace) -{ - if (image.size() == QSize(w, h)) - setSerialNumber(++qt_gl_pixmap_serial); - - resize(image.width(), image.height()); - - if (pixelType() == BitmapType) { - m_source = image.convertToFormat(QImage::Format_MonoLSB); - - } else { - QImage::Format format = QImage::Format_RGB32; - if (qApp->desktop()->depth() == 16) - format = QImage::Format_RGB16; - - if (image.hasAlphaChannel() - && ((flags & Qt::NoOpaqueDetection) - || const_cast(image).data_ptr()->checkForAlphaPixels())) - format = QImage::Format_ARGB32_Premultiplied;; - - if (inPlace && image.data_ptr()->convertInPlace(format, flags)) { - m_source = image; - } else { - m_source = image.convertToFormat(format); - - // convertToFormat won't detach the image if format stays the same. - if (image.format() == format) - m_source.detach(); - } - } - - m_dirty = true; - m_hasFillColor = false; - - m_hasAlpha = m_source.hasAlphaChannel(); - w = image.width(); - h = image.height(); - is_null = (w <= 0 || h <= 0); - d = m_source.depth(); - - if (m_texture.id) { - QGLShareContextScope ctx(qt_gl_share_context()); - glDeleteTextures(1, &m_texture.id); - m_texture.id = 0; - } -} - -bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) -{ - Q_UNUSED(dx); - Q_UNUSED(dy); - Q_UNUSED(rect); - return false; -} - -void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - if (data->classId() != QPixmapData::OpenGLClass || !static_cast(data)->useFramebufferObjects()) { - QPixmapData::copy(data, rect); - return; - } - - const QGLPixmapData *other = static_cast(data); - if (other->m_renderFbo) { - QGLShareContextScope ctx(qt_gl_share_context()); - - resize(rect.width(), rect.height()); - m_hasAlpha = other->m_hasAlpha; - ensureCreated(); - - if (!ctx->d_ptr->fbo) - glGenFramebuffers(1, &ctx->d_ptr->fbo); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, m_texture.id, 0); - - if (!other->m_renderFbo->isBound()) - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle()); - - glDisable(GL_SCISSOR_TEST); - if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2) - static_cast(ctx->d_ptr->active_engine)->invalidateState(); - - glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), - 0, 0, w, h, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); - } else { - QPixmapData::copy(data, rect); - } -} - -void QGLPixmapData::fill(const QColor &color) -{ - if (!isValid()) - return; - - bool hasAlpha = color.alpha() != 255; - if (hasAlpha && !m_hasAlpha) { - if (m_texture.id) { - glDeleteTextures(1, &m_texture.id); - m_texture.id = 0; - m_dirty = true; - } - m_hasAlpha = color.alpha() != 255; - } - - if (useFramebufferObjects()) { - m_source = QImage(); - m_hasFillColor = true; - m_fillColor = color; - } else { - - if (m_source.isNull()) { - m_fillColor = color; - m_hasFillColor = true; - - } else if (m_source.depth() == 32) { - m_source.fill(PREMUL(color.rgba())); - - } else if (m_source.depth() == 1) { - if (color == Qt::color1) - m_source.fill(1); - else - m_source.fill(0); - } - } -} - -bool QGLPixmapData::hasAlphaChannel() const -{ - return m_hasAlpha; -} - -QImage QGLPixmapData::fillImage(const QColor &color) const -{ - QImage img; - if (pixelType() == BitmapType) { - img = QImage(w, h, QImage::Format_MonoLSB); - - img.setColorCount(2); - img.setColor(0, QColor(Qt::color0).rgba()); - img.setColor(1, QColor(Qt::color1).rgba()); - - if (color == Qt::color1) - img.fill(1); - else - img.fill(0); - } else { - img = QImage(w, h, - m_hasAlpha - ? QImage::Format_ARGB32_Premultiplied - : QImage::Format_RGB32); - img.fill(PREMUL(color.rgba())); - } - return img; -} - -extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); - -QImage QGLPixmapData::toImage() const -{ - if (!isValid()) - return QImage(); - - if (m_renderFbo) { - copyBackFromRenderFbo(true); - } else if (!m_source.isNull()) { - QImageData *data = const_cast(m_source).data_ptr(); - if (data->paintEngine && data->paintEngine->isActive() - && data->paintEngine->paintDevice() == &m_source) - { - return m_source.copy(); - } - return m_source; - } else if (m_dirty || m_hasFillColor) { - return fillImage(m_fillColor); - } else { - ensureCreated(); - } - - QGLShareContextScope ctx(qt_gl_share_context()); - glBindTexture(GL_TEXTURE_2D, m_texture.id); - return qt_gl_read_texture(QSize(w, h), true, true); -} - -struct TextureBuffer -{ - QGLFramebufferObject *fbo; - QGL2PaintEngineEx *engine; -}; - -Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool) -QGLFramebufferObjectPool* qgl_fbo_pool() -{ - return _qgl_fbo_pool(); -} - -void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const -{ - if (!isValid()) - return; - - m_hasFillColor = false; - - const QGLContext *share_ctx = qt_gl_share_context(); - QGLShareContextScope ctx(share_ctx); - - ensureCreated(); - - if (!ctx->d_ptr->fbo) - glGenFramebuffers(1, &ctx->d_ptr->fbo); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, m_texture.id, 0); - - const int x0 = 0; - const int x1 = w; - const int y0 = 0; - const int y1 = h; - - if (!m_renderFbo->isBound()) - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); - - glDisable(GL_SCISSOR_TEST); - - glBlitFramebufferEXT(x0, y0, x1, y1, - x0, y0, x1, y1, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - if (keepCurrentFboBound) { - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); - } else { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle()); - ctx->d_ptr->current_fbo = m_renderFbo->handle(); - } -} - -bool QGLPixmapData::useFramebufferObjects() const -{ - return QGLFramebufferObject::hasOpenGLFramebufferObjects() - && QGLFramebufferObject::hasOpenGLFramebufferBlit() - && qt_gl_preferGL2Engine() - && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps -} - -QPaintEngine* QGLPixmapData::paintEngine() const -{ - if (!isValid()) - return 0; - - if (m_renderFbo) - return m_engine; - - if (useFramebufferObjects()) { - extern QGLWidget* qt_gl_share_widget(); - - if (!QGLContext::currentContext()) - const_cast(qt_gl_share_context())->makeCurrent(); - QGLShareContextScope ctx(qt_gl_share_context()); - - QGLFramebufferObjectFormat format; - format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format.setSamples(4); - format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB)); - - m_renderFbo = qgl_fbo_pool()->acquire(size(), format); - - if (m_renderFbo) { - if (!m_engine) - m_engine = new QGL2PaintEngineEx; - return m_engine; - } - - qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine"; - } - - m_dirty = true; - if (m_source.size() != size()) - m_source = QImage(size(), QImage::Format_ARGB32_Premultiplied); - if (m_hasFillColor) { - m_source.fill(PREMUL(m_fillColor.rgba())); - m_hasFillColor = false; - } - return m_source.paintEngine(); -} - -extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format); - -// If copyBack is true, bind will copy the contents of the render -// FBO to the texture (which is not bound to the texture, as it's -// a multisample FBO). -GLuint QGLPixmapData::bind(bool copyBack) const -{ - if (m_renderFbo && copyBack) { - copyBackFromRenderFbo(true); - } else { - ensureCreated(); - } - - GLuint id = m_texture.id; - glBindTexture(GL_TEXTURE_2D, id); - - if (m_hasFillColor) { - if (!useFramebufferObjects()) { - m_source = QImage(w, h, QImage::Format_ARGB32_Premultiplied); - m_source.fill(PREMUL(m_fillColor.rgba())); - } - - m_hasFillColor = false; - - GLenum format = qt_gl_preferredTextureFormat(); - QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); - tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); - } - - return id; -} - -QGLTexture* QGLPixmapData::texture() const -{ - return &m_texture; -} - -int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const -{ - if (w == 0) - return 0; - - switch (metric) { - case QPaintDevice::PdmWidth: - return w; - case QPaintDevice::PdmHeight: - return h; - case QPaintDevice::PdmNumColors: - return 0; - case QPaintDevice::PdmDepth: - return d; - case QPaintDevice::PdmWidthMM: - return qRound(w * 25.4 / qt_defaultDpiX()); - case QPaintDevice::PdmHeightMM: - return qRound(h * 25.4 / qt_defaultDpiY()); - case QPaintDevice::PdmDpiX: - case QPaintDevice::PdmPhysicalDpiX: - return qt_defaultDpiX(); - case QPaintDevice::PdmDpiY: - case QPaintDevice::PdmPhysicalDpiY: - return qt_defaultDpiY(); - default: - qWarning("QGLPixmapData::metric(): Invalid metric"); - return 0; - } -} - -QGLPaintDevice *QGLPixmapData::glDevice() const -{ - return &m_glDevice; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h deleted file mode 100644 index 909f264d05..0000000000 --- a/src/opengl/qpixmapdata_gl_p.h +++ /dev/null @@ -1,247 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAPDATA_GL_P_H -#define QPIXMAPDATA_GL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qgl_p.h" -#include "qgl.h" - -#include "private/qpixmapdata_p.h" -#include "private/qglpaintdevice_p.h" - -#ifdef Q_OS_SYMBIAN -#include "private/qvolatileimage_p.h" -#endif - -QT_BEGIN_NAMESPACE - -class QPaintEngine; -class QGLFramebufferObject; -class QGLFramebufferObjectFormat; -class QGLPixmapData; - -#ifdef QGL_USE_TEXTURE_POOL -void qt_gl_register_pixmap(QGLPixmapData *pd); -void qt_gl_unregister_pixmap(QGLPixmapData *pd); -void qt_gl_hibernate_pixmaps(); -#endif - -#ifdef Q_OS_SYMBIAN -class QNativeImageHandleProvider; -#endif - -class QGLFramebufferObjectPool -{ -public: - QGLFramebufferObject *acquire(const QSize &size, const QGLFramebufferObjectFormat &format, bool strictSize = false); - void release(QGLFramebufferObject *fbo); - -private: - QList m_fbos; -}; - -QGLFramebufferObjectPool* qgl_fbo_pool(); - - -class QGLPixmapGLPaintDevice : public QGLPaintDevice -{ -public: - QPaintEngine* paintEngine() const; - - void beginPaint(); - void endPaint(); - QGLContext* context() const; - QSize size() const; - bool alphaRequested() const; - - void setPixmapData(QGLPixmapData*); -private: - QGLPixmapData *data; -}; - - -class Q_OPENGL_EXPORT QGLPixmapData : public QPixmapData -{ -public: - QGLPixmapData(PixelType type); - ~QGLPixmapData(); - - QPixmapData *createCompatiblePixmapData() const; - - // Re-implemented from QPixmapData: - void resize(int width, int height); - void fromImage(const QImage &image, Qt::ImageConversionFlags flags); - void fromImageReader(QImageReader *imageReader, - Qt::ImageConversionFlags flags); - bool fromFile(const QString &filename, const char *format, - Qt::ImageConversionFlags flags); - bool fromData(const uchar *buffer, uint len, const char *format, - Qt::ImageConversionFlags flags); - void copy(const QPixmapData *data, const QRect &rect); - bool scroll(int dx, int dy, const QRect &rect); - void fill(const QColor &color); - bool hasAlphaChannel() const; - QImage toImage() const; - QPaintEngine *paintEngine() const; - int metric(QPaintDevice::PaintDeviceMetric metric) const; - - // For accessing as a target: - QGLPaintDevice *glDevice() const; - - // For accessing as a source: - bool isValidContext(const QGLContext *ctx) const; - GLuint bind(bool copyBack = true) const; - QGLTexture *texture() const; - -#ifdef QGL_USE_TEXTURE_POOL - void destroyTexture(); - // Detach this image from the image pool. - void detachTextureFromPool(); - // Release the GL resources associated with this pixmap and copy - // the pixmap's contents out of the GPU back into main memory. - // The GL resource will be automatically recreated the next time - // ensureCreated() is called. Does nothing if the pixmap cannot be - // hibernated for some reason (e.g. texture is shared with another - // process via a SgImage). - void hibernate(); - // Called when the QGLTexturePool wants to reclaim this pixmap's - // texture objects to reuse storage. - void reclaimTexture(); - void forceToImage(); -#endif - -#ifdef Q_OS_SYMBIAN - QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags); - void* toNativeType(NativeType type); - void fromNativeType(void* pixmap, NativeType type); - bool initFromNativeImageHandle(void *handle, const QString &type); - void createFromNativeImageHandleProvider(); - void releaseNativeImageHandle(); -#endif - -private: - bool isValid() const; - - void ensureCreated() const; - - bool isUninitialized() const { return m_dirty && m_source.isNull(); } - - bool needsFill() const { return m_hasFillColor; } - QColor fillColor() const { return m_fillColor; } - - - - QGLPixmapData(const QGLPixmapData &other); - QGLPixmapData &operator=(const QGLPixmapData &other); - - void copyBackFromRenderFbo(bool keepCurrentFboBound) const; - QSize size() const { return QSize(w, h); } - - bool useFramebufferObjects() const; - - QImage fillImage(const QColor &color) const; - - void createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace); - - mutable QGLFramebufferObject *m_renderFbo; - mutable QPaintEngine *m_engine; - mutable QGLContext *m_ctx; -#ifdef Q_OS_SYMBIAN - mutable QVolatileImage m_source; - mutable QNativeImageHandleProvider *nativeImageHandleProvider; - void *nativeImageHandle; - QString nativeImageType; -#else - mutable QImage m_source; -#endif - mutable QGLTexture m_texture; - - // the texture is not in sync with the source image - mutable bool m_dirty; - - // fill has been called and no painting has been done, so the pixmap is - // represented by a single fill color - mutable QColor m_fillColor; - mutable bool m_hasFillColor; - - mutable bool m_hasAlpha; - - mutable QGLPixmapGLPaintDevice m_glDevice; - -#ifdef QGL_USE_TEXTURE_POOL - QGLPixmapData *nextLRU; - QGLPixmapData *prevLRU; - mutable bool inLRU; - mutable bool failedToAlloc; - mutable bool inTexturePool; - - QGLPixmapData *next; - QGLPixmapData *prev; - - friend class QGLTexturePool; - - friend void qt_gl_register_pixmap(QGLPixmapData *pd); - friend void qt_gl_unregister_pixmap(QGLPixmapData *pd); - friend void qt_gl_hibernate_pixmaps(); -#endif - - friend class QGLPixmapGLPaintDevice; - friend class QMeeGoPixmapData; - friend class QMeeGoLivePixmapData; -}; - -QT_END_NAMESPACE - -#endif // QPIXMAPDATA_GL_P_H - - diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_poolgl.cpp deleted file mode 100644 index 5dd7b09c64..0000000000 --- a/src/opengl/qpixmapdata_poolgl.cpp +++ /dev/null @@ -1,934 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qpixmap.h" -#include "qglframebufferobject.h" - -#include - -#include "qpixmapdata_gl_p.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "qgltexturepool_p.h" - -QT_BEGIN_NAMESPACE - -Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget(); - -static inline int areaDiff(const QSize &size, const QGLFramebufferObject *fbo) -{ - return qAbs(size.width() * size.height() - fbo->width() * fbo->height()); -} - -extern int qt_next_power_of_two(int v); - -static inline QSize maybeRoundToNextPowerOfTwo(const QSize &sz) -{ -#ifdef QT_OPENGL_ES_2 - QSize rounded(qt_next_power_of_two(sz.width()), qt_next_power_of_two(sz.height())); - if (rounded.width() * rounded.height() < 1.20 * sz.width() * sz.height()) - return rounded; -#endif - return sz; -} - - -QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize, const QGLFramebufferObjectFormat &requestFormat, bool strictSize) -{ - QGLFramebufferObject *chosen = 0; - QGLFramebufferObject *candidate = 0; - for (int i = 0; !chosen && i < m_fbos.size(); ++i) { - QGLFramebufferObject *fbo = m_fbos.at(i); - - if (strictSize) { - if (fbo->size() == requestSize && fbo->format() == requestFormat) { - chosen = fbo; - break; - } else { - continue; - } - } - - if (fbo->format() == requestFormat) { - // choose the fbo with a matching format and the closest size - if (!candidate || areaDiff(requestSize, candidate) > areaDiff(requestSize, fbo)) - candidate = fbo; - } - - if (candidate) { - m_fbos.removeOne(candidate); - - const QSize fboSize = candidate->size(); - QSize sz = fboSize; - - if (sz.width() < requestSize.width()) - sz.setWidth(qMax(requestSize.width(), qRound(sz.width() * 1.5))); - if (sz.height() < requestSize.height()) - sz.setHeight(qMax(requestSize.height(), qRound(sz.height() * 1.5))); - - // wasting too much space? - if (sz.width() * sz.height() > requestSize.width() * requestSize.height() * 4) - sz = requestSize; - - if (sz != fboSize) { - delete candidate; - candidate = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(sz), requestFormat); - } - - chosen = candidate; - } - } - - if (!chosen) { - if (strictSize) - chosen = new QGLFramebufferObject(requestSize, requestFormat); - else - chosen = new QGLFramebufferObject(maybeRoundToNextPowerOfTwo(requestSize), requestFormat); - } - - if (!chosen->isValid()) { - delete chosen; - chosen = 0; - } - - return chosen; -} - -void QGLFramebufferObjectPool::release(QGLFramebufferObject *fbo) -{ - if (fbo) - m_fbos << fbo; -} - - -QPaintEngine* QGLPixmapGLPaintDevice::paintEngine() const -{ - return data->paintEngine(); -} - -void QGLPixmapGLPaintDevice::beginPaint() -{ - if (!data->isValid()) - return; - - // QGLPaintDevice::beginPaint will store the current binding and replace - // it with m_thisFBO: - m_thisFBO = data->m_renderFbo->handle(); - QGLPaintDevice::beginPaint(); - - Q_ASSERT(data->paintEngine()->type() == QPaintEngine::OpenGL2); - - // QPixmap::fill() is deferred until now, where we actually need to do the fill: - if (data->needsFill()) { - const QColor &c = data->fillColor(); - float alpha = c.alphaF(); - glDisable(GL_SCISSOR_TEST); - glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha); - glClear(GL_COLOR_BUFFER_BIT); - } - else if (!data->isUninitialized()) { - // If the pixmap (GL Texture) has valid content (it has been - // uploaded from an image or rendered into before), we need to - // copy it from the texture to the render FBO. - - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - -#if !defined(QT_OPENGL_ES_2) - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, data->width(), data->height(), 0, -999999, 999999); -#endif - - glViewport(0, 0, data->width(), data->height()); - - // Pass false to bind so it doesn't copy the FBO into the texture! - context()->drawTexture(QRect(0, 0, data->width(), data->height()), data->bind(false)); - } -} - -void QGLPixmapGLPaintDevice::endPaint() -{ - if (!data->isValid()) - return; - - data->copyBackFromRenderFbo(false); - - // Base's endPaint will restore the previous FBO binding - QGLPaintDevice::endPaint(); - - qgl_fbo_pool()->release(data->m_renderFbo); - data->m_renderFbo = 0; -} - -QGLContext* QGLPixmapGLPaintDevice::context() const -{ - data->ensureCreated(); - return data->m_ctx; -} - -QSize QGLPixmapGLPaintDevice::size() const -{ - return data->size(); -} - -bool QGLPixmapGLPaintDevice::alphaRequested() const -{ - return data->m_hasAlpha; -} - -void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d) -{ - data = d; -} - -int qt_gl_pixmap_serial = 0; - -QGLPixmapData::QGLPixmapData(PixelType type) - : QPixmapData(type, OpenGLClass) - , m_renderFbo(0) - , m_engine(0) - , m_ctx(0) - , nativeImageHandleProvider(0) - , nativeImageHandle(0) - , m_dirty(false) - , m_hasFillColor(false) - , m_hasAlpha(false) - , inLRU(false) - , failedToAlloc(false) - , inTexturePool(false) -{ - setSerialNumber(++qt_gl_pixmap_serial); - m_glDevice.setPixmapData(this); - - qt_gl_register_pixmap(this); -} - -QGLPixmapData::~QGLPixmapData() -{ - delete m_engine; - - destroyTexture(); - qt_gl_unregister_pixmap(this); -} - -void QGLPixmapData::destroyTexture() -{ - if (inTexturePool) { - QGLTexturePool *pool = QGLTexturePool::instance(); - if (m_texture.id) - pool->releaseTexture(this, m_texture.id); - } else { - if (m_texture.id) { - QGLWidget *shareWidget = qt_gl_share_widget(); - if (shareWidget) { - QGLShareContextScope ctx(shareWidget->context()); - glDeleteTextures(1, &m_texture.id); - } - } - } - m_texture.id = 0; - inTexturePool = false; - - releaseNativeImageHandle(); -} - -QPixmapData *QGLPixmapData::createCompatiblePixmapData() const -{ - return new QGLPixmapData(pixelType()); -} - -bool QGLPixmapData::isValid() const -{ - return w > 0 && h > 0; -} - -bool QGLPixmapData::isValidContext(const QGLContext *ctx) const -{ - if (ctx == m_ctx) - return true; - - const QGLContext *share_ctx = qt_gl_share_widget()->context(); - return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx); -} - -void QGLPixmapData::resize(int width, int height) -{ - if (width == w && height == h) - return; - - if (width <= 0 || height <= 0) { - width = 0; - height = 0; - } - - w = width; - h = height; - is_null = (w <= 0 || h <= 0); - d = pixelType() == QPixmapData::PixmapType ? 32 : 1; - - destroyTexture(); - - m_source = QVolatileImage(); - m_dirty = isValid(); - setSerialNumber(++qt_gl_pixmap_serial); -} - -void QGLPixmapData::ensureCreated() const -{ - if (!m_dirty) - return; - - m_dirty = false; - - if (nativeImageHandleProvider && !nativeImageHandle) - const_cast(this)->createFromNativeImageHandleProvider(); - - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - m_ctx = ctx; - - const GLenum internal_format = m_hasAlpha ? GL_RGBA : GL_RGB; -#ifdef QT_OPENGL_ES_2 - const GLenum external_format = internal_format; -#else - const GLenum external_format = qt_gl_preferredTextureFormat(); -#endif - const GLenum target = GL_TEXTURE_2D; - - GLenum type = GL_UNSIGNED_BYTE; - // Avoid conversion when pixmap is created from CFbsBitmap of EColor64K. - if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16) - type = GL_UNSIGNED_SHORT_5_6_5; - - m_texture.options &= ~QGLContext::MemoryManagedBindOption; - - if (!m_texture.id) { - m_texture.id = QGLTexturePool::instance()->createTextureForPixmap( - target, - 0, internal_format, - w, h, - external_format, - type, - const_cast(this)); - if (!m_texture.id) { - failedToAlloc = true; - return; - } - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - inTexturePool = true; - } else if (inTexturePool) { - glBindTexture(target, m_texture.id); - QGLTexturePool::instance()->useTexture(const_cast(this)); - } - - if (!m_source.isNull() && m_texture.id) { - if (external_format == GL_RGB) { - m_source.beginDataAccess(); - QImage tx; - if (type == GL_UNSIGNED_BYTE) - tx = m_source.imageRef().convertToFormat(QImage::Format_RGB888).mirrored(false, true); - else if (type == GL_UNSIGNED_SHORT_5_6_5) - tx = m_source.imageRef().mirrored(false, true); - m_source.endDataAccess(true); - - glBindTexture(target, m_texture.id); - if (!tx.isNull()) - glTexSubImage2D(target, 0, 0, 0, w, h, external_format, - type, tx.constBits()); - else - qWarning("QGLPixmapData: Failed to create GL_RGB image of size %dx%d", w, h); - } else { - // do byte swizzling ARGB -> RGBA - m_source.beginDataAccess(); - const QImage tx = ctx->d_func()->convertToGLFormat(m_source.imageRef(), true, external_format); - m_source.endDataAccess(true); - glBindTexture(target, m_texture.id); - if (!tx.isNull()) - glTexSubImage2D(target, 0, 0, 0, w, h, external_format, - type, tx.constBits()); - else - qWarning("QGLPixmapData: Failed to create GL_RGBA image of size %dx%d", w, h); - } - - if (useFramebufferObjects()) - m_source = QVolatileImage(); - } -} - - -void QGLPixmapData::fromImage(const QImage &image, - Qt::ImageConversionFlags flags) -{ - QImage img = image; - createPixmapForImage(img, flags, false); -} - -void QGLPixmapData::fromImageReader(QImageReader *imageReader, - Qt::ImageConversionFlags flags) -{ - QImage image = imageReader->read(); - if (image.isNull()) - return; - - createPixmapForImage(image, flags, true); -} - -bool QGLPixmapData::fromFile(const QString &filename, const char *format, - Qt::ImageConversionFlags flags) -{ - if (pixelType() == QPixmapData::BitmapType) - return QPixmapData::fromFile(filename, format, flags); - QFile file(filename); - if (file.open(QIODevice::ReadOnly)) { - QByteArray data = file.peek(64); - bool alpha; - if (m_texture.canBindCompressedTexture - (data.constData(), data.size(), format, &alpha)) { - resize(0, 0); - data = file.readAll(); - file.close(); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - QSize size = m_texture.bindCompressedTexture - (data.constData(), data.size(), format); - if (!size.isEmpty()) { - w = size.width(); - h = size.height(); - is_null = false; - d = 32; - m_hasAlpha = alpha; - m_source = QVolatileImage(); - m_dirty = isValid(); - return true; - } - return false; - } - } - - QImage image = QImageReader(filename, format).read(); - if (image.isNull()) - return false; - - createPixmapForImage(image, flags, true); - - return !isNull(); -} - -bool QGLPixmapData::fromData(const uchar *buffer, uint len, const char *format, - Qt::ImageConversionFlags flags) -{ - bool alpha; - const char *buf = reinterpret_cast(buffer); - if (m_texture.canBindCompressedTexture(buf, int(len), format, &alpha)) { - resize(0, 0); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - QSize size = m_texture.bindCompressedTexture(buf, int(len), format); - if (!size.isEmpty()) { - w = size.width(); - h = size.height(); - is_null = false; - d = 32; - m_hasAlpha = alpha; - m_source = QVolatileImage(); - m_dirty = isValid(); - return true; - } - } - - QByteArray a = QByteArray::fromRawData(reinterpret_cast(buffer), len); - QBuffer b(&a); - b.open(QIODevice::ReadOnly); - QImage image = QImageReader(&b, format).read(); - if (image.isNull()) - return false; - - createPixmapForImage(image, flags, true); - - return !isNull(); -} - -QImage::Format QGLPixmapData::idealFormat(QImage &image, Qt::ImageConversionFlags flags) -{ - QImage::Format format = QImage::Format_RGB32; - if (qApp->desktop()->depth() == 16) - format = QImage::Format_RGB16; - - if (image.hasAlphaChannel() - && ((flags & Qt::NoOpaqueDetection) - || const_cast(image).data_ptr()->checkForAlphaPixels())) - format = QImage::Format_ARGB32_Premultiplied; - - return format; -} - -void QGLPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace) -{ - if (image.size() == QSize(w, h)) - setSerialNumber(++qt_gl_pixmap_serial); - - resize(image.width(), image.height()); - - if (pixelType() == BitmapType) { - QImage convertedImage = image.convertToFormat(QImage::Format_MonoLSB); - if (image.format() == QImage::Format_MonoLSB) - convertedImage.detach(); - - m_source = QVolatileImage(convertedImage); - - } else { - QImage::Format format = idealFormat(image, flags); - - if (inPlace && image.data_ptr()->convertInPlace(format, flags)) { - m_source = QVolatileImage(image); - } else { - QImage convertedImage = image.convertToFormat(format); - - // convertToFormat won't detach the image if format stays the same. - if (image.format() == format) - convertedImage.detach(); - - m_source = QVolatileImage(convertedImage); - } - } - - m_dirty = true; - m_hasFillColor = false; - - m_hasAlpha = m_source.hasAlphaChannel(); - w = image.width(); - h = image.height(); - is_null = (w <= 0 || h <= 0); - d = m_source.depth(); - - destroyTexture(); -} - -bool QGLPixmapData::scroll(int dx, int dy, const QRect &rect) -{ - Q_UNUSED(dx); - Q_UNUSED(dy); - Q_UNUSED(rect); - return false; -} - -void QGLPixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - if (data->classId() != QPixmapData::OpenGLClass || !static_cast(data)->useFramebufferObjects()) { - QPixmapData::copy(data, rect); - return; - } - - const QGLPixmapData *other = static_cast(data); - if (other->m_renderFbo) { - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - - resize(rect.width(), rect.height()); - m_hasAlpha = other->m_hasAlpha; - ensureCreated(); - - if (!ctx->d_ptr->fbo) - glGenFramebuffers(1, &ctx->d_ptr->fbo); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, m_texture.id, 0); - - if (!other->m_renderFbo->isBound()) - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, other->m_renderFbo->handle()); - - glDisable(GL_SCISSOR_TEST); - if (ctx->d_ptr->active_engine && ctx->d_ptr->active_engine->type() == QPaintEngine::OpenGL2) - static_cast(ctx->d_ptr->active_engine)->invalidateState(); - - glBlitFramebufferEXT(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height(), - 0, 0, w, h, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); - } else { - QPixmapData::copy(data, rect); - } -} - -void QGLPixmapData::fill(const QColor &color) -{ - if (!isValid()) - return; - - bool hasAlpha = color.alpha() != 255; - if (hasAlpha && !m_hasAlpha) { - if (m_texture.id) { - destroyTexture(); - m_dirty = true; - } - m_hasAlpha = color.alpha() != 255; - } - - if (useFramebufferObjects()) { - m_source = QVolatileImage(); - m_hasFillColor = true; - m_fillColor = color; - } else { - forceToImage(); - - if (m_source.depth() == 32) { - m_source.fill(PREMUL(color.rgba())); - - } else if (m_source.depth() == 1) { - if (color == Qt::color1) - m_source.fill(1); - else - m_source.fill(0); - } - } -} - -bool QGLPixmapData::hasAlphaChannel() const -{ - return m_hasAlpha; -} - -QImage QGLPixmapData::fillImage(const QColor &color) const -{ - QImage img; - if (pixelType() == BitmapType) { - img = QImage(w, h, QImage::Format_MonoLSB); - - img.setColorCount(2); - img.setColor(0, QColor(Qt::color0).rgba()); - img.setColor(1, QColor(Qt::color1).rgba()); - - if (color == Qt::color1) - img.fill(1); - else - img.fill(0); - } else { - img = QImage(w, h, - m_hasAlpha - ? QImage::Format_ARGB32_Premultiplied - : QImage::Format_RGB32); - img.fill(PREMUL(color.rgba())); - } - return img; -} - -extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); - -QImage QGLPixmapData::toImage() const -{ - if (!isValid()) - return QImage(); - - if (m_renderFbo) { - copyBackFromRenderFbo(true); - } else if (!m_source.isNull()) { - // QVolatileImage::toImage() will make a copy always so no check - // for active painting is needed. - QImage img = m_source.toImage(); - if (img.format() == QImage::Format_MonoLSB) { - img.setColorCount(2); - img.setColor(0, QColor(Qt::color0).rgba()); - img.setColor(1, QColor(Qt::color1).rgba()); - } - return img; - } else if (m_dirty || m_hasFillColor) { - return fillImage(m_fillColor); - } else { - ensureCreated(); - } - - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - glBindTexture(GL_TEXTURE_2D, m_texture.id); - return qt_gl_read_texture(QSize(w, h), true, true); -} - -struct TextureBuffer -{ - QGLFramebufferObject *fbo; - QGL2PaintEngineEx *engine; -}; - -Q_GLOBAL_STATIC(QGLFramebufferObjectPool, _qgl_fbo_pool) -QGLFramebufferObjectPool* qgl_fbo_pool() -{ - return _qgl_fbo_pool(); -} - -void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const -{ - if (!isValid()) - return; - - m_hasFillColor = false; - - const QGLContext *share_ctx = qt_gl_share_widget()->context(); - QGLShareContextScope ctx(share_ctx); - - ensureCreated(); - - if (!ctx->d_ptr->fbo) - glGenFramebuffers(1, &ctx->d_ptr->fbo); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, m_texture.id, 0); - - const int x0 = 0; - const int x1 = w; - const int y0 = 0; - const int y1 = h; - - if (!m_renderFbo->isBound()) - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, m_renderFbo->handle()); - - glDisable(GL_SCISSOR_TEST); - - glBlitFramebufferEXT(x0, y0, x1, y1, - x0, y0, x1, y1, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - if (keepCurrentFboBound) { - glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo); - } else { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, m_renderFbo->handle()); - ctx->d_ptr->current_fbo = m_renderFbo->handle(); - } -} - -bool QGLPixmapData::useFramebufferObjects() const -{ -#ifdef Q_OS_SYMBIAN - // We don't want to use FBOs on Symbian - return false; -#else - return QGLFramebufferObject::hasOpenGLFramebufferObjects() - && QGLFramebufferObject::hasOpenGLFramebufferBlit() - && qt_gl_preferGL2Engine() - && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps -#endif -} - -QPaintEngine* QGLPixmapData::paintEngine() const -{ - if (!isValid()) - return 0; - - if (m_renderFbo) - return m_engine; - - if (useFramebufferObjects()) { - extern QGLWidget* qt_gl_share_widget(); - - if (!QGLContext::currentContext()) - qt_gl_share_widget()->makeCurrent(); - QGLShareContextScope ctx(qt_gl_share_widget()->context()); - - QGLFramebufferObjectFormat format; - format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format.setSamples(4); - format.setInternalTextureFormat(GLenum(m_hasAlpha ? GL_RGBA : GL_RGB)); - - m_renderFbo = qgl_fbo_pool()->acquire(size(), format); - - if (m_renderFbo) { - if (!m_engine) - m_engine = new QGL2PaintEngineEx; - return m_engine; - } - - qWarning() << "Failed to create pixmap texture buffer of size " << size() << ", falling back to raster paint engine"; - } - - // If the application wants to paint into the QPixmap, we first - // force it to QImage format and then paint into that. - // This is simpler than juggling multiple GL contexts. - const_cast(this)->forceToImage(); - - if (m_hasFillColor) { - m_source.fill(PREMUL(m_fillColor.rgba())); - m_hasFillColor = false; - } - return m_source.paintEngine(); -} - -extern QRgb qt_gl_convertToGLFormat(QRgb src_pixel, GLenum texture_format); - -// If copyBack is true, bind will copy the contents of the render -// FBO to the texture (which is not bound to the texture, as it's -// a multisample FBO). -GLuint QGLPixmapData::bind(bool copyBack) const -{ - if (m_renderFbo && copyBack) { - copyBackFromRenderFbo(true); - } else { - ensureCreated(); - } - - GLuint id = m_texture.id; - glBindTexture(GL_TEXTURE_2D, id); - - if (m_hasFillColor) { - if (!useFramebufferObjects()) { - m_source = QVolatileImage(w, h, QImage::Format_ARGB32_Premultiplied); - m_source.fill(PREMUL(m_fillColor.rgba())); - } - - m_hasFillColor = false; - - GLenum format = qt_gl_preferredTextureFormat(); - QImage tx(w, h, QImage::Format_ARGB32_Premultiplied); - tx.fill(qt_gl_convertToGLFormat(m_fillColor.rgba(), format)); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.constBits()); - } - - return id; -} - -QGLTexture* QGLPixmapData::texture() const -{ - return &m_texture; -} - -void QGLPixmapData::detachTextureFromPool() -{ - if (inTexturePool) { - QGLTexturePool::instance()->detachTexture(this); - inTexturePool = false; - } -} - -void QGLPixmapData::hibernate() -{ - // If the image was imported (e.g, from an SgImage under Symbian), then - // skip the hibernation, there is no sense in copying it back to main - // memory because the data is most likely shared between several processes. - bool skipHibernate = (m_texture.id && m_source.isNull()); -#if defined(Q_OS_SYMBIAN) - // However we have to proceed normally if the image was retrieved via - // a handle provider. - skipHibernate &= !nativeImageHandleProvider; -#endif - if (skipHibernate) - return; - - forceToImage(); - destroyTexture(); -} - -void QGLPixmapData::reclaimTexture() -{ - if (!inTexturePool) - return; - forceToImage(); - destroyTexture(); -} - -int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const -{ - if (w == 0) - return 0; - - switch (metric) { - case QPaintDevice::PdmWidth: - return w; - case QPaintDevice::PdmHeight: - return h; - case QPaintDevice::PdmNumColors: - return 0; - case QPaintDevice::PdmDepth: - return d; - case QPaintDevice::PdmWidthMM: - return qRound(w * 25.4 / qt_defaultDpiX()); - case QPaintDevice::PdmHeightMM: - return qRound(h * 25.4 / qt_defaultDpiY()); - case QPaintDevice::PdmDpiX: - case QPaintDevice::PdmPhysicalDpiX: - return qt_defaultDpiX(); - case QPaintDevice::PdmDpiY: - case QPaintDevice::PdmPhysicalDpiY: - return qt_defaultDpiY(); - default: - qWarning("QGLPixmapData::metric(): Invalid metric"); - return 0; - } -} - -// Force the pixmap data to be backed by some valid data. -void QGLPixmapData::forceToImage() -{ - if (!isValid()) - return; - - if (m_source.isNull()) { - QImage::Format format = QImage::Format_ARGB32_Premultiplied; - if (pixelType() == BitmapType) - format = QImage::Format_MonoLSB; - m_source = QVolatileImage(w, h, format); - } - - m_dirty = true; -} - -QGLPaintDevice *QGLPixmapData::glDevice() const -{ - return &m_glDevice; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp deleted file mode 100644 index 8a8eb38b7c..0000000000 --- a/src/opengl/qpixmapdata_x11gl_egl.cpp +++ /dev/null @@ -1,403 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include - -#include -#include -#include -#include - -#if !defined(QT_OPENGL_ES_1) -#include -#endif - -#ifndef QT_OPENGL_ES_2 -#include -#endif - -#include -#include - -#include "qpixmapdata_x11gl_p.h" - -QT_BEGIN_NAMESPACE - - -class QX11GLSharedContexts -{ -public: - QX11GLSharedContexts() - : rgbContext(0) - , argbContext(0) - , sharedQGLContext(0) - , sharePixmap(0) - { - EGLint rgbConfigId; - EGLint argbConfigId; - - do { - EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable); - EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, - QEgl::Renderable | QEgl::Translucent); - - eglGetConfigAttrib(QEgl::display(), rgbConfig, EGL_CONFIG_ID, &rgbConfigId); - eglGetConfigAttrib(QEgl::display(), argbConfig, EGL_CONFIG_ID, &argbConfigId); - - rgbContext = new QEglContext; - rgbContext->setConfig(rgbConfig); - rgbContext->createContext(); - - if (!rgbContext->isValid()) - break; - - // If the RGB & ARGB configs are the same, use the same egl context for both: - if (rgbConfig == argbConfig) - argbContext = rgbContext; - - // Otherwise, create a separate context to be used for ARGB pixmaps: - if (!argbContext) { - argbContext = new QEglContext; - argbContext->setConfig(argbConfig); - bool success = argbContext->createContext(rgbContext); - if (!success) { - qWarning("QX11GLPixmapData - RGB & ARGB contexts aren't shared"); - success = argbContext->createContext(); - if (!success) - argbContext = rgbContext; // Might work, worth a shot at least. - } - } - - if (!argbContext->isValid()) - break; - - // Create the pixmap which will be used to create the egl surface for the share QGLContext - QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); - rgbPixmapData->resize(8, 8); - rgbPixmapData->fill(Qt::red); - sharePixmap = new QPixmap(rgbPixmapData); - EGLSurface sharePixmapSurface = QEgl::createSurface(sharePixmap, rgbConfig); - rgbPixmapData->gl_surface = (void*)sharePixmapSurface; - - // Create the actual QGLContext which will be used for sharing - sharedQGLContext = new QGLContext(QX11GLPixmapData::glFormat()); - sharedQGLContext->d_func()->eglContext = rgbContext; - sharedQGLContext->d_func()->eglSurface = sharePixmapSurface; - sharedQGLContext->d_func()->valid = true; - qt_glformat_from_eglconfig(sharedQGLContext->d_func()->glFormat, rgbConfig); - - - valid = rgbContext->makeCurrent(sharePixmapSurface); - - // If the ARGB & RGB configs are different, check ARGB works too: - if (argbConfig != rgbConfig) { - QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType); - argbPixmapData->resize(8, 8); - argbPixmapData->fill(Qt::transparent); // Force ARGB - QPixmap argbPixmap(argbPixmapData); // destroys pixmap data when goes out of scope - EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig); - valid = argbContext->makeCurrent(argbPixmapSurface); - argbContext->doneCurrent(); - eglDestroySurface(QEgl::display(), argbPixmapSurface); - argbPixmapData->gl_surface = 0; - } - - if (!valid) { - qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString(); - break; - } - - // The pixmap surface destruction hooks are installed by QGLTextureCache, so we - // must make sure this is instanciated: - QGLTextureCache::instance(); - } while(0); - - if (!valid) - cleanup(); - else - qDebug("Using QX11GLPixmapData with EGL config %d for ARGB and config %d for RGB", argbConfigId, rgbConfigId); - - } - - ~QX11GLSharedContexts() { - cleanup(); - } - - void cleanup() { - if (sharedQGLContext) { - delete sharedQGLContext; - sharedQGLContext = 0; - } - if (argbContext && argbContext != rgbContext) - delete argbContext; - argbContext = 0; - - if (rgbContext) { - delete rgbContext; - rgbContext = 0; - } - - // Deleting the QPixmap will fire the pixmap destruction cleanup hooks which in turn - // will destroy the egl surface: - if (sharePixmap) { - delete sharePixmap; - sharePixmap = 0; - } - } - - bool isValid() { return valid;} - - // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need - // different contexts: - QEglContext *rgbContext; - QEglContext *argbContext; - - // The share context wraps the rgbContext and is used as the master of the context share - // group. As all other contexts will have the same egl context (or a shared one if rgb != argb) - // all QGLContexts will actually be sharing and can be in the same context group. - QGLContext *sharedQGLContext; -private: - QPixmap *sharePixmap; - bool valid; -}; - -static void qt_cleanup_x11gl_share_contexts(); - -Q_GLOBAL_STATIC_WITH_INITIALIZER(QX11GLSharedContexts, qt_x11gl_share_contexts, - { - qAddPostRoutine(qt_cleanup_x11gl_share_contexts); - }) - -static void qt_cleanup_x11gl_share_contexts() -{ - qt_x11gl_share_contexts()->cleanup(); -} - - -QX11GLSharedContexts* QX11GLPixmapData::sharedContexts() -{ - return qt_x11gl_share_contexts(); -} - -bool QX11GLPixmapData::hasX11GLPixmaps() -{ - static bool checkedForX11GLPixmaps = false; - static bool haveX11GLPixmaps = false; - - if (checkedForX11GLPixmaps) - return haveX11GLPixmaps; - - haveX11GLPixmaps = qt_x11gl_share_contexts()->isValid(); - checkedForX11GLPixmaps = true; - - return haveX11GLPixmaps; -} - -QX11GLPixmapData::QX11GLPixmapData() - : QX11PixmapData(QPixmapData::PixmapType), - ctx(0) -{ -} - -QX11GLPixmapData::~QX11GLPixmapData() -{ - if (ctx) - delete ctx; -} - - -void QX11GLPixmapData::fill(const QColor &color) -{ - if (ctx) { - ctx->makeCurrent(); - glFinish(); - eglWaitClient(); - } - - QX11PixmapData::fill(color); - XSync(X11->display, False); - - if (ctx) { - ctx->makeCurrent(); - eglWaitNative(EGL_CORE_NATIVE_ENGINE); - } -} - -void QX11GLPixmapData::copy(const QPixmapData *data, const QRect &rect) -{ - if (ctx) { - ctx->makeCurrent(); - glFinish(); - eglWaitClient(); - } - - QX11PixmapData::copy(data, rect); - XSync(X11->display, False); - - if (ctx) { - ctx->makeCurrent(); - eglWaitNative(EGL_CORE_NATIVE_ENGINE); - } -} - -bool QX11GLPixmapData::scroll(int dx, int dy, const QRect &rect) -{ - if (ctx) { - ctx->makeCurrent(); - glFinish(); - eglWaitClient(); - } - - bool success = QX11PixmapData::scroll(dx, dy, rect); - XSync(X11->display, False); - - if (ctx) { - ctx->makeCurrent(); - eglWaitNative(EGL_CORE_NATIVE_ENGINE); - } - - return success; -} - -#if !defined(QT_OPENGL_ES_1) -Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_pixmap_2_engine) -#endif - -#ifndef QT_OPENGL_ES_2 -Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_pixmap_engine) -#endif - - -QPaintEngine* QX11GLPixmapData::paintEngine() const -{ - // We need to create the context before beginPaint - do it here: - if (!ctx) { - ctx = new QGLContext(glFormat()); - Q_ASSERT(ctx->d_func()->eglContext == 0); - ctx->d_func()->eglContext = hasAlphaChannel() ? sharedContexts()->argbContext : sharedContexts()->rgbContext; - - // While we use a separate QGLContext for each pixmap, the underlying QEglContext is - // the same. So we must use a "fake" QGLContext and fool the texture cache into thinking - // each pixmap's QGLContext is sharing with this central one. The only place this is - // going to fail is where we the underlying EGL RGB and ARGB contexts aren't sharing. - ctx->d_func()->sharing = true; - QGLContextGroup::addShare(ctx, sharedContexts()->sharedQGLContext); - - // Update the glFormat for the QGLContext: - qt_glformat_from_eglconfig(ctx->d_func()->glFormat, ctx->d_func()->eglContext->config()); - } - - QPaintEngine* engine; - -#if defined(QT_OPENGL_ES_1) - engine = qt_gl_pixmap_engine(); -#elif defined(QT_OPENGL_ES_2) - engine = qt_gl_pixmap_2_engine(); -#else - if (qt_gl_preferGL2Engine()) - engine = qt_gl_pixmap_2_engine(); - else - engine = qt_gl_pixmap_engine(); -#endif - - - - // Support multiple painters on multiple pixmaps simultaniously - if (engine->isActive()) { - qWarning("Pixmap paint engine already active"); - -#if defined(QT_OPENGL_ES_1) - engine = new QOpenGLPaintEngine; -#elif defined(QT_OPENGL_ES_2) - engine = new QGL2PaintEngineEx; -#else - if (qt_gl_preferGL2Engine()) - engine = new QGL2PaintEngineEx; - else - engine = new QOpenGLPaintEngine; -#endif - - engine->setAutoDestruct(true); - return engine; - } - - return engine; -} - -void QX11GLPixmapData::beginPaint() -{ -// qDebug("QX11GLPixmapData::beginPaint()"); - // TODO: Check to see if the surface is renderable - if ((EGLSurface)gl_surface == EGL_NO_SURFACE) { - QPixmap tmpPixmap(this); - EGLConfig cfg = ctx->d_func()->eglContext->config(); - Q_ASSERT(cfg != QEGL_NO_CONFIG); - -// qDebug("QX11GLPixmapData - using EGL Config ID %d", ctx->d_func()->eglContext->configAttrib(EGL_CONFIG_ID)); - EGLSurface surface = QEgl::createSurface(&tmpPixmap, cfg); - if (surface == EGL_NO_SURFACE) { - qWarning() << "Error creating EGL surface for pixmap:" << QEgl::errorString(); - return; - } - gl_surface = (void*)surface; - ctx->d_func()->eglSurface = surface; - ctx->d_func()->valid = true; - } - QGLPaintDevice::beginPaint(); -} - -QGLContext* QX11GLPixmapData::context() const -{ - return ctx; -} - -QSize QX11GLPixmapData::size() const -{ - return QSize(w, h); -} - - -QGLFormat QX11GLPixmapData::glFormat() -{ - return QGLFormat::defaultFormat(); //### -} - -QT_END_NAMESPACE diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h deleted file mode 100644 index 0a6c4e8f2f..0000000000 --- a/src/opengl/qpixmapdata_x11gl_p.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QPIXMAPDATA_X11GL_P_H -#define QPIXMAPDATA_X11GL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include - -#include - -#ifndef QT_NO_EGL -#include -#endif - -QT_BEGIN_NAMESPACE - -class QX11GLSharedContexts; - -class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice -{ -public: - QX11GLPixmapData(); - virtual ~QX11GLPixmapData(); - - // Re-implemented from QX11PixmapData: - void fill(const QColor &color); - void copy(const QPixmapData *data, const QRect &rect); - bool scroll(int dx, int dy, const QRect &rect); - - // Re-implemented from QGLPaintDevice - QPaintEngine* paintEngine() const; // Also re-implements QX11PixmapData::paintEngine - void beginPaint(); - QGLContext* context() const; - QSize size() const; - - static bool hasX11GLPixmaps(); - static QGLFormat glFormat(); - static QX11GLSharedContexts* sharedContexts(); - -private: - mutable QGLContext* ctx; -}; - - -QT_END_NAMESPACE - -#endif // QPIXMAPDATA_X11GL_P_H diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp deleted file mode 100644 index d3e7e5178e..0000000000 --- a/src/opengl/qwindowsurface_gl.cpp +++ /dev/null @@ -1,1104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include "qdebug.h" - -#ifdef Q_WS_X11 -#include -#include - -#ifndef QT_OPENGL_ES -#include -#include -#endif -#endif //Q_WS_X11 - -#include -#include - -#include - -#include - -#include -#include - -#ifndef QT_OPENGL_ES_2 -#include -#endif - -#ifndef GLX_ARB_multisample -#define GLX_SAMPLE_BUFFERS_ARB 100000 -#define GLX_SAMPLES_ARB 100001 -#endif - -#ifndef QT_NO_EGL -#include -#endif - -#ifdef Q_WS_QPA -#include -#endif - -QT_BEGIN_NAMESPACE - -// -// QGLWindowSurface -// -class QGLGlobalShareWidget -{ -public: - QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) { - created = true; - } - - QGLWidget *shareWidget() { - if (!initializing && !widget && !cleanedUp) { - initializing = true; - widget = new QGLWidget(QGLFormat(QGL::SingleBuffer | QGL::NoDepthBuffer | QGL::NoStencilBuffer)); - widget->resize(1, 1); - - // We don't need this internal widget to appear in QApplication::topLevelWidgets() - if (QWidgetPrivate::allWidgets) - QWidgetPrivate::allWidgets->remove(widget); - initializing = false; - } - return widget; - } - - // destroys the share widget and prevents recreation - void cleanup() { - QGLWidget *w = widget; - cleanedUp = true; - widget = 0; - delete w; - } - - // destroys the share widget, but allows it to be recreated later on - void destroy() { - if (cleanedUp) - return; - - QGLWidget *w = widget; - - // prevent potential recursions - cleanedUp = true; - widget = 0; - delete w; - cleanedUp = false; - } - - static bool cleanedUp; - static bool created; - - QGLPixmapData *firstPixmap; - int widgetRefCount; - -private: - QGLWidget *widget; - bool initializing; -}; - -bool QGLGlobalShareWidget::cleanedUp = false; -bool QGLGlobalShareWidget::created = false; - -static void qt_cleanup_gl_share_widget(); -Q_GLOBAL_STATIC_WITH_INITIALIZER(QGLGlobalShareWidget, _qt_gl_share_widget, - { - qAddPostRoutine(qt_cleanup_gl_share_widget); - }) - -static void qt_cleanup_gl_share_widget() -{ - if (QGLGlobalShareWidget::created) - _qt_gl_share_widget()->cleanup(); -} - -QGLWidget* qt_gl_share_widget() -{ - if (QGLGlobalShareWidget::cleanedUp) - return 0; - return _qt_gl_share_widget()->shareWidget(); -} - -void qt_destroy_gl_share_widget() -{ - if (QGLGlobalShareWidget::created) - _qt_gl_share_widget()->destroy(); -} - -const QGLContext *qt_gl_share_context() -{ - QGLWidget *widget = qt_gl_share_widget(); - if (widget) - return widget->context(); - return 0; -} - -#ifdef QGL_USE_TEXTURE_POOL -void qt_gl_register_pixmap(QGLPixmapData *pd) -{ - QGLGlobalShareWidget *shared = _qt_gl_share_widget(); - pd->next = shared->firstPixmap; - pd->prev = 0; - if (shared->firstPixmap) - shared->firstPixmap->prev = pd; - shared->firstPixmap = pd; -} - -void qt_gl_unregister_pixmap(QGLPixmapData *pd) -{ - if (pd->next) - pd->next->prev = pd->prev; - if (pd->prev) { - pd->prev->next = pd->next; - } else { - QGLGlobalShareWidget *shared = _qt_gl_share_widget(); - if (shared) - shared->firstPixmap = pd->next; - } -} - -void qt_gl_hibernate_pixmaps() -{ - QGLGlobalShareWidget *shared = _qt_gl_share_widget(); - - // Scan all QGLPixmapData objects in the system and hibernate them. - QGLPixmapData *pd = shared->firstPixmap; - while (pd != 0) { - pd->hibernate(); - pd = pd->next; - } -} -#endif - -struct QGLWindowSurfacePrivate -{ - QGLFramebufferObject *fbo; - QGLPixelBuffer *pb; - GLuint tex_id; - GLuint pb_tex_id; - - int tried_fbo : 1; - int tried_pb : 1; - int destructive_swap_buffers : 1; - int geometry_updated : 1; - int did_paint : 1; - - QGLContext *ctx; - - QList contexts; - - QRegion paintedRegion; - QSize size; - - QSize textureSize; - - QList buffers; - QGLWindowSurfaceGLPaintDevice glDevice; - QGLWindowSurface* q_ptr; - - bool swap_region_support; -}; - -QGLFormat QGLWindowSurface::surfaceFormat; -QGLWindowSurface::SwapMode QGLWindowSurface::swapBehavior = QGLWindowSurface::AutomaticSwap; - -void QGLWindowSurfaceGLPaintDevice::endPaint() -{ - glFlush(); - QGLPaintDevice::endPaint(); -} - -QSize QGLWindowSurfaceGLPaintDevice::size() const -{ - return d->size; -} - -QGLContext* QGLWindowSurfaceGLPaintDevice::context() const -{ - return d->ctx; -} - - -int QGLWindowSurfaceGLPaintDevice::metric(PaintDeviceMetric m) const -{ - QWindow *window = d->q_ptr->window(); - QPlatformScreen *screen = QPlatformScreen::platformScreenForWindow(window); - if (!screen) { - if (m == PdmDpiX || m == PdmDpiY) - return 72; - } - int val; - if (m == PdmWidth) { - val = window->geometry().width(); - } else if (m == PdmWidthMM) { - val = window->geometry().width() * screen->physicalSize().width() / screen->geometry().width(); - } else if (m == PdmHeight) { - val = window->geometry().height(); - } else if (m == PdmHeightMM) { - val = window->geometry().height() * screen->physicalSize().height() / screen->geometry().height(); - } else if (m == PdmDepth) { - val = screen->depth(); - } else if (m == PdmDpiX || m == PdmPhysicalDpiX) { - val = qRound(screen->geometry().width() / double(screen->physicalSize().width() / 25.4)); - } else if (m == PdmDpiY || m == PdmPhysicalDpiY) { - val = qRound(screen->geometry().height() / double(screen->physicalSize().height() / 25.4)); - } else { - val = 1 << qMax(24, screen->depth()); - } - return val; -} - -QPaintEngine *QGLWindowSurfaceGLPaintDevice::paintEngine() const -{ - return qt_qgl_paint_engine(); -} - -QGLWindowSurface::QGLWindowSurface(QWindow *window) - : QWindowSurface(window), d_ptr(new QGLWindowSurfacePrivate) -{ -// Q_ASSERT(window->isTopLevel()); - d_ptr->pb = 0; - d_ptr->fbo = 0; - d_ptr->ctx = 0; - d_ptr->tex_id = 0; -#if defined (QT_OPENGL_ES_2) - d_ptr->tried_fbo = true; - d_ptr->tried_pb = true; -#else - d_ptr->tried_fbo = false; - d_ptr->tried_pb = false; -#endif - d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull(); - d_ptr->glDevice.d = d_ptr; - d_ptr->q_ptr = this; - d_ptr->geometry_updated = false; - d_ptr->did_paint = false; - d_ptr->swap_region_support = false; -} - -QGLWindowSurface::~QGLWindowSurface() -{ - if (d_ptr->ctx) - glDeleteTextures(1, &d_ptr->tex_id); -#ifndef Q_WS_QPA // Dont delete the contexts. Destroying the window does that for us - foreach(QGLContext **ctx, d_ptr->contexts) { - delete *ctx; - *ctx = 0; - } -#endif - delete d_ptr->pb; - delete d_ptr->fbo; - delete d_ptr; - - if (QGLGlobalShareWidget::cleanedUp) - return; - - --(_qt_gl_share_widget()->widgetRefCount); - -#ifdef QGL_USE_TEXTURE_POOL - if (_qt_gl_share_widget()->widgetRefCount <= 0) { - // All of the widget window surfaces have been destroyed - // but we still have GL pixmaps active. Ask them to hibernate - // to free up GPU resources until a widget is shown again. - // This may eventually cause the EGLContext to be destroyed - // because nothing in the system needs a context, which will - // free up even more GPU resources. - qt_gl_hibernate_pixmaps(); - - // Destroy the context if necessary. - if (!qt_gl_share_widget()->context()->isSharing()) - qt_destroy_gl_share_widget(); - } -#endif // QGL_USE_TEXTURE_POOL -} - -void QGLWindowSurface::deleted(QObject *object) -{ -#if 0 - QWidget *widget = qobject_cast(object); - if (widget) { - if (widget == window()) { - // Make sure that the fbo is destroyed before destroying its context. - delete d_ptr->fbo; - d_ptr->fbo = 0; - } - -#ifndef Q_WS_QPA //no need to specifically delete the QGLContext as it will be deleted by QWidget - QWidgetPrivate *widgetPrivate = widget->d_func(); - if (widgetPrivate->extraData()) { - union { QGLContext **ctxPtrPtr; void **voidPtrPtr; }; - voidPtrPtr = &widgetPrivate->extraData()->glContext; - int index = d_ptr->contexts.indexOf(ctxPtrPtr); - if (index != -1) { - delete *ctxPtrPtr; - *ctxPtrPtr = 0; - d_ptr->contexts.removeAt(index); - } - } -#endif - } -#endif -} - -void QGLWindowSurface::hijackWindow(QWindow *window) -{ -#if 0 - QWidgetPrivate *widgetPrivate = widget->d_func(); - widgetPrivate->createExtra(); - if (widgetPrivate->extraData()->glContext) - return; - - QGLContext *ctx = NULL; - - // For translucent top-level widgets we need alpha in the format. - if (widget->testAttribute(Qt::WA_TranslucentBackground)) { - QGLFormat modFormat(surfaceFormat); - modFormat.setSampleBuffers(false); - modFormat.setSamples(0); - modFormat.setAlpha(true); - ctx = new QGLContext(modFormat, widget); - } else - ctx = new QGLContext(surfaceFormat, widget); - - ctx->create(qt_gl_share_context()); - - if (widget != qt_gl_share_widget()) - ++(_qt_gl_share_widget()->widgetRefCount); - -#ifndef QT_NO_EGL - static bool checkedForNOKSwapRegion = false; - static bool haveNOKSwapRegion = false; - - if (!checkedForNOKSwapRegion) { - haveNOKSwapRegion = QEgl::hasExtension("EGL_NOK_swap_region2"); - checkedForNOKSwapRegion = true; - - if (haveNOKSwapRegion) - qDebug() << "Found EGL_NOK_swap_region2 extension. Using partial updates."; - } - - d_ptr->destructive_swap_buffers = true; - if (ctx->d_func()->eglContext->configAttrib(EGL_SURFACE_TYPE)&EGL_SWAP_BEHAVIOR_PRESERVED_BIT) { - EGLint swapBehavior; - if (eglQuerySurface(ctx->d_func()->eglContext->display(), ctx->d_func()->eglSurface - , EGL_SWAP_BEHAVIOR, &swapBehavior)) { - d_ptr->destructive_swap_buffers = (swapBehavior != EGL_BUFFER_PRESERVED); - } - } - - d_ptr->swap_region_support = haveNOKSwapRegion; -#endif - - widgetPrivate->extraData()->glContext = ctx; - - union { QGLContext **ctxPtrPtr; void **voidPtrPtr; }; - - connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*))); - - voidPtrPtr = &widgetPrivate->extraData()->glContext; - d_ptr->contexts << ctxPtrPtr; -#ifndef Q_OS_SYMBIAN - qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size(); -#endif -#endif -} - -QGLContext *QGLWindowSurface::context() const -{ - return d_ptr->ctx; -} - -QPaintDevice *QGLWindowSurface::paintDevice() -{ - updateGeometry(); - - if (d_ptr->pb) - return d_ptr->pb; - - if (d_ptr->ctx) - return &d_ptr->glDevice; - -#if 0 - QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); - ctx->makeCurrent(); -#endif - - Q_ASSERT(d_ptr->fbo); - return d_ptr->fbo; -} - -static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &src = QRectF()); - -void QGLWindowSurface::beginPaint(const QRegion &) -{ - d_ptr->did_paint = true; - updateGeometry(); - - int clearFlags = 0; - -#if 0 - QGLContext *ctx = reinterpret_cast(window()->d_func()->extraData()->glContext); -#endif - const QGLContext *ctx = QGLContext::currentContext(); - - if (!ctx) - return; - - if (ctx->d_func()->workaround_needsFullClearOnEveryFrame) - clearFlags = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; - else if (ctx->format().alpha()) - clearFlags = GL_COLOR_BUFFER_BIT; - - if (clearFlags) { - if (d_ptr->fbo) - d_ptr->fbo->bind(); - - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(clearFlags); - - if (d_ptr->fbo) - d_ptr->fbo->release(); - } -} - -void QGLWindowSurface::endPaint(const QRegion &rgn) -{ - if (context()) - d_ptr->paintedRegion |= rgn; - - d_ptr->buffers.clear(); -} - -static void blitTexture(QGLContext *ctx, GLuint texture, const QSize &viewport, const QSize &texSize, const QRect &targetRect, const QRect &sourceRect) -{ - glDisable(GL_DEPTH_TEST); - glDisable(GL_SCISSOR_TEST); - glDisable(GL_BLEND); - - glViewport(0, 0, viewport.width(), viewport.height()); - - QGLShaderProgram *blitProgram = - QGLEngineSharedShaders::shadersForContext(ctx)->blitProgram(); - blitProgram->bind(); - blitProgram->setUniformValue("imageTexture", 0 /*QT_IMAGE_TEXTURE_UNIT*/); - - // The shader manager's blit program does not multiply the - // vertices by the pmv matrix, so we need to do the effect - // of the orthographic projection here ourselves. - QRectF r; - qreal w = viewport.width(); - qreal h = viewport.height(); - r.setLeft((targetRect.left() / w) * 2.0f - 1.0f); - if (targetRect.right() == (viewport.width() - 1)) - r.setRight(1.0f); - else - r.setRight((targetRect.right() / w) * 2.0f - 1.0f); - r.setBottom((targetRect.top() / h) * 2.0f - 1.0f); - if (targetRect.bottom() == (viewport.height() - 1)) - r.setTop(1.0f); - else - r.setTop((targetRect.bottom() / w) * 2.0f - 1.0f); - - drawTexture(r, texture, texSize, sourceRect); -} - - -void QGLWindowSurface::flush(QWindow *window, const QRegion &rgn, const QPoint &offset) -{ -#if 0 - //### Find out why d_ptr->geometry_updated isn't always false. - // flush() should not be called when d_ptr->geometry_updated is true. It assumes that either - // d_ptr->fbo or d_ptr->pb is allocated and has the correct size. - if (d_ptr->geometry_updated) - return; - - // did_paint is set to true in ::beginPaint. ::beginPaint means that we - // at least cleared the background (= painted something). In EGL API it's a - // mistake to call swapBuffers if nothing was painted unless - // EGL_BUFFER_PRESERVED is set. This check protects the flush func from - // being executed if it's for nothing. - if (!d_ptr->destructive_swap_buffers && !d_ptr->did_paint) - return; - -#ifdef Q_OS_SYMBIAN - if (window() != widget) { - // For performance reasons we don't support - // flushing native child widgets on Symbian. - // It breaks overlapping native child widget - // rendering in some cases but we prefer performance. - return; - } -#endif - - - QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); - Q_ASSERT(parent); - -#if !defined(Q_WS_QPA) - if (!geometry().isValid()) - return; -#else - if (!size().isValid()) - return; -#endif - - // Needed to support native child-widgets... - hijackWindow(parent); - - QRect br = rgn.boundingRect().translated(offset); - br = br.intersected(window()->rect()); - QPoint wOffset = qt_qwidget_data(parent)->wrect.topLeft(); - QRect rect = br.translated(-offset - wOffset); - - const GLenum target = GL_TEXTURE_2D; - Q_UNUSED(target); - - if (QGLWindowSurface::swapBehavior == QGLWindowSurface::KillSwap) - return; - - if (context()) { - context()->makeCurrent(); - - if (context()->format().doubleBuffer()) { -#if !defined(QT_OPENGL_ES_2) - if (d_ptr->destructive_swap_buffers) { - glBindTexture(target, d_ptr->tex_id); - - QVector rects = d_ptr->paintedRegion.rects(); - for (int i = 0; i < rects.size(); ++i) { - QRect br = rects.at(i); - if (br.isEmpty()) - continue; - - const uint bottom = window()->height() - (br.y() + br.height()); - glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); - } - - glBindTexture(target, 0); - - QRegion dirtyRegion = QRegion(window()->rect()) - d_ptr->paintedRegion; - - if (!dirtyRegion.isEmpty()) { - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); -#ifndef QT_OPENGL_ES - glOrtho(0, window()->width(), window()->height(), 0, -999999, 999999); -#else - glOrthof(0, window()->width(), window()->height(), 0, -999999, 999999); -#endif - glViewport(0, 0, window()->width(), window()->height()); - - QVector rects = dirtyRegion.rects(); - glColor4f(1, 1, 1, 1); - for (int i = 0; i < rects.size(); ++i) { - QRect rect = rects.at(i); - if (rect.isEmpty()) - continue; - - drawTexture(rect, d_ptr->tex_id, window()->size(), rect); - } - } - } -#endif - bool doingPartialUpdate = false; - if (d_ptr->swap_region_support) { - if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AutomaticSwap) - doingPartialUpdate = br.width() * br.height() < parent->geometry().width() * parent->geometry().height() * 0.2; - else if (QGLWindowSurface::swapBehavior == QGLWindowSurface::AlwaysPartialSwap) - doingPartialUpdate = true; - } - - QGLContext *ctx = reinterpret_cast(parent->d_func()->extraData()->glContext); - if (widget != window()) { - if (initializeOffscreenTexture(window()->size())) - qWarning() << "QGLWindowSurface: Flushing to native child widget, may lead to significant performance loss"; - glBindTexture(target, d_ptr->tex_id); - - const uint bottom = window()->height() - (br.y() + br.height()); - glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); - - glBindTexture(target, 0); - - ctx->makeCurrent(); - if (doingPartialUpdate) - blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), rect, br); - else - blitTexture(ctx, d_ptr->tex_id, parent->size(), window()->size(), parent->rect(), parent->rect().translated(offset + wOffset)); - } - - if (doingPartialUpdate) - ctx->d_func()->swapRegion(br); - else - ctx->swapBuffers(); - - d_ptr->paintedRegion = QRegion(); - } else { - glFlush(); - } - return; - } - - QGLContext *previous_ctx = const_cast(QGLContext::currentContext()); - QGLContext *ctx = reinterpret_cast(parent->d_func()->extraData()->glContext); - - // QPainter::end() should have unbound the fbo, otherwise something is very wrong... - Q_ASSERT(!d_ptr->fbo || !d_ptr->fbo->isBound()); - - if (ctx != previous_ctx) { - ctx->makeCurrent(); - } - - QSize size = widget->rect().size(); - if (d_ptr->destructive_swap_buffers && ctx->format().doubleBuffer()) { - rect = parent->rect(); - br = rect.translated(wOffset + offset); - size = parent->size(); - } - - glDisable(GL_SCISSOR_TEST); - - if (d_ptr->fbo && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit)) { - const int h = d_ptr->fbo->height(); - - const int sx0 = br.left(); - const int sx1 = br.left() + br.width(); - const int sy0 = h - (br.top() + br.height()); - const int sy1 = h - br.top(); - - const int tx0 = rect.left(); - const int tx1 = rect.left() + rect.width(); - const int ty0 = parent->height() - (rect.top() + rect.height()); - const int ty1 = parent->height() - rect.top(); - - if (window() == parent || d_ptr->fbo->format().samples() <= 1) { - if (ctx->d_ptr->current_fbo != 0) - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); - - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); - - glBlitFramebufferEXT(sx0, sy0, sx1, sy1, - tx0, ty0, tx1, ty1, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0); - } else { - // can't do sub-region blits with multisample FBOs - QGLFramebufferObject *temp = qgl_fbo_pool()->acquire(d_ptr->fbo->size(), QGLFramebufferObjectFormat()); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, temp->handle()); - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, d_ptr->fbo->handle()); - - glBlitFramebufferEXT(0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(), - 0, 0, d_ptr->fbo->width(), d_ptr->fbo->height(), - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, temp->handle()); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, 0); - - glBlitFramebufferEXT(sx0, sy0, sx1, sy1, - tx0, ty0, tx1, ty1, - GL_COLOR_BUFFER_BIT, - GL_NEAREST); - - glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, 0); - - qgl_fbo_pool()->release(temp); - } - - ctx->d_ptr->current_fbo = 0; - } -#if !defined(QT_OPENGL_ES_2) - else { - GLuint texture; - if (d_ptr->fbo) { - texture = d_ptr->fbo->texture(); - } else { - d_ptr->pb->makeCurrent(); - glBindTexture(target, d_ptr->pb_tex_id); - const uint bottom = window()->height() - (br.y() + br.height()); - glCopyTexSubImage2D(target, 0, br.x(), bottom, br.x(), bottom, br.width(), br.height()); - texture = d_ptr->pb_tex_id; - glBindTexture(target, 0); - } - - glDisable(GL_DEPTH_TEST); - - if (d_ptr->fbo) { - d_ptr->fbo->release(); - } else { - ctx->makeCurrent(); - } - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); -#ifndef QT_OPENGL_ES - glOrtho(0, size.width(), size.height(), 0, -999999, 999999); -#else - glOrthof(0, size.width(), size.height(), 0, -999999, 999999); -#endif - glViewport(0, 0, size.width(), size.height()); - - glColor4f(1, 1, 1, 1); - drawTexture(rect, texture, window()->size(), br); - - if (d_ptr->fbo) - d_ptr->fbo->bind(); - } -#else - // OpenGL/ES 2.0 version of the fbo blit. - else if (d_ptr->fbo) { - Q_UNUSED(target); - - if (d_ptr->fbo->isBound()) - d_ptr->fbo->release(); - - blitTexture(ctx, d_ptr->fbo->texture(), size, window()->size(), rect, br); - } -#endif - - if (ctx->format().doubleBuffer()) - ctx->swapBuffers(); - else - glFlush(); -#endif - d_ptr->did_paint = false; -} - - -#if !defined(Q_WS_QPA) -void QGLWindowSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); - d_ptr->geometry_updated = true; -} -#else -void QGLWindowSurface::resize(const QSize &size) -{ - QWindowSurface::resize(size); - d_ptr->geometry_updated = true; -} -#endif - -void QGLWindowSurface::updateGeometry() { -#if 0 - if (!d_ptr->geometry_updated) - return; - d_ptr->geometry_updated = false; - - bool hijack(true); - QWidgetPrivate *wd = window()->d_func(); - if (wd->extraData() && wd->extraData()->glContext) { -#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes - if (d_ptr->size != geometry().size()) { - if (window() != qt_gl_share_widget()) - --(_qt_gl_share_widget()->widgetRefCount); - - delete wd->extraData()->glContext; - wd->extraData()->glContext = 0; - d_ptr->ctx = 0; - } - else -#endif - { - hijack = false; // we already have gl context for widget - } - } - - if (hijack) - hijackWindow(window()); - - QGLContext *ctx = reinterpret_cast(wd->extraData()->glContext); - -#ifdef Q_WS_MAC - ctx->updatePaintDevice(); -#endif - - QSize surfSize = geometry().size(); - - if (surfSize.width() <= 0 || surfSize.height() <= 0) - return; - - if (d_ptr->size == surfSize) - return; - - d_ptr->size = surfSize; - - if (d_ptr->ctx) { -#ifndef QT_OPENGL_ES_2 - if (d_ptr->destructive_swap_buffers) - initializeOffscreenTexture(surfSize); -#endif - return; - } - - const GLenum target = GL_TEXTURE_2D; - if (d_ptr->destructive_swap_buffers - && (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject) - && (d_ptr->fbo || !d_ptr->tried_fbo) - && qt_gl_preferGL2Engine()) - { - d_ptr->tried_fbo = true; - ctx->d_ptr->internal_context = true; - ctx->makeCurrent(); - delete d_ptr->fbo; - - QGLFramebufferObjectFormat format; - format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); - format.setInternalTextureFormat(GLenum(GL_RGBA)); - format.setTextureTarget(target); - - if (QGLExtensions::glExtensions() & QGLExtensions::FramebufferBlit) - format.setSamples(8); - - d_ptr->fbo = new QGLFramebufferObject(surfSize, format); - - if (d_ptr->fbo->isValid()) { - qDebug() << "Created Window Surface FBO" << surfSize - << "with samples" << d_ptr->fbo->format().samples(); - return; - } else { - qDebug() << "QGLWindowSurface: Failed to create valid FBO, falling back"; - delete d_ptr->fbo; - d_ptr->fbo = 0; - } - } - -#if !defined(QT_OPENGL_ES_2) && !defined(Q_WS_QPA) //QPA doesn't support pixelbuffers - if (d_ptr->destructive_swap_buffers && (d_ptr->pb || !d_ptr->tried_pb)) { - d_ptr->tried_pb = true; - - if (d_ptr->pb) { - d_ptr->pb->makeCurrent(); - glDeleteTextures(1, &d_ptr->pb_tex_id); - } - - delete d_ptr->pb; - - d_ptr->pb = new QGLPixelBuffer(surfSize.width(), surfSize.height(), - QGLFormat(QGL::SampleBuffers | QGL::StencilBuffer | QGL::DepthBuffer), - qt_gl_share_widget()); - - if (d_ptr->pb->isValid()) { - qDebug() << "Created Window Surface Pixelbuffer, Sample buffers:" << d_ptr->pb->format().sampleBuffers(); - d_ptr->pb->makeCurrent(); - - glGenTextures(1, &d_ptr->pb_tex_id); - glBindTexture(target, d_ptr->pb_tex_id); - glTexImage2D(target, 0, GL_RGBA, surfSize.width(), surfSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glBindTexture(target, 0); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0, d_ptr->pb->width(), d_ptr->pb->height(), 0, -999999, 999999); - - d_ptr->pb->d_ptr->qctx->d_func()->internal_context = true; - return; - } else { - qDebug() << "QGLWindowSurface: Failed to create valid pixelbuffer, falling back"; - delete d_ptr->pb; - d_ptr->pb = 0; - } - } -#endif // !defined(QT_OPENGL_ES_2) !defined(Q_WS_QPA) - - ctx->makeCurrent(); - -#ifndef QT_OPENGL_ES_2 - if (d_ptr->destructive_swap_buffers) - initializeOffscreenTexture(surfSize); -#endif -#ifndef Q_OS_SYMBIAN - qDebug() << "QGLWindowSurface: Using plain widget as window surface" << this; -#endif - d_ptr->ctx = ctx; - d_ptr->ctx->d_ptr->internal_context = true; -#endif -} - -bool QGLWindowSurface::initializeOffscreenTexture(const QSize &size) -{ - if (size == d_ptr->textureSize) - return false; - - glGenTextures(1, &d_ptr->tex_id); - glBindTexture(GL_TEXTURE_2D, d_ptr->tex_id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, 0); - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glBindTexture(GL_TEXTURE_2D, 0); - - d_ptr->textureSize = size; - return true; -} - -bool QGLWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ -#if 0 - // this code randomly fails currently for unknown reasons - return false; - - if (!d_ptr->pb) - return false; - - d_ptr->pb->makeCurrent(); - - QRect br = area.boundingRect(); - -#if 0 - // ## workaround driver issue (scrolling by these deltas is unbearably slow for some reason) - // ## maybe we should use glCopyTexSubImage insteadk - if (dx == 1 || dx == -1 || dy == 1 || dy == -1 || dy == 2) - return false; - - glRasterPos2i(br.x() + dx, br.y() + br.height() + dy); - glCopyPixels(br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), GL_COLOR); - return true; -#endif - - const GLenum target = GL_TEXTURE_2D; - - glBindTexture(target, d_ptr->tex_id); - glCopyTexImage2D(target, 0, GL_RGBA, br.x(), d_ptr->pb->height() - (br.y() + br.height()), br.width(), br.height(), 0); - glBindTexture(target, 0); - - drawTexture(br.translated(dx, dy), d_ptr->tex_id, window()->size()); -#endif - return true; -} - -static void drawTexture(const QRectF &rect, GLuint tex_id, const QSize &texSize, const QRectF &br) -{ - const GLenum target = GL_TEXTURE_2D; - QRectF src = br.isEmpty() - ? QRectF(QPointF(), texSize) - : QRectF(QPointF(br.x(), texSize.height() - br.bottom()), br.size()); - - if (target == GL_TEXTURE_2D) { - qreal width = texSize.width(); - qreal height = texSize.height(); - - src.setLeft(src.left() / width); - src.setRight(src.right() / width); - src.setTop(src.top() / height); - src.setBottom(src.bottom() / height); - } - - const GLfloat tx1 = src.left(); - const GLfloat tx2 = src.right(); - const GLfloat ty1 = src.top(); - const GLfloat ty2 = src.bottom(); - - GLfloat texCoordArray[4*2] = { - tx1, ty2, tx2, ty2, tx2, ty1, tx1, ty1 - }; - - GLfloat vertexArray[4*2]; - extern void qt_add_rect_to_array(const QRectF &r, GLfloat *array); // qpaintengine_opengl.cpp - qt_add_rect_to_array(rect, vertexArray); - -#if !defined(QT_OPENGL_ES_2) - glVertexPointer(2, GL_FLOAT, 0, vertexArray); - glTexCoordPointer(2, GL_FLOAT, 0, texCoordArray); - - glBindTexture(target, tex_id); - glEnable(target); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - glDisable(target); - glBindTexture(target, 0); -#else - glVertexAttribPointer(QT_VERTEX_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, vertexArray); - glVertexAttribPointer(QT_TEXTURE_COORDS_ATTR, 2, GL_FLOAT, GL_FALSE, 0, texCoordArray); - - glBindTexture(target, tex_id); - - glEnableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glEnableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); - glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); - - glBindTexture(target, 0); -#endif -} - -QWindowSurface::WindowSurfaceFeatures QGLWindowSurface::features() const -{ - WindowSurfaceFeatures features = 0; - if (!d_ptr->destructive_swap_buffers || d_ptr->swap_region_support) - features |= PartialUpdates; - if (!d_ptr->destructive_swap_buffers) - features |= PreservedContents; - return features; -} - -QT_END_NAMESPACE - diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h deleted file mode 100644 index c7b0d10efa..0000000000 --- a/src/opengl/qwindowsurface_gl_p.h +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSURFACE_GL_P_H -#define QWINDOWSURFACE_GL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QPaintDevice; -class QPoint; -class QRegion; -class QWindow; -struct QGLWindowSurfacePrivate; - -Q_OPENGL_EXPORT QGLWidget* qt_gl_share_widget(); -Q_OPENGL_EXPORT void qt_destroy_gl_share_widget(); - -class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice -{ -public: - QPaintEngine* paintEngine() const; - void endPaint(); - QSize size() const; - int metric(PaintDeviceMetric m) const; - QGLContext* context() const; - QGLWindowSurfacePrivate* d; -}; - -class Q_OPENGL_EXPORT QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice -{ - Q_OBJECT -public: - QGLWindowSurface(QWindow *window); - ~QGLWindowSurface(); - - QPaintDevice *paintDevice(); - void flush(QWindow *window, const QRegion ®ion, const QPoint &offset); - -#if !defined(Q_WS_QPA) - void setGeometry(const QRect &rect); -#else - virtual void resize(const QSize &size); -#endif - - void updateGeometry(); - bool scroll(const QRegion &area, int dx, int dy); - - void beginPaint(const QRegion ®ion); - void endPaint(const QRegion ®ion); - - WindowSurfaceFeatures features() const; - - QGLContext *context() const; - - static QGLFormat surfaceFormat; - - enum SwapMode { AutomaticSwap, AlwaysFullSwap, AlwaysPartialSwap, KillSwap }; - static SwapMode swapBehavior; - -private slots: - void deleted(QObject *object); - -private: - void hijackWindow(QWindow *window); - bool initializeOffscreenTexture(const QSize &size); - - QGLWindowSurfacePrivate *d_ptr; -}; - -QT_END_NAMESPACE - -#endif // QWINDOWSURFACE_GL_P_H - diff --git a/src/opengl/qwindowsurface_x11gl.cpp b/src/opengl/qwindowsurface_x11gl.cpp deleted file mode 100644 index bec0ea7587..0000000000 --- a/src/opengl/qwindowsurface_x11gl.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -#include -#include - -#include "qwindowsurface_x11gl_p.h" -#include "qpixmapdata_x11gl_p.h" - -QT_BEGIN_NAMESPACE - -QX11GLWindowSurface::QX11GLWindowSurface(QWidget* window) - : QWindowSurface(window), m_windowGC(0), m_pixmapGC(0), m_window(window) -{ -} - -QX11GLWindowSurface::~QX11GLWindowSurface() -{ - if (m_windowGC) - XFree(m_windowGC); - if (m_pixmapGC) - XFree(m_pixmapGC); -} - -QPaintDevice *QX11GLWindowSurface::paintDevice() -{ - return &m_backBuffer; -} - -extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp - -void QX11GLWindowSurface::flush(QWidget *widget, const QRegion &widgetRegion, const QPoint &offset) -{ - // We don't need to know the widget which initiated the flush. Instead we just use the offset - // to translate the widgetRegion: - Q_UNUSED(widget); - - if (m_backBuffer.isNull()) { - qDebug("QX11GLWindowSurface::flush() - backBuffer is null, not flushing anything"); - return; - } - - Q_ASSERT(window()->size() != m_backBuffer.size()); - - // Wait for all GL rendering to the back buffer pixmap to complete before trying to - // copy it to the window. We do this by making sure the pixmap's context is current - // and then call eglWaitClient. The EGL 1.4 spec says eglWaitClient doesn't have to - // block, just that "All rendering calls...are guaranteed to be executed before native - // rendering calls". This makes it potentially less expensive than glFinish. - QGLContext* ctx = static_cast(m_backBuffer.data_ptr().data())->context(); - if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) - ctx->makeCurrent(); - eglWaitClient(); - - if (m_windowGC == 0) { - XGCValues attribs; - attribs.graphics_exposures = False; - m_windowGC = XCreateGC(X11->display, m_window->handle(), GCGraphicsExposures, &attribs); - } - - int rectCount; - XRectangle *rects = (XRectangle *)qt_getClipRects(widgetRegion, rectCount); - if (rectCount <= 0) - return; - - XSetClipRectangles(X11->display, m_windowGC, 0, 0, rects, rectCount, YXBanded); - - QRect dirtyRect = widgetRegion.boundingRect().translated(-offset); - XCopyArea(X11->display, m_backBuffer.handle(), m_window->handle(), m_windowGC, - dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(), - dirtyRect.x(), dirtyRect.y()); - - // Make sure the blit of the update from the back buffer to the window completes - // before allowing rendering to start again to the back buffer. Otherwise the GPU - // might start rendering to the back buffer again while the blit takes place. - eglWaitNative(EGL_CORE_NATIVE_ENGINE); -} - -void QX11GLWindowSurface::setGeometry(const QRect &rect) -{ - if (rect.width() > m_backBuffer.size().width() || rect.height() > m_backBuffer.size().height()) { - QX11GLPixmapData *pd = new QX11GLPixmapData; - QSize newSize = rect.size(); - pd->resize(newSize.width(), newSize.height()); - m_backBuffer = QPixmap(pd); - if (window()->testAttribute(Qt::WA_TranslucentBackground)) - m_backBuffer.fill(Qt::transparent); - if (m_pixmapGC) { - XFreeGC(X11->display, m_pixmapGC); - m_pixmapGC = 0; - } - } - - QWindowSurface::setGeometry(rect); -} - -bool QX11GLWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - if (m_backBuffer.isNull()) - return false; - - Q_ASSERT(m_backBuffer.data_ptr()->classId() == QPixmapData::X11Class); - - // Make sure all GL rendering is complete before starting the scroll operation: - QGLContext* ctx = static_cast(m_backBuffer.data_ptr().data())->context(); - if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) - ctx->makeCurrent(); - eglWaitClient(); - - if (!m_pixmapGC) - m_pixmapGC = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); - - foreach (const QRect& rect, area.rects()) { - XCopyArea(X11->display, m_backBuffer.handle(), m_backBuffer.handle(), m_pixmapGC, - rect.x(), rect.y(), rect.width(), rect.height(), - rect.x()+dx, rect.y()+dy); - } - - // Make sure the scroll operation is complete before allowing GL rendering to resume - eglWaitNative(EGL_CORE_NATIVE_ENGINE); - - return true; -} - - -QPixmap QX11GLWindowSurface::grabWidget(const QWidget *widget, const QRect& rect) const -{ - if (!widget || m_backBuffer.isNull()) - return QPixmap(); - - QRect srcRect; - - // make sure the rect is inside the widget & clip to widget's rect - if (!rect.isEmpty()) - srcRect = rect & widget->rect(); - else - srcRect = widget->rect(); - - if (srcRect.isEmpty()) - return QPixmap(); - - // If it's a child widget we have to translate the coordinates - if (widget != window()) - srcRect.translate(widget->mapTo(window(), QPoint(0, 0))); - - QPixmap::x11SetDefaultScreen(widget->x11Info().screen()); - - QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType); - pmd->resize(srcRect.width(), srcRect.height()); - QPixmap px(pmd); - - GC tmpGc = XCreateGC(X11->display, m_backBuffer.handle(), 0, 0); - - // Make sure all GL rendering is complete before copying the window - QGLContext* ctx = static_cast(m_backBuffer.pixmapData())->context(); - if (QGLContext::currentContext() != ctx && ctx && ctx->isValid()) - ctx->makeCurrent(); - eglWaitClient(); - - // Copy srcRect from the backing store to the new pixmap - XSetGraphicsExposures(X11->display, tmpGc, False); - XCopyArea(X11->display, m_backBuffer.handle(), px.handle(), tmpGc, - srcRect.x(), srcRect.y(), srcRect.width(), srcRect.height(), 0, 0); - XFreeGC(X11->display, tmpGc); - - // Wait until the copy has finised before allowing more rendering into the back buffer - eglWaitNative(EGL_CORE_NATIVE_ENGINE); - - return px; -} - -QT_END_NAMESPACE diff --git a/src/opengl/qwindowsurface_x11gl_p.h b/src/opengl/qwindowsurface_x11gl_p.h deleted file mode 100644 index 737997b879..0000000000 --- a/src/opengl/qwindowsurface_x11gl_p.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtOpenGL module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used 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. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSURFACE_X11GL_P_H -#define QWINDOWSURFACE_X11GL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include - -QT_BEGIN_NAMESPACE - -class QX11GLWindowSurface : public QWindowSurface -{ -public: - QX11GLWindowSurface(QWidget* window); - virtual ~QX11GLWindowSurface(); - - // Inherreted from QWindowSurface - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - void setGeometry(const QRect &rect); - bool scroll(const QRegion &area, int dx, int dy); - QPixmap grabWidget(const QWidget *widget, const QRect& rectangle = QRect()) const; - -private: - GC m_windowGC; - GC m_pixmapGC; - QPixmap m_backBuffer; - QWidget *m_window; -}; - - -QT_END_NAMESPACE - -#endif // QWINDOWSURFACE_X11GL_P_H -- cgit v1.2.3