summaryrefslogtreecommitdiffstats
path: root/src/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl')
-rw-r--r--src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp8
-rw-r--r--src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglcustomshaderstage.cpp8
-rw-r--r--src/opengl/gl2paintengineex/qglcustomshaderstage_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp8
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache.cpp8
-rw-r--r--src/opengl/gl2paintengineex/qglgradientcache_p.h8
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp89
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h11
-rw-r--r--src/opengl/opengl.pro7
-rw-r--r--src/opengl/qgl.cpp540
-rw-r--r--src/opengl/qgl.h19
-rw-r--r--src/opengl/qgl_cl_p.h8
-rw-r--r--src/opengl/qgl_egl.cpp8
-rw-r--r--src/opengl/qgl_egl_p.h8
-rw-r--r--src/opengl/qgl_mac.mm8
-rw-r--r--src/opengl/qgl_p.h163
-rw-r--r--src/opengl/qgl_qws.cpp8
-rw-r--r--src/opengl/qgl_win.cpp8
-rw-r--r--src/opengl/qgl_wince.cpp8
-rw-r--r--src/opengl/qgl_x11.cpp9
-rw-r--r--src/opengl/qgl_x11egl.cpp8
-rw-r--r--src/opengl/qglcolormap.cpp8
-rw-r--r--src/opengl/qglcolormap.h8
-rw-r--r--src/opengl/qglextensions.cpp8
-rw-r--r--src/opengl/qglextensions_p.h8
-rw-r--r--src/opengl/qglframebufferobject.cpp201
-rw-r--r--src/opengl/qglframebufferobject.h18
-rw-r--r--src/opengl/qglframebufferobject_p.h152
-rw-r--r--src/opengl/qglpaintdevice.cpp187
-rw-r--r--src/opengl/qglpaintdevice_p.h112
-rw-r--r--src/opengl/qglpaintdevice_qws.cpp8
-rw-r--r--src/opengl/qglpaintdevice_qws_p.h8
-rw-r--r--src/opengl/qglpixelbuffer.cpp25
-rw-r--r--src/opengl/qglpixelbuffer.h10
-rw-r--r--src/opengl/qglpixelbuffer_egl.cpp8
-rw-r--r--src/opengl/qglpixelbuffer_mac.mm8
-rw-r--r--src/opengl/qglpixelbuffer_p.h23
-rw-r--r--src/opengl/qglpixelbuffer_win.cpp8
-rw-r--r--src/opengl/qglpixelbuffer_x11.cpp8
-rw-r--r--src/opengl/qglpixmapfilter.cpp8
-rw-r--r--src/opengl/qglpixmapfilter_p.h8
-rw-r--r--src/opengl/qglscreen_qws.cpp8
-rw-r--r--src/opengl/qglscreen_qws.h8
-rw-r--r--src/opengl/qglshaderprogram.cpp315
-rw-r--r--src/opengl/qglshaderprogram.h8
-rw-r--r--src/opengl/qglwindowsurface_qws.cpp8
-rw-r--r--src/opengl/qglwindowsurface_qws_p.h8
-rw-r--r--src/opengl/qgraphicsshadereffect.cpp8
-rw-r--r--src/opengl/qgraphicsshadereffect_p.h8
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp8
-rw-r--r--src/opengl/qgraphicssystem_gl_p.h8
-rw-r--r--src/opengl/qpaintengine_opengl.cpp132
-rw-r--r--src/opengl/qpaintengine_opengl_p.h8
-rw-r--r--src/opengl/qpixmapdata_gl.cpp131
-rw-r--r--src/opengl/qpixmapdata_gl_p.h60
-rw-r--r--src/opengl/qwindowsurface_gl.cpp73
-rw-r--r--src/opengl/qwindowsurface_gl_p.h27
-rw-r--r--src/opengl/util/fragmentprograms_p.h8
-rw-r--r--src/opengl/util/generator.cpp8
-rwxr-xr-xsrc/opengl/util/glsl_to_include.sh8
63 files changed, 1566 insertions, 1074 deletions
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp
index 2dd830d..866d1a2 100644
--- a/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp
+++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
index a241c41..08ce234 100644
--- a/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
+++ b/src/opengl/gl2paintengineex/qgl2pexvertexarray_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp
index 0b93320..24606bc 100644
--- a/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp
+++ b/src/opengl/gl2paintengineex/qglcustomshaderstage.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
index 5f9d86a..25f5c2f 100644
--- a/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
+++ b/src/opengl/gl2paintengineex/qglcustomshaderstage_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index e7c11fd..2d1885c 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index 0cfdcf1..423df99 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 6a928c4..acd4461 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp
index 7db3e63..4b2b2a0 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache.cpp
+++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h
index bbebf30..3813f39 100644
--- a/src/opengl/gl2paintengineex/qglgradientcache_p.h
+++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 0ad454f..c87941b 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -711,7 +711,7 @@ void QGL2PaintEngineEx::beginNativePainting()
{ mtx.dx(), mtx.dy(), 0, mtx.m33() }
};
- const QSize sz = d->drawable.size();
+ const QSize sz = d->device->size();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -1309,21 +1309,20 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
Q_D(QGL2PaintEngineEx);
// qDebug("QGL2PaintEngineEx::begin()");
- d->drawable.setDevice(pdev);
- d->ctx = d->drawable.context();
-
- if (d->ctx->d_ptr->active_engine) {
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(d->ctx->d_ptr->active_engine);
- QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr.data());
- p->transferMode(BrushDrawingMode);
- p->drawable.doneCurrent();
- }
+ if (pdev->devType() == QInternal::OpenGL)
+ d->device = static_cast<QGLPaintDevice*>(pdev);
+ else
+ d->device = QGLPaintDevice::getDevice(pdev);
+
+ if (!d->device)
+ return false;
+
+ d->ctx = d->device->context();
d->ctx->d_ptr->active_engine = this;
d->last_created_state = 0;
- d->drawable.makeCurrent();
- QSize sz = d->drawable.size();
+ QSize sz = d->device->size();
d->width = sz.width();
d->height = sz.height();
d->mode = BrushDrawingMode;
@@ -1334,8 +1333,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->shaderManager = new QGLEngineShaderManager(d->ctx);
- glViewport(0, 0, d->width, d->height);
-
d->brushTextureDirty = true;
d->brushUniformsDirty = true;
d->matrixDirty = true;
@@ -1344,10 +1341,12 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->simpleShaderDepthUniformDirty = true;
d->depthUniformDirty = true;
d->opacityUniformDirty = true;
- d->needsSync = false;
-
+ d->needsSync = true;
d->use_system_clip = !systemClip().isEmpty();
+
+ d->device->beginPaint();
+
if (!d->inRenderText) {
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
@@ -1359,30 +1358,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
glDisable(GL_MULTISAMPLE);
#endif
- QGLPixmapData *source = d->drawable.copyOnBegin();
- if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) {
- if (d->drawable.hasTransparentBackground())
- glClearColor(0.0, 0.0, 0.0, 0.0);
- else {
- const QColor &c = d->drawable.backgroundColor();
- float alpha = c.alphaF();
- glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
- }
- glClear(GL_COLOR_BUFFER_BIT);
- } else if (source) {
- QGLContext *ctx = d->ctx;
-
- d->transferMode(ImageDrawingMode);
-
- glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- source->bind(false);
-
- QRect rect(0, 0, source->width(), source->height());
- d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
- d->drawTexture(QRectF(rect), QRectF(rect), rect.size(), true);
- }
-
- d->systemStateChanged();
return true;
}
@@ -1390,19 +1365,11 @@ bool QGL2PaintEngineEx::end()
{
Q_D(QGL2PaintEngineEx);
QGLContext *ctx = d->ctx;
- if (ctx->d_ptr->active_engine != this) {
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine);
- if (engine && engine->isActive()) {
- QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr.data());
- p->transferMode(BrushDrawingMode);
- p->drawable.doneCurrent();
- }
- d->drawable.makeCurrent();
- }
glUseProgram(0);
d->transferMode(BrushDrawingMode);
- d->drawable.swapBuffers();
+ d->device->endPaint();
+
#if defined(Q_WS_X11)
// On some (probably all) drivers, deleting an X pixmap which has been bound to a texture
// before calling glFinish/swapBuffers renders garbage. Presumably this is because X deletes
@@ -1411,7 +1378,6 @@ bool QGL2PaintEngineEx::end()
// them here, after swapBuffers, where they can be safely deleted.
ctx->d_func()->boundPixmaps.clear();
#endif
- d->drawable.doneCurrent();
d->ctx->d_ptr->active_engine = 0;
d->resetGLState();
@@ -1428,21 +1394,12 @@ void QGL2PaintEngineEx::ensureActive()
QGLContext *ctx = d->ctx;
if (isActive() && ctx->d_ptr->active_engine != this) {
- QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(ctx->d_ptr->active_engine);
- if (engine && engine->isActive()) {
- QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr.data());
- p->transferMode(BrushDrawingMode);
- p->drawable.doneCurrent();
- }
- d->drawable.context()->makeCurrent();
- d->drawable.makeCurrent();
-
ctx->d_ptr->active_engine = this;
d->needsSync = true;
- } else {
- d->drawable.context()->makeCurrent();
}
+ d->device->ensureActiveTarget();
+
if (d->needsSync) {
glViewport(0, 0, d->width, d->height);
glDepthMask(false);
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 2b16019..34f4eb8 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -58,6 +58,7 @@
#include <private/qpaintengineex_p.h>
#include <private/qglengineshadermanager_p.h>
#include <private/qgl2pexvertexarray_p.h>
+#include <private/qglpaintdevice_p.h>
enum EngineMode {
ImageDrawingMode,
@@ -199,7 +200,7 @@ public:
static QGLEngineShaderManager* shaderManagerForEngine(QGL2PaintEngineEx *engine) { return engine->d_func()->shaderManager; }
QGL2PaintEngineEx* q;
- QGLDrawable drawable;
+ QGLPaintDevice* device;
int width, height;
QGLContext *ctx;
EngineMode mode;
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 560d31f..d479c2e 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -22,13 +22,18 @@ HEADERS += qgl.h \
qglpixelbuffer.h \
qglpixelbuffer_p.h \
qglframebufferobject.h \
- qglextensions_p.h
+ qglframebufferobject_p.h \
+ qglextensions_p.h \
+ qglpaintdevice_p.h \
+
SOURCES += qgl.cpp \
qglcolormap.cpp \
qglpixelbuffer.cpp \
qglframebufferobject.cpp \
qglextensions.cpp \
+ qglpaintdevice.cpp \
+
!contains(QT_CONFIG, opengles2) {
HEADERS += qpaintengine_opengl_p.h
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 3c23149..799c749 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -63,6 +63,7 @@
#include "qpixmap.h"
#include "qimage.h"
+#include "qmatrix4x4.h"
#include "qgl_p.h"
#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
@@ -140,6 +141,48 @@ QGLSignalProxy *QGLSignalProxy::instance()
return theSignalProxy();
}
+
+class QGLEngineSelector
+{
+public:
+ QGLEngineSelector() : engineType(QPaintEngine::MaxUser) { }
+
+ void setPreferredPaintEngine(QPaintEngine::Type type) {
+ if (type == QPaintEngine::OpenGL || type == QPaintEngine::OpenGL2)
+ engineType = type;
+ }
+
+ QPaintEngine::Type preferredPaintEngine() {
+ if (engineType == QPaintEngine::MaxUser) {
+ // No user-set engine - use the defaults
+#if defined(QT_OPENGL_ES_2)
+ engineType = QPaintEngine::OpenGL2;
+#else
+ // We can't do this in the constructor for this object because it
+ // needs to be called *before* the QApplication constructor
+ if ((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
+ && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty())
+ engineType = QPaintEngine::OpenGL2;
+ else
+ engineType = QPaintEngine::OpenGL;
+#endif
+ }
+ return engineType;
+ }
+
+private:
+ QPaintEngine::Type engineType;
+};
+
+Q_GLOBAL_STATIC(QGLEngineSelector, qgl_engine_selector)
+
+
+bool qt_gl_preferGL2Engine()
+{
+ return qgl_engine_selector()->preferredPaintEngine() == QPaintEngine::OpenGL2;
+}
+
+
/*!
\namespace QGL
\inmodule QtOpenGL
@@ -180,6 +223,32 @@ QGLSignalProxy *QGLSignalProxy::instance()
\sa {Sample Buffers Example}
*/
+/*!
+ \fn void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
+
+ \since 4.6
+
+ Sets the preferred OpenGL paint engine that is used to draw onto
+ QGLWidgets, QGLPixelBuffers and QGLFrameBufferObjects with QPainter
+ in Qt.
+
+ The \a engineType parameter specifies which of the GL engines to
+ use. Only \c QPaintEngine::OpenGL and \c QPaintEngine::OpenGL2 are
+ valid parameters to this function. All other values are ignored.
+
+ By default, the \c QPaintEngine::OpenGL2 engine is used if GL/GLES
+ version 2.0 is available, otherwise \c QPaintEngine::OpenGL is
+ used.
+
+ \warning This function must be called before the QApplication
+ constructor is called.
+*/
+void QGL::setPreferredPaintEngine(QPaintEngine::Type engineType)
+{
+ qgl_engine_selector()->setPreferredPaintEngine(engineType);
+}
+
+
/*****************************************************************************
QGLFormat implementation
*****************************************************************************/
@@ -251,46 +320,24 @@ QGLSignalProxy *QGLSignalProxy::instance()
\sa QGLContext, QGLWidget
*/
-static inline void transform_point(GLdouble out[4], const GLdouble m[16], const GLdouble in[4])
+static inline void qgluProject
+ (qreal objx, qreal objy, qreal objz,
+ const QMatrix4x4& model, const QMatrix4x4& proj, const GLint viewport[4],
+ GLfloat *winx, GLfloat *winy, GLfloat* winz)
{
-#define M(row,col) m[col*4+row]
- out[0] =
- M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];
- out[1] =
- M(1, 0) * in[0] + M(1, 1) * in[1] + M(1, 2) * in[2] + M(1, 3) * in[3];
- out[2] =
- M(2, 0) * in[0] + M(2, 1) * in[1] + M(2, 2) * in[2] + M(2, 3) * in[3];
- out[3] =
- M(3, 0) * in[0] + M(3, 1) * in[1] + M(3, 2) * in[2] + M(3, 3) * in[3];
-#undef M
-}
-
-static inline GLint qgluProject(GLdouble objx, GLdouble objy, GLdouble objz,
- const GLdouble model[16], const GLdouble proj[16],
- const GLint viewport[4],
- GLdouble * winx, GLdouble * winy, GLdouble * winz)
-{
- GLdouble in[4], out[4];
+ QVector4D transformed = proj.map(model.map(QVector4D(objx, objy, objz, 1)));
- in[0] = objx;
- in[1] = objy;
- in[2] = objz;
- in[3] = 1.0;
- transform_point(out, model, in);
- transform_point(in, proj, out);
+ qreal w = transformed.w();
+ if (w == 0.0f)
+ w = 1.0f; // Just in case!
- if (in[3] == 0.0)
- return GL_FALSE;
+ qreal x = transformed.x() / w;
+ qreal y = transformed.y() / w;
- in[0] /= in[3];
- in[1] /= in[3];
- in[2] /= in[3];
+ *winx = viewport[0] + (1 + x) * viewport[2] / 2;
+ *winy = viewport[1] + (1 + y) * viewport[3] / 2;
- *winx = viewport[0] + (1 + in[0]) * viewport[2] / 2;
- *winy = viewport[1] + (1 + in[1]) * viewport[3] / 2;
-
- *winz = (1 + in[2]) / 2;
- return GL_TRUE;
+ *winz = (1 + transformed.z() / w) / 2;
}
/*!
@@ -1313,6 +1360,9 @@ bool operator!=(const QGLFormat& a, const QGLFormat& b)
*****************************************************************************/
QGLContextPrivate::~QGLContextPrivate()
{
+ if (!reference->deref())
+ delete reference;
+
if (!group->m_refs.deref()) {
Q_ASSERT(group->context() == q_ptr);
delete group;
@@ -1352,7 +1402,6 @@ void QGLContextPrivate::init(QPaintDevice *dev, const QGLFormat &format)
crWin = false;
initDone = false;
sharing = false;
- clear_on_painter_begin = true;
max_texture_size = -1;
version_flags_cached = false;
version_flags = QGLFormat::OpenGL_Version_None;
@@ -2073,6 +2122,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
case QImage::Format_RGB16:
pixel_type = GL_UNSIGNED_SHORT_5_6_5;
texture_format = GL_RGB;
+ format = GL_RGB;
break;
case QImage::Format_RGB32:
if (format == GL_RGBA)
@@ -4113,6 +4163,30 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str,
p->setFont(old_font);
}
+#if defined(GL_OES_VERSION_1_0) && !defined(GL_OES_VERSION_1_1)
+
+// OpenGL/ES 1.0 cannot fetch viewports from the GL server.
+// We therefore create a default viewport to simulate the fetch.
+
+static void qt_gl_get_viewport(GLint *view, int deviceWidth, int deviceHeight)
+{
+ view[0] = 0;
+ view[1] = 0;
+ view[2] = deviceWidth;
+ view[3] = deviceHeight;
+}
+
+#else
+
+static void qt_gl_get_viewport(GLint *view, int deviceWidth, int deviceHeight)
+{
+ Q_UNUSED(deviceWidth);
+ Q_UNUSED(deviceHeight);
+ glGetIntegerv(GL_VIEWPORT, view);
+}
+
+#endif
+
/*!
Renders the string \a str into the GL context of this widget.
@@ -4138,13 +4212,19 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
GLint view[4];
#ifndef QT_OPENGL_ES
bool use_scissor_testing = glIsEnabled(GL_SCISSOR_TEST);
- if (!use_scissor_testing)
- glGetIntegerv(GL_VIEWPORT, &view[0]);
#else
bool use_scissor_testing = false;
#endif
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
+ if (!use_scissor_testing) {
+ qt_gl_get_viewport(&view[0], width, height);
+ } else {
+ view[0] = 0;
+ view[1] = 0;
+ view[2] = width;
+ view[3] = height;
+ }
bool auto_swap = autoBufferSwap();
QPaintEngine *engine = paintEngine();
@@ -4176,7 +4256,7 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
- d->glcx->d_func()->clear_on_painter_begin = false;
+ d->disable_clear_on_painter_begin = true;
if (engine->type() == QPaintEngine::OpenGL2) {
qt_save_gl_state();
#ifndef QT_OPENGL_ES_2
@@ -4206,7 +4286,7 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
p->end();
delete p;
setAutoBufferSwap(auto_swap);
- d->glcx->d_func()->clear_on_painter_begin = true;
+ d->disable_clear_on_painter_begin = false;
if (engine->type() == QPaintEngine::OpenGL2)
qt_restore_gl_state();
}
@@ -4216,12 +4296,95 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font,
#endif
}
+#if defined(QT_OPENGL_ES_2) || \
+ (defined(GL_OES_VERSION_1_0) && !defined(GL_OES_VERSION_1_1))
+
+// OpenGL/ES 1.0 cannot fetch matrices from the GL server.
+// OpenGL/ES 2.0 does not use fixed-function matrices at all.
+// We therefore create some default matrices to simulate the fetch.
+
+static QMatrix4x4 qt_gl_projection_matrix(int deviceWidth, int deviceHeight)
+{
+ QMatrix4x4 m;
+ m.ortho(0, deviceWidth, deviceHeight, 0, -1, 1);
+ return m;
+}
+
+static QMatrix4x4 qt_gl_modelview_matrix(void)
+{
+ return QMatrix4x4();
+}
+
+#else // !QT_OPENGL_ES_2
+
+static QMatrix4x4 qt_gl_fetch_matrix(GLenum type)
+{
+ QMatrix4x4 matrix;
+#if defined(QT_OPENGL_ES_1_CL)
+ GLfixed mat[16];
+ glGetFixedv(type, mat);
+ qreal *m = matrix.data();
+ for (int index = 0; index < 16; ++index)
+ m[index] = vt2f(mat[index]);
+#else
+ if (sizeof(qreal) == sizeof(GLfloat)) {
+ glGetFloatv(type, reinterpret_cast<GLfloat *>(matrix.data()));
+#if !defined(QT_OPENGL_ES)
+ } else if (sizeof(qreal) == sizeof(GLdouble)) {
+ glGetDoublev(type, reinterpret_cast<GLdouble *>(matrix.data()));
+#endif
+ } else {
+ GLfloat mat[16];
+ glGetFloatv(type, mat);
+ qreal *m = matrix.data();
+ for (int index = 0; index < 16; ++index)
+ m[index] = mat[index];
+ }
+#endif
+ matrix.inferSpecialType();
+ return matrix;
+}
+
+static QMatrix4x4 qt_gl_projection_matrix(int deviceWidth, int deviceHeight)
+{
+ Q_UNUSED(deviceWidth);
+ Q_UNUSED(deviceHeight);
+ return qt_gl_fetch_matrix(GL_PROJECTION_MATRIX);
+}
+
+static QMatrix4x4 qt_gl_modelview_matrix(void)
+{
+ return qt_gl_fetch_matrix(GL_MODELVIEW_MATRIX);
+}
+
+#endif // !QT_OPENGL_ES_2
+
/*! \overload
\a x, \a y and \a z are specified in scene or object coordinates
relative to the currently set projection and model matrices. This
can be useful if you want to annotate models with text labels and
have the labels move with the model as it is rotated etc.
+
+ This function fetches the modelview matrix, projection matrix, and
+ current viewport from the GL server to map (\a x, \a y, \a z)
+ into window co-ordinates. This entails several round-trips to the GL
+ server which will probably impact performance.
+
+ Fetching the modelview and projection matrices is not supported
+ under OpenGL/ES 1.0 and OpenGL/ES 2.0 so a default orthographic
+ projection will be used to map the co-ordinates on those platforms.
+ This probably will not give results that are consistent with desktop
+ and OpenGL/ES 1.1 systems. Fetching the viewport is not supported
+ under OpenGL/ES 1.0, so the full device will be used as the viewport.
+
+ This function is deprecated because it is non-portable. It is
+ recommended that the application map the co-ordinates itself using
+ application-provided matrix data that reflects the desired
+ transformation. Then use QPainter::drawText() to draw \a str at
+ the mapped position.
+
+ \sa QMatrix4x4
*/
void QGLWidget::renderText(double x, double y, double z, const QString &str, const QFont &font, int)
{
@@ -4233,16 +4396,15 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
int width = d->glcx->device()->width();
int height = d->glcx->device()->height();
- GLdouble model[4][4], proj[4][4];
+
+ QMatrix4x4 model = qt_gl_modelview_matrix();
+ QMatrix4x4 proj = qt_gl_projection_matrix(width, height);
GLint view[4];
-#ifndef QT_OPENGL_ES
- glGetDoublev(GL_MODELVIEW_MATRIX, &model[0][0]);
- glGetDoublev(GL_PROJECTION_MATRIX, &proj[0][0]);
- glGetIntegerv(GL_VIEWPORT, &view[0]);
-#endif
- GLdouble win_x = 0, win_y = 0, win_z = 0;
- qgluProject(x, y, z, &model[0][0], &proj[0][0], &view[0],
- &win_x, &win_y, &win_z);
+ qt_gl_get_viewport(view, width, height);
+
+ GLfloat win_x = 0, win_y = 0, win_z = 0;
+ qgluProject(qreal(x), qreal(y), qreal(z),
+ model, proj, &view[0], &win_x, &win_y, &win_z);
win_y = height - win_y; // y is inverted
QPaintEngine *engine = paintEngine();
@@ -4267,7 +4429,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
- d->glcx->d_func()->clear_on_painter_begin = false;
+ d->disable_clear_on_painter_begin = true;
if (engine->type() == QPaintEngine::OpenGL2)
qt_save_gl_state();
p = new QPainter(this);
@@ -4295,11 +4457,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
glEnable(GL_ALPHA_TEST);
if (use_depth_testing)
glEnable(GL_DEPTH_TEST);
-#ifndef QT_OPENGL_ES
- glTranslated(0, 0, -win_z);
-#else
glTranslatef(0, 0, -win_z);
-#endif
#endif // !defined(QT_OPENGL_ES_2)
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
@@ -4311,7 +4469,7 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
if (engine->type() == QPaintEngine::OpenGL2)
qt_restore_gl_state();
setAutoBufferSwap(auto_swap);
- d->glcx->d_func()->clear_on_painter_begin = true;
+ d->disable_clear_on_painter_begin = false;
}
#ifndef QT_OPENGL_ES
if (engine->type() == QPaintEngine::OpenGL2)
@@ -4659,6 +4817,8 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
{
Q_Q(QGLWidget);
+ glDevice.setWidget(q);
+
QGLExtensions::init();
glcx = 0;
autoSwap = true;
@@ -4694,242 +4854,6 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name()
}
#endif
-void QGLDrawable::setDevice(QPaintDevice *pdev)
-{
- wasBound = false;
- widget = 0;
- buffer = 0;
- fbo = 0;
-#ifdef Q_WS_QWS
- wsurf = 0;
-#endif
-
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- if (pdev->devType() == QInternal::Pixmap) {
- QPixmapData *data = static_cast<QPixmap *>(pdev)->pixmapData();
- Q_ASSERT(data->classId() == QPixmapData::OpenGLClass);
- pixmapData = static_cast<QGLPixmapData *>(data);
-
- fbo = pixmapData->fbo();
- }
-#else
- Q_ASSERT(pdev->devType() != QInternal::Pixmap);
-#endif
-
- if (pdev->devType() == QInternal::Widget)
- widget = static_cast<QGLWidget *>(pdev);
- else if (pdev->devType() == QInternal::Pbuffer)
- buffer = static_cast<QGLPixelBuffer *>(pdev);
- else if (pdev->devType() == QInternal::FramebufferObject)
- fbo = static_cast<QGLFramebufferObject *>(pdev);
-#ifdef Q_WS_QWS
- else if (pdev->devType() == QInternal::UnknownDevice)
- wsurf = static_cast<QWSGLPaintDevice*>(pdev)->windowSurface();
-#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- else if (pdev->devType() == QInternal::UnknownDevice)
- wsurf = static_cast<QGLWindowSurface *>(pdev);
-#endif
-}
-
-void QGLDrawable::swapBuffers()
-{
- if (widget) {
- if (widget->autoBufferSwap())
- widget->swapBuffers();
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- } else if (pixmapData) {
- pixmapData->swapBuffers();
-#endif
- } else {
- glFlush();
- }
-}
-
-void QGLDrawable::makeCurrent()
-{
- previous_fbo = 0;
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- if (!pixmapData && !fbo) {
-#else
- if (!fbo) {
-#endif
- QGLContext *ctx = context();
- previous_fbo = ctx->d_ptr->current_fbo;
- ctx->d_ptr->current_fbo = 0;
- if (previous_fbo)
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- }
-
- if (widget)
- widget->makeCurrent();
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- else if (pixmapData)
- pixmapData->makeCurrent();
-#endif
- else if (buffer)
- buffer->makeCurrent();
-#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
- else if (wsurf)
- wsurf->context()->makeCurrent();
-#endif
- else if (fbo) {
- wasBound = fbo->isBound();
- if (!wasBound)
- fbo->bind();
- }
-}
-
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
-QGLPixmapData *QGLDrawable::copyOnBegin() const
-{
- if (!pixmapData || pixmapData->isUninitialized())
- return 0;
- return pixmapData;
-}
-#endif
-
-void QGLDrawable::doneCurrent()
-{
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- if (pixmapData) {
- pixmapData->doneCurrent();
- return;
- }
-#endif
-
- if (previous_fbo) {
- QGLContext *ctx = context();
- ctx->d_ptr->current_fbo = previous_fbo;
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, previous_fbo);
- }
-
- if (fbo && !wasBound)
- fbo->release();
-}
-
-QSize QGLDrawable::size() const
-{
- if (widget) {
- return QSize(widget->d_func()->glcx->device()->width(),
- widget->d_func()->glcx->device()->height());
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- } else if (pixmapData) {
- return pixmapData->size();
-#endif
- } else if (buffer) {
- return buffer->size();
- } else if (fbo) {
- return fbo->size();
- }
-#ifdef Q_WS_QWS
- else if (wsurf)
- return wsurf->window()->frameSize();
-#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- else if (wsurf)
- return QSize(wsurf->width(), wsurf->height());
-#endif
- return QSize();
-}
-
-QGLFormat QGLDrawable::format() const
-{
- if (widget)
- return widget->format();
- else if (buffer)
- return buffer->format();
-#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
- else if (wsurf)
- return wsurf->context()->format();
-#endif
- else if (fbo && QGLContext::currentContext()) {
- QGLFormat fmt = QGLContext::currentContext()->format();
- fmt.setStencil(fbo->attachment() == QGLFramebufferObject::CombinedDepthStencil);
- fmt.setDepth(fbo->attachment() != QGLFramebufferObject::NoAttachment);
- return fmt;
- }
-
- return QGLFormat();
-}
-
-QGLTexture *QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format,
- QGLContext::BindOptions options)
-{
- QGLTexture *texture = 0;
- options |= QGLContext::MemoryManagedBindOption;
- if (widget)
- texture = widget->d_func()->glcx->d_func()->bindTexture(image, target, format, options);
- else if (buffer)
- texture = buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, options);
- else if (fbo && QGLContext::currentContext())
- texture = const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, options);
-#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
- else if (wsurf)
- texture = wsurf->context()->d_func()->bindTexture(image, target, format, options);
-#endif
- return texture;
-}
-
-QGLTexture *QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format,
- QGLContext::BindOptions options)
-{
- QGLTexture *texture = 0;
- if (widget)
- texture = widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, options);
- else if (buffer)
- texture = buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, options);
- else if (fbo && QGLContext::currentContext())
- texture = const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, options);
-#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
- else if (wsurf)
- texture = wsurf->context()->d_func()->bindTexture(pixmap, target, format, options);
-#endif
- return texture;
-}
-
-QColor QGLDrawable::backgroundColor() const
-{
- if (widget)
- return widget->palette().brush(widget->backgroundRole()).color();
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- else if (pixmapData)
- return pixmapData->fillColor();
-#endif
- return QApplication::palette().brush(QPalette::Background).color();
-}
-
-bool QGLDrawable::hasTransparentBackground() const
-{
- return widget && widget->testAttribute(Qt::WA_TranslucentBackground);
-}
-
-QGLContext *QGLDrawable::context() const
-{
- if (widget)
- return widget->d_func()->glcx;
- else if (buffer)
- return buffer->d_func()->qctx;
- else if (fbo)
- return const_cast<QGLContext *>(QGLContext::currentContext());
-#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
- else if (wsurf)
- return wsurf->context();
-#endif
- return 0;
-}
-
-bool QGLDrawable::autoFillBackground() const
-{
- if (widget)
- return widget->autoFillBackground();
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- else if (pixmapData)
- return pixmapData->needsFill();
-#endif
- else
- return false;
-}
-
-
bool QGLShareRegister::checkSharing(const QGLContext *context1, const QGLContext *context2) {
bool sharing = (context1 && context2 && context1->d_ptr->group == context2->d_ptr->group);
return sharing;
@@ -5086,4 +5010,30 @@ void QGLContextResource::removeOne(const QGLContext *key)
m_resources.erase(it);
}
+QGLContextReference::QGLContextReference(const QGLContext *ctx)
+ : m_ref(1), m_ctx(ctx)
+{
+ connect(QGLSignalProxy::instance(),
+ SIGNAL(aboutToDestroyContext(const QGLContext *)),
+ this, SLOT(aboutToDestroyContext(const QGLContext *)));
+}
+
+void QGLContextReference::aboutToDestroyContext(const QGLContext *ctx)
+{
+ // Bail out if our context is not being destroyed.
+ if (ctx != m_ctx || !m_ctx)
+ return;
+
+ // Find some other context that this one is shared with to take over.
+ QList<const QGLContext *> shares = qgl_share_reg()->shares(m_ctx);
+ shares.removeAll(m_ctx);
+ if (!shares.isEmpty()) {
+ m_ctx = shares[0];
+ return;
+ }
+
+ // No more contexts sharing with this one, so the reference is now invalid.
+ m_ctx = 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 0d72469..1776004 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -43,6 +43,7 @@
#define QGL_H
#include <QtGui/qwidget.h>
+#include <QtGui/qpaintengine.h>
#include <QtOpenGL/qglcolormap.h>
#include <QtCore/qmap.h>
#include <QtCore/qscopedpointer.h>
@@ -130,6 +131,8 @@ class QGLContextPrivate;
// Namespace class:
namespace QGL
{
+ Q_OPENGL_EXPORT void setPreferredPaintEngine(QPaintEngine::Type engineType);
+
enum FormatOption {
DoubleBuffer = 0x0001,
DepthBuffer = 0x0002,
@@ -382,7 +385,6 @@ private:
friend class QGLPixelBuffer;
friend class QGLPixelBufferPrivate;
friend class QGLWidget;
- friend class QGLDrawable;
friend class QGLWidgetPrivate;
friend class QGLGlyphCache;
friend class QOpenGLPaintEngine;
@@ -394,6 +396,7 @@ private:
friend class QGLPixmapFilterBase;
friend class QGLTextureGlyphCache;
friend class QGLShareRegister;
+ friend class QGLSharedResourceGuard;
friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags();
#ifdef Q_WS_MAC
public:
@@ -404,11 +407,13 @@ private:
#endif
friend class QGLFramebufferObject;
friend class QGLFramebufferObjectPrivate;
+ friend class QGLFBOGLPaintDevice;
+ friend class QGLPaintDevice;
private:
Q_DISABLE_COPY(QGLContext)
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QGLContext::BindOptions);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QGLContext::BindOptions)
class Q_OPENGL_EXPORT QGLWidget : public QWidget
{
@@ -539,6 +544,8 @@ private:
friend class QGLContext;
friend class QGLOverlayWidget;
friend class QOpenGLPaintEngine;
+ friend class QGLPaintDevice;
+ friend class QGLWidgetGLPaintDevice;
};
diff --git a/src/opengl/qgl_cl_p.h b/src/opengl/qgl_cl_p.h
index 88a8a44..c3bc68c 100644
--- a/src/opengl/qgl_cl_p.h
+++ b/src/opengl/qgl_cl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 0bf1151..60155b6 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_egl_p.h b/src/opengl/qgl_egl_p.h
index c4f2b63..47a4a19 100644
--- a/src/opengl/qgl_egl_p.h
+++ b/src/opengl/qgl_egl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm
index a3d9c72..dd9d9ff 100644
--- a/src/opengl/qgl_mac.mm
+++ b/src/opengl/qgl_mac.mm
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 2eb4aa5..fdd28a4 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -62,6 +62,7 @@
#include "QtCore/qatomic.h"
#include "private/qwidget_p.h"
#include "qcache.h"
+#include "qglpaintdevice_p.h"
#ifndef QT_OPENGL_ES_1_CL
#define q_vertexType float
@@ -174,6 +175,7 @@ class QGLWidgetPrivate : public QWidgetPrivate
Q_DECLARE_PUBLIC(QGLWidget)
public:
QGLWidgetPrivate() : QWidgetPrivate()
+ , disable_clear_on_painter_begin(false)
#ifdef Q_WS_QWS
, wsurf(0)
#endif
@@ -190,11 +192,14 @@ public:
void cleanupColormaps();
QGLContext *glcx;
+ QGLWidgetGLPaintDevice glDevice;
bool autoSwap;
QGLColormap cmap;
QMap<QString, int> displayListCache;
+ bool disable_clear_on_painter_begin;
+
#if defined(Q_WS_WIN)
void updateColormap();
QGLContext *olcx;
@@ -232,13 +237,37 @@ private:
friend class QGLContextPrivate;
};
+// Reference to a QGLContext which automatically switches to another
+// shared context when the main one is destroyed. If there is no
+// shared context to switch to, the context pointer is set to null.
+// Note: should be merged into QGLContextGroup at some point.
+class QGLContextReference : public QObject
+{
+ Q_OBJECT
+public:
+ QGLContextReference(const QGLContext *ctx);
+ ~QGLContextReference() {}
+
+ const QGLContext *context() const { return m_ctx; }
+
+ void ref() { m_ref.ref(); }
+ bool deref() { return m_ref.deref(); }
+
+private slots:
+ void aboutToDestroyContext(const QGLContext *ctx);
+
+private:
+ QAtomicInt m_ref;
+ const QGLContext *m_ctx;
+};
+
class QGLTexture;
class QGLContextPrivate
{
Q_DECLARE_PUBLIC(QGLContext)
public:
- explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {group = new QGLContextGroup(context);}
+ explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {reference = new QGLContextReference(context); group = new QGLContextGroup(context);}
~QGLContextPrivate();
QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format,
QGLContext::BindOptions options);
@@ -293,7 +322,6 @@ public:
uint sharing : 1;
uint initDone : 1;
uint crWin : 1;
- uint clear_on_painter_begin : 1;
uint internal_context : 1;
uint version_flags_cached : 1;
QPaintDevice *paintDevice;
@@ -301,6 +329,7 @@ public:
QGLContext *q_ptr;
QGLFormat::OpenGLVersionFlags version_flags;
+ QGLContextReference *reference;
QGLContextGroup *group;
GLint max_texture_size;
@@ -337,59 +366,6 @@ Q_SIGNALS:
void aboutToDestroyContext(const QGLContext *context);
};
-class QGLPixelBuffer;
-class QGLFramebufferObject;
-class QWSGLWindowSurface;
-class QGLWindowSurface;
-class QGLPixmapData;
-class QGLDrawable {
-public:
- QGLDrawable() : widget(0), buffer(0), fbo(0)
-#if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
- , wsurf(0)
-#endif
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- , pixmapData(0)
-#endif
- {}
- void setDevice(QPaintDevice *pdev);
- void swapBuffers();
- void makeCurrent();
- void doneCurrent();
- QSize size() const;
- QGLFormat format() const;
- QGLTexture *bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D,
- GLint format = GL_RGBA,
- QGLContext::BindOptions = QGLContext::InternalBindOption);
- QGLTexture *bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D,
- GLint format = GL_RGBA,
- QGLContext::BindOptions = QGLContext::InternalBindOption);
- QColor backgroundColor() const;
- QGLContext *context() const;
- bool autoFillBackground() const;
- bool hasTransparentBackground() const;
-
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- QGLPixmapData *copyOnBegin() const;
-#endif
-
-private:
- bool wasBound;
- QGLWidget *widget;
- QGLPixelBuffer *buffer;
- QGLFramebufferObject *fbo;
-#ifdef Q_WS_QWS
- QWSGLWindowSurface *wsurf;
-#elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- QGLWindowSurface *wsurf;
-#endif
-
-#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
- QGLPixmapData *pixmapData;
-#endif
- int previous_fbo;
-};
-
// GL extension definitions
class QGLExtensions {
public:
@@ -521,15 +497,7 @@ extern QPaintEngine* qt_qgl_paint_engine();
extern EGLDisplay qt_qgl_egl_display();
#endif
-inline bool qt_gl_preferGL2Engine()
-{
-#if defined(QT_OPENGL_ES_2)
- return true;
-#else
- return (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
- && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty();
-#endif
-}
+bool qt_gl_preferGL2Engine();
inline GLenum qt_gl_preferredTextureFormat()
{
@@ -611,6 +579,65 @@ private:
QGLContext *m_ctx;
};
+// Put a guard around a GL object identifier and its context.
+// When the context goes away, a shared context will be used
+// in its place. If there are no more shared contexts, then
+// the identifier is returned as zero - it is assumed that the
+// context destruction cleaned up the identifier in this case.
+class Q_OPENGL_EXPORT QGLSharedResourceGuard
+{
+public:
+ QGLSharedResourceGuard(const QGLContext *context)
+ : m_ctxref(0), m_id(0)
+ {
+ setContext(context);
+ }
+ QGLSharedResourceGuard(const QGLContext *context, GLuint id)
+ : m_ctxref(0), m_id(id)
+ {
+ setContext(context);
+ }
+ ~QGLSharedResourceGuard()
+ {
+ if (m_ctxref && !m_ctxref->deref())
+ delete m_ctxref;
+ }
+
+ const QGLContext *context() const
+ {
+ return m_ctxref ? m_ctxref->context() : 0;
+ }
+
+ void setContext(const QGLContext *context)
+ {
+ if (m_ctxref && !m_ctxref->deref())
+ delete m_ctxref;
+ if (context) {
+ m_ctxref = context->d_ptr->reference;
+ m_ctxref->ref();
+ } else {
+ m_ctxref = 0;
+ }
+ }
+
+ GLuint id() const
+ {
+ if (m_ctxref && m_ctxref->context())
+ return m_id;
+ else
+ return 0;
+ }
+
+ void setId(GLuint id)
+ {
+ m_id = id;
+ }
+
+private:
+ QGLContextReference *m_ctxref;
+ GLuint m_id;
+};
+
QT_END_NAMESPACE
#endif // QGL_P_H
diff --git a/src/opengl/qgl_qws.cpp b/src/opengl/qgl_qws.cpp
index e865b96..c71ceeb 100644
--- a/src/opengl/qgl_qws.cpp
+++ b/src/opengl/qgl_qws.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_win.cpp b/src/opengl/qgl_win.cpp
index 03529dc..78dad80 100644
--- a/src/opengl/qgl_win.cpp
+++ b/src/opengl/qgl_win.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_wince.cpp b/src/opengl/qgl_wince.cpp
index a26d491..881d7f7 100644
--- a/src/opengl/qgl_wince.cpp
+++ b/src/opengl/qgl_wince.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index 81985cd..cb1da18 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -1308,7 +1308,6 @@ void QGLWidget::setContext(QGLContext *context,
QGLContext* oldcx = d->glcx;
d->glcx = context;
-
if (parentWidget()) {
// force creation of delay-created widgets
parentWidget()->winId();
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index 5ebde15..276b408 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglcolormap.cpp b/src/opengl/qglcolormap.cpp
index b4c86f1..7edb250 100644
--- a/src/opengl/qglcolormap.cpp
+++ b/src/opengl/qglcolormap.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglcolormap.h b/src/opengl/qglcolormap.h
index 1f3ee01..5596992 100644
--- a/src/opengl/qglcolormap.h
+++ b/src/opengl/qglcolormap.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglextensions.cpp b/src/opengl/qglextensions.cpp
index a883c42..8c8d46c 100644
--- a/src/opengl/qglextensions.cpp
+++ b/src/opengl/qglextensions.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h
index b1c9503..40840b5 100644
--- a/src/opengl/qglextensions_p.h
+++ b/src/opengl/qglextensions_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 94e3930..094f675 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qglframebufferobject.h"
+#include "qglframebufferobject_p.h"
#include <qdebug.h>
#include <private/qgl_p.h>
@@ -63,7 +64,7 @@ QT_BEGIN_NAMESPACE
extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
-#define QGL_FUNC_CONTEXT QGLContext *ctx = d_ptr->ctx;
+#define QGL_FUNC_CONTEXT QGLContextGroup *ctx = d_ptr->ctx;
#define QT_CHECK_GLERROR() \
{ \
@@ -74,15 +75,6 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
} \
}
-class QGLFramebufferObjectFormatPrivate
-{
-public:
- int samples;
- QGLFramebufferObject::Attachment attachment;
- GLenum target;
- GLenum internal_format;
-};
-
/*!
\class QGLFramebufferObjectFormat
\brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL
@@ -109,6 +101,20 @@ public:
*/
/*!
+ \internal
+*/
+void QGLFramebufferObjectFormat::detach()
+{
+ if (d->ref != 1) {
+ QGLFramebufferObjectFormatPrivate *newd
+ = new QGLFramebufferObjectFormatPrivate(d);
+ if (!d->ref.deref())
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
Creates a QGLFramebufferObjectFormat object for specifying
the format of an OpenGL framebuffer object.
@@ -118,19 +124,9 @@ public:
\sa samples(), attachment(), target(), internalTextureFormat()
*/
-#ifndef QT_OPENGL_ES
-#define DEFAULT_FORMAT GL_RGBA8
-#else
-#define DEFAULT_FORMAT GL_RGBA
-#endif
-
QGLFramebufferObjectFormat::QGLFramebufferObjectFormat()
{
d = new QGLFramebufferObjectFormatPrivate;
- d->samples = 0;
- d->attachment = QGLFramebufferObject::NoAttachment;
- d->target = GL_TEXTURE_2D;
- d->internal_format = DEFAULT_FORMAT;
}
/*!
@@ -139,8 +135,8 @@ QGLFramebufferObjectFormat::QGLFramebufferObjectFormat()
QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other)
{
- d = new QGLFramebufferObjectFormatPrivate;
- *d = *other.d;
+ d = other.d;
+ d->ref.ref();
}
/*!
@@ -149,7 +145,12 @@ QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjec
QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other)
{
- *d = *other.d;
+ if (d != other.d) {
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = other.d;
+ }
return *this;
}
@@ -158,7 +159,8 @@ QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFrame
*/
QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
{
- delete d;
+ if (!d->ref.deref())
+ delete d;
}
/*!
@@ -176,6 +178,7 @@ QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
*/
void QGLFramebufferObjectFormat::setSamples(int samples)
{
+ detach();
d->samples = samples;
}
@@ -197,6 +200,7 @@ int QGLFramebufferObjectFormat::samples() const
*/
void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment)
{
+ detach();
d->attachment = attachment;
}
@@ -219,6 +223,7 @@ QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const
*/
void QGLFramebufferObjectFormat::setTextureTarget(GLenum target)
{
+ detach();
d->target = target;
}
@@ -242,6 +247,7 @@ GLenum QGLFramebufferObjectFormat::textureTarget() const
*/
void QGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat)
{
+ detach();
d->internal_format = internalTextureFormat;
}
@@ -260,38 +266,71 @@ GLenum QGLFramebufferObjectFormat::internalTextureFormat() const
/*! \internal */
void QGLFramebufferObjectFormat::setTextureTarget(QMacCompatGLenum target)
{
+ detach();
d->target = target;
}
/*! \internal */
void QGLFramebufferObjectFormat::setInternalTextureFormat(QMacCompatGLenum internalTextureFormat)
{
+ detach();
d->internal_format = internalTextureFormat;
}
#endif
-class QGLFramebufferObjectPrivate
+/*!
+ Returns true if all the options of this framebuffer object format
+ are the same as \a other; otherwise returns false.
+*/
+bool QGLFramebufferObjectFormat::operator==(const QGLFramebufferObjectFormat& other) const
+{
+ if (d == other.d)
+ return true;
+ else
+ return d->equals(other.d);
+}
+
+/*!
+ Returns false if all the options of this framebuffer object format
+ are the same as \a other; otherwise returns true.
+*/
+bool QGLFramebufferObjectFormat::operator!=(const QGLFramebufferObjectFormat& other) const
{
-public:
- QGLFramebufferObjectPrivate() : depth_stencil_buffer(0), valid(false), ctx(0), previous_fbo(0), engine(0) {}
- ~QGLFramebufferObjectPrivate() {}
-
- void init(const QSize& sz, QGLFramebufferObject::Attachment attachment,
- GLenum internal_format, GLenum texture_target, GLint samples = 0);
- bool checkFramebufferStatus() const;
- GLuint texture;
- GLuint fbo;
- GLuint depth_stencil_buffer;
- GLuint color_buffer;
- GLenum target;
- QSize size;
- QGLFramebufferObjectFormat format;
- uint valid : 1;
- QGLFramebufferObject::Attachment fbo_attachment;
- QGLContext *ctx; // for Windows extension ptrs
- GLuint previous_fbo;
- mutable QPaintEngine *engine;
-};
+ return !(*this == other);
+}
+
+void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f)
+{
+ fbo = f;
+ m_thisFBO = fbo->d_func()->fbo; // This shouldn't be needed
+}
+
+void QGLFBOGLPaintDevice::ensureActiveTarget()
+{
+ QGLContext* ctx = const_cast<QGLContext*>(QGLContext::currentContext());
+ Q_ASSERT(ctx);
+ const GLuint fboId = fbo->d_func()->fbo;
+ if (ctx->d_func()->current_fbo != fboId) {
+ ctx->d_func()->current_fbo = fboId;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId);
+ }
+}
+
+void QGLFBOGLPaintDevice::beginPaint()
+{
+ // We let QFBO track the previously bound FBO rather than doing it
+ // ourselves here. This has the advantage that begin/release & bind/end
+ // work as expected.
+ wasBound = fbo->isBound();
+ if (!wasBound)
+ fbo->bind();
+}
+
+void QGLFBOGLPaintDevice::endPaint()
+{
+ if (!wasBound)
+ fbo->release();
+}
bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
{
@@ -337,12 +376,15 @@ bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
return false;
}
-void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::Attachment attachment,
+void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
+ QGLFramebufferObject::Attachment attachment,
GLenum texture_target, GLenum internal_format, GLint samples)
{
- ctx = const_cast<QGLContext *>(QGLContext::currentContext());
+ QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext());
+ ctx = QGLContextPrivate::contextGroup(currentContext);
+
bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject);
- if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx)))
+ if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(currentContext)))
return;
size = sz;
@@ -353,6 +395,8 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
+ glDevice.setFBO(q);
+
QT_CHECK_GLERROR();
// init texture
if (samples == 0) {
@@ -466,7 +510,7 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
fbo_attachment = QGLFramebufferObject::NoAttachment;
}
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, currentContext->d_ptr->current_fbo);
if (!valid) {
if (color_buffer)
glDeleteRenderbuffers(1, &color_buffer);
@@ -599,7 +643,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(size, NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
@@ -608,7 +652,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, QMacCompatGLenum t
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(size, NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, size, NoAttachment, target, DEFAULT_FORMAT);
}
#endif
@@ -623,7 +667,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
}
/*! \overload
@@ -636,7 +680,8 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, const QGLFramebuff
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(size, format.attachment(), format.textureTarget(), format.internalTextureFormat(), format.samples());
+ d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(),
+ format.samples());
}
/*! \overload
@@ -649,7 +694,8 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFrame
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(QSize(width, height), format.attachment(), format.textureTarget(), format.internalTextureFormat(), format.samples());
+ d->init(this, QSize(width, height), format.attachment(), format.textureTarget(),
+ format.internalTextureFormat(), format.samples());
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
@@ -658,7 +704,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, QMacCompatGLen
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
+ d->init(this, QSize(width, height), NoAttachment, target, DEFAULT_FORMAT);
}
#endif
@@ -679,7 +725,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(QSize(width, height), attachment, target, internal_format);
+ d->init(this, QSize(width, height), attachment, target, internal_format);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
@@ -689,7 +735,7 @@ QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment att
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(QSize(width, height), attachment, target, internal_format);
+ d->init(this, QSize(width, height), attachment, target, internal_format);
}
#endif
@@ -710,7 +756,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(size, attachment, target, internal_format);
+ d->init(this, size, attachment, target, internal_format);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
@@ -720,7 +766,7 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachm
: d_ptr(new QGLFramebufferObjectPrivate)
{
Q_D(QGLFramebufferObject);
- d->init(size, attachment, target, internal_format);
+ d->init(this, size, attachment, target, internal_format);
}
#endif
@@ -736,16 +782,19 @@ QGLFramebufferObject::~QGLFramebufferObject()
delete d->engine;
- if (isValid()
- && (d->ctx == QGLContext::currentContext()
- || qgl_share_reg()->checkSharing(d->ctx, QGLContext::currentContext())))
- {
+ if (isValid()) {
+ const QGLContext *oldContext = QGLContext::currentContext();
+ bool switchContext = !oldContext || QGLContextPrivate::contextGroup(oldContext) != ctx;
+ if (switchContext)
+ const_cast<QGLContext *>(ctx->context())->makeCurrent();
glDeleteTextures(1, &d->texture);
if (d->color_buffer)
glDeleteRenderbuffers(1, &d->color_buffer);
if (d->depth_stencil_buffer)
glDeleteRenderbuffers(1, &d->depth_stencil_buffer);
glDeleteFramebuffers(1, &d->fbo);
+ if (oldContext && switchContext)
+ const_cast<QGLContext *>(oldContext)->makeCurrent();
}
}
@@ -867,7 +916,7 @@ QSize QGLFramebufferObject::size() const
/*!
Returns the format of this framebuffer object.
*/
-const QGLFramebufferObjectFormat &QGLFramebufferObject::format() const
+QGLFramebufferObjectFormat QGLFramebufferObject::format() const
{
Q_D(const QGLFramebufferObject);
return d->format;
@@ -897,7 +946,7 @@ QImage QGLFramebufferObject::toImage() const
bool wasBound = isBound();
if (!wasBound)
const_cast<QGLFramebufferObject *>(this)->bind();
- QImage image = qt_gl_read_framebuffer(d->size, d->ctx->format().alpha(), true);
+ QImage image = qt_gl_read_framebuffer(d->size, format().textureTarget() != GL_RGB, true);
if (!wasBound)
const_cast<QGLFramebufferObject *>(this)->release();
@@ -969,16 +1018,14 @@ bool QGLFramebufferObject::hasOpenGLFramebufferObjects()
*/
void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
{
- Q_D(QGLFramebufferObject);
- d->ctx->drawTexture(target, textureId, textureTarget);
+ const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLFramebufferObject::drawTexture(const QRectF &target, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
- Q_D(QGLFramebufferObject);
- d->ctx->drawTexture(target, textureId, textureTarget);
+ const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}
#endif
@@ -994,16 +1041,14 @@ void QGLFramebufferObject::drawTexture(const QRectF &target, QMacCompatGLuint te
*/
void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
{
- Q_D(QGLFramebufferObject);
- d->ctx->drawTexture(point, textureId, textureTarget);
+ const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}
#ifdef Q_MAC_COMPAT_GL_FUNCTIONS
/*! \internal */
void QGLFramebufferObject::drawTexture(const QPointF &point, QMacCompatGLuint textureId, QMacCompatGLenum textureTarget)
{
- Q_D(QGLFramebufferObject);
- d->ctx->drawTexture(point, textureId, textureTarget);
+ const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}
#endif
@@ -1100,7 +1145,7 @@ QGLFramebufferObject::Attachment QGLFramebufferObject::attachment() const
bool QGLFramebufferObject::isBound() const
{
Q_D(const QGLFramebufferObject);
- return d->ctx->d_ptr->current_fbo == d->fbo;
+ return QGLContext::currentContext()->d_ptr->current_fbo == d->fbo;
}
/*!
diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h
index ec1ae7d..6cf5571 100644
--- a/src/opengl/qglframebufferobject.h
+++ b/src/opengl/qglframebufferobject.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -93,7 +93,7 @@ public:
virtual ~QGLFramebufferObject();
- const QGLFramebufferObjectFormat &format() const;
+ QGLFramebufferObjectFormat format() const;
bool isValid() const;
bool isBound() const;
@@ -130,7 +130,8 @@ protected:
private:
Q_DISABLE_COPY(QGLFramebufferObject)
QScopedPointer<QGLFramebufferObjectPrivate> d_ptr;
- friend class QGLDrawable;
+ friend class QGLPaintDevice;
+ friend class QGLFBOGLPaintDevice;
};
class QGLFramebufferObjectFormatPrivate;
@@ -159,8 +160,13 @@ public:
void setInternalTextureFormat(QMacCompatGLenum internalTextureFormat);
#endif
+ bool operator==(const QGLFramebufferObjectFormat& other) const;
+ bool operator!=(const QGLFramebufferObjectFormat& other) const;
+
private:
QGLFramebufferObjectFormatPrivate *d;
+
+ void detach();
};
QT_END_NAMESPACE
diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h
new file mode 100644
index 0000000..c11c496
--- /dev/null
+++ b/src/opengl/qglframebufferobject_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLFRAMEBUFFEROBJECT_P_H
+#define QGLFRAMEBUFFEROBJECT_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.
+//
+
+QT_BEGIN_NAMESPACE
+
+QT_BEGIN_INCLUDE_NAMESPACE
+
+#include <qglframebufferobject.h>
+#include <private/qglpaintdevice_p.h>
+#include <private/qgl_p.h>
+
+QT_END_INCLUDE_NAMESPACE
+
+#ifndef QT_OPENGL_ES
+#define DEFAULT_FORMAT GL_RGBA8
+#else
+#define DEFAULT_FORMAT GL_RGBA
+#endif
+
+class QGLFramebufferObjectFormatPrivate
+{
+public:
+ QGLFramebufferObjectFormatPrivate()
+ : ref(1),
+ samples(0),
+ attachment(QGLFramebufferObject::NoAttachment),
+ target(GL_TEXTURE_2D),
+ internal_format(DEFAULT_FORMAT)
+ {
+ }
+ QGLFramebufferObjectFormatPrivate
+ (const QGLFramebufferObjectFormatPrivate *other)
+ : ref(1),
+ samples(other->samples),
+ attachment(other->attachment),
+ target(other->target),
+ internal_format(other->internal_format)
+ {
+ }
+ bool equals(const QGLFramebufferObjectFormatPrivate *other)
+ {
+ return samples == other->samples &&
+ attachment == other->attachment &&
+ target == other->target &&
+ internal_format == other->internal_format;
+ }
+
+ QAtomicInt ref;
+ int samples;
+ QGLFramebufferObject::Attachment attachment;
+ GLenum target;
+ GLenum internal_format;
+};
+
+class QGLFBOGLPaintDevice : public QGLPaintDevice
+{
+public:
+ virtual QPaintEngine* paintEngine() const {return fbo->paintEngine();}
+ virtual QSize size() const {return fbo->size();}
+ virtual QGLContext* context() const {return const_cast<QGLContext *>(QGLContext::currentContext());}
+ virtual void ensureActiveTarget();
+ virtual void beginPaint();
+ virtual void endPaint();
+
+ void setFBO(QGLFramebufferObject* f);
+
+private:
+ bool wasBound;
+ QGLFramebufferObject* fbo;
+};
+
+class QGLFramebufferObjectPrivate
+{
+public:
+ QGLFramebufferObjectPrivate() : depth_stencil_buffer(0), valid(false), ctx(0), previous_fbo(0), engine(0) {}
+ ~QGLFramebufferObjectPrivate() {}
+
+ void init(QGLFramebufferObject *q, const QSize& sz,
+ QGLFramebufferObject::Attachment attachment,
+ GLenum internal_format, GLenum texture_target, GLint samples = 0);
+ bool checkFramebufferStatus() const;
+ GLuint texture;
+ GLuint fbo;
+ GLuint depth_stencil_buffer;
+ GLuint color_buffer;
+ GLenum target;
+ QSize size;
+ QGLFramebufferObjectFormat format;
+ uint valid : 1;
+ QGLFramebufferObject::Attachment fbo_attachment;
+ QGLContextGroup *ctx; // for Windows extension ptrs
+ GLuint previous_fbo;
+ mutable QPaintEngine *engine;
+ QGLFBOGLPaintDevice glDevice;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QGLFRAMEBUFFEROBJECT_P_H
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
new file mode 100644
index 0000000..c0f1813
--- /dev/null
+++ b/src/opengl/qglpaintdevice.cpp
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qglpaintdevice_p.h>
+#include <private/qgl_p.h>
+#include <private/qglpixelbuffer_p.h>
+#include <private/qglframebufferobject_p.h>
+#include <private/qwindowsurface_gl_p.h>
+#include <private/qpixmapdata_gl_p.h>
+
+QT_BEGIN_NAMESPACE
+
+QGLPaintDevice::QGLPaintDevice()
+ : m_thisFBO(0)
+{
+}
+
+QGLPaintDevice::~QGLPaintDevice()
+{
+}
+
+
+void QGLPaintDevice::beginPaint()
+{
+ // Make sure our context is the current one:
+ QGLContext *ctx = context();
+ if (ctx != QGLContext::currentContext())
+ ctx->makeCurrent();
+
+ // Record the currently bound FBO so we can restore it again
+ // in endPaint() and bind this device's FBO
+ m_previousFBO = ctx->d_func()->current_fbo;
+ if (m_previousFBO != m_thisFBO) {
+ ctx->d_ptr->current_fbo = m_thisFBO;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
+ }
+}
+
+void QGLPaintDevice::ensureActiveTarget()
+{
+ QGLContext* ctx = context();
+ if (ctx != QGLContext::currentContext())
+ ctx->makeCurrent();
+
+ if (ctx->d_ptr->current_fbo != m_thisFBO) {
+ ctx->d_ptr->current_fbo = m_thisFBO;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_thisFBO);
+ }
+}
+
+void QGLPaintDevice::endPaint()
+{
+ // Make sure the FBO bound at beginPaint is re-bound again here:
+ QGLContext *ctx = context();
+ if (m_previousFBO != ctx->d_func()->current_fbo) {
+ ctx->d_ptr->current_fbo = m_previousFBO;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_previousFBO);
+ }
+}
+
+QGLFormat QGLPaintDevice::format() const
+{
+ return context()->format();
+}
+
+
+
+
+////////////////// QGLWidgetGLPaintDevice //////////////////
+
+QGLWidgetGLPaintDevice::QGLWidgetGLPaintDevice()
+{
+}
+
+QPaintEngine* QGLWidgetGLPaintDevice::paintEngine() const
+{
+ return glWidget->paintEngine();
+}
+
+void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w)
+{
+ glWidget = w;
+}
+
+void QGLWidgetGLPaintDevice::beginPaint()
+{
+ QGLPaintDevice::beginPaint();
+ if (!glWidget->d_func()->disable_clear_on_painter_begin && glWidget->autoFillBackground()) {
+ if (glWidget->testAttribute(Qt::WA_TranslucentBackground))
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ else {
+ const QColor &c = glWidget->palette().brush(glWidget->backgroundRole()).color();
+ float alpha = c.alphaF();
+ glClearColor(c.redF() * alpha, c.greenF() * alpha, c.blueF() * alpha, alpha);
+ }
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+}
+
+void QGLWidgetGLPaintDevice::endPaint()
+{
+ if (glWidget->autoBufferSwap())
+ glWidget->swapBuffers();
+ QGLPaintDevice::endPaint();
+}
+
+
+QSize QGLWidgetGLPaintDevice::size() const
+{
+ return glWidget->size();
+}
+
+QGLContext* QGLWidgetGLPaintDevice::context() const
+{
+ return const_cast<QGLContext*>(glWidget->context());
+}
+
+// returns the QGLPaintDevice for the given QPaintDevice
+QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd)
+{
+ QGLPaintDevice* glpd = 0;
+
+ switch(pd->devType()) {
+ case QInternal::Widget:
+ // Should not be called on a non-gl widget:
+ Q_ASSERT(qobject_cast<QGLWidget*>(static_cast<QWidget*>(pd)));
+ glpd = &(static_cast<QGLWidget*>(pd)->d_func()->glDevice);
+ break;
+ case QInternal::Pbuffer:
+ glpd = &(static_cast<QGLPixelBuffer*>(pd)->d_func()->glDevice);
+ break;
+ case QInternal::FramebufferObject:
+ glpd = &(static_cast<QGLFramebufferObject*>(pd)->d_func()->glDevice);
+ break;
+ case QInternal::Pixmap: {
+ QPixmapData* pmd = static_cast<QPixmap*>(pd)->pixmapData();
+ Q_ASSERT(pmd->classId() == QPixmapData::OpenGLClass);
+ glpd = static_cast<QGLPixmapData*>(pmd)->glDevice();
+ break;
+ }
+ default:
+ qWarning("QGLPaintDevice::getDevice() - Unknown device type %d", pd->devType());
+ break;
+ }
+
+ return glpd;
+}
+
+QT_END_NAMESPACE
diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h
new file mode 100644
index 0000000..66b24a9
--- /dev/null
+++ b/src/opengl/qglpaintdevice_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, 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.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLPAINTDEVICE_P_H
+#define QGLPAINTDEVICE_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 QtOpenGL module. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+
+#include <qpaintdevice.h>
+#include <qgl.h>
+
+
+QT_BEGIN_NAMESPACE
+
+class QGLPaintDevice : public QPaintDevice
+{
+public:
+ QGLPaintDevice();
+ virtual ~QGLPaintDevice();
+
+ int devType() const {return QInternal::OpenGL;}
+
+ virtual void beginPaint();
+ virtual void ensureActiveTarget();
+ virtual void endPaint();
+
+ virtual QGLContext* context() const = 0;
+ QGLFormat format() const;
+ virtual QSize size() const = 0;
+
+ // returns the QGLPaintDevice for the given QPaintDevice
+ static QGLPaintDevice* getDevice(QPaintDevice*);
+
+protected:
+ GLuint m_previousFBO;
+ GLuint m_thisFBO;
+};
+
+
+// Wraps a QGLWidget
+class QGLWidget;
+class QGLWidgetGLPaintDevice : public QGLPaintDevice
+{
+public:
+ QGLWidgetGLPaintDevice();
+
+ virtual QPaintEngine* paintEngine() const;
+
+ // QGLWidgets need to do swapBufers in endPaint:
+ virtual void beginPaint();
+ virtual void endPaint();
+ virtual QSize size() const;
+ virtual QGLContext* context() const;
+
+ void setWidget(QGLWidget*);
+
+private:
+ friend class QGLWidget;
+ QGLWidget *glWidget;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGLPAINTDEVICE_P_H
diff --git a/src/opengl/qglpaintdevice_qws.cpp b/src/opengl/qglpaintdevice_qws.cpp
index 3367940..600efa6 100644
--- a/src/opengl/qglpaintdevice_qws.cpp
+++ b/src/opengl/qglpaintdevice_qws.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpaintdevice_qws_p.h b/src/opengl/qglpaintdevice_qws_p.h
index 078eb11..6dc9d31 100644
--- a/src/opengl/qglpaintdevice_qws_p.h
+++ b/src/opengl/qglpaintdevice_qws_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp
index f082ff0..6cd8968 100644
--- a/src/opengl/qglpixelbuffer.cpp
+++ b/src/opengl/qglpixelbuffer.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -100,6 +100,22 @@ void qgl_cleanup_glyph_cache(QGLContext *) {}
extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool);
+
+QGLContext* QGLPBufferGLPaintDevice::context() const
+{
+ return pbuf->d_func()->qctx;
+}
+
+void QGLPBufferGLPaintDevice::endPaint() {
+ glFlush();
+ QGLPaintDevice::endPaint();
+}
+
+void QGLPBufferGLPaintDevice::setPBuffer(QGLPixelBuffer* pb)
+{
+ pbuf = pb;
+}
+
void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget)
{
Q_Q(QGLPixelBuffer);
@@ -115,6 +131,7 @@ void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &form
shareWidget->d_func()->glcx->d_func()->sharing = true;
}
+ glDevice.setPBuffer(q);
qctx->d_func()->paintDevice = q;
qctx->d_func()->valid = true;
#if defined(Q_WS_WIN) && !defined(QT_OPENGL_ES)
diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h
index 5e81ea3..94ecd46 100644
--- a/src/opengl/qglpixelbuffer.h
+++ b/src/opengl/qglpixelbuffer.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -110,6 +110,8 @@ private:
QScopedPointer<QGLPixelBufferPrivate> d_ptr;
friend class QGLDrawable;
friend class QGLWindowSurface;
+ friend class QGLPaintDevice;
+ friend class QGLPBufferGLPaintDevice;
};
QT_END_NAMESPACE
diff --git a/src/opengl/qglpixelbuffer_egl.cpp b/src/opengl/qglpixelbuffer_egl.cpp
index 089384f..e331de5 100644
--- a/src/opengl/qglpixelbuffer_egl.cpp
+++ b/src/opengl/qglpixelbuffer_egl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpixelbuffer_mac.mm b/src/opengl/qglpixelbuffer_mac.mm
index 330fc2e..6b9344b 100644
--- a/src/opengl/qglpixelbuffer_mac.mm
+++ b/src/opengl/qglpixelbuffer_mac.mm
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpixelbuffer_p.h b/src/opengl/qglpixelbuffer_p.h
index 74cb330..7fde802 100644
--- a/src/opengl/qglpixelbuffer_p.h
+++ b/src/opengl/qglpixelbuffer_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
QT_BEGIN_INCLUDE_NAMESPACE
#include "QtOpenGL/qglpixelbuffer.h"
#include <private/qgl_p.h>
+#include <private/qglpaintdevice_p.h>
#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
#include <GL/glx.h>
@@ -135,6 +136,19 @@ QT_END_INCLUDE_NAMESPACE
class QEglContext;
+
+class QGLPBufferGLPaintDevice : public QGLPaintDevice
+{
+public:
+ virtual QPaintEngine* paintEngine() const {return pbuf->paintEngine();}
+ virtual QSize size() const {return pbuf->size();}
+ virtual QGLContext* context() const;
+ virtual void endPaint();
+ void setPBuffer(QGLPixelBuffer* pb);
+private:
+ QGLPixelBuffer* pbuf;
+};
+
class QGLPixelBufferPrivate {
Q_DECLARE_PUBLIC(QGLPixelBuffer)
public:
@@ -154,6 +168,7 @@ public:
QGLPixelBuffer *q_ptr;
bool invalid;
QGLContext *qctx;
+ QGLPBufferGLPaintDevice glDevice;
QGLFormat format;
QGLFormat req_format;
diff --git a/src/opengl/qglpixelbuffer_win.cpp b/src/opengl/qglpixelbuffer_win.cpp
index 47e9942..71b37ca 100644
--- a/src/opengl/qglpixelbuffer_win.cpp
+++ b/src/opengl/qglpixelbuffer_win.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp
index 5f34605..793471d 100644
--- a/src/opengl/qglpixelbuffer_x11.cpp
+++ b/src/opengl/qglpixelbuffer_x11.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp
index 68db9c0..6ebc397 100644
--- a/src/opengl/qglpixmapfilter.cpp
+++ b/src/opengl/qglpixmapfilter.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglpixmapfilter_p.h b/src/opengl/qglpixmapfilter_p.h
index b68a2b9..0ef3eb5 100644
--- a/src/opengl/qglpixmapfilter_p.h
+++ b/src/opengl/qglpixmapfilter_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglscreen_qws.cpp b/src/opengl/qglscreen_qws.cpp
index 75c3f42..8ca9919 100644
--- a/src/opengl/qglscreen_qws.cpp
+++ b/src/opengl/qglscreen_qws.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglscreen_qws.h b/src/opengl/qglscreen_qws.h
index cb63848..a2f4a5b 100644
--- a/src/opengl/qglscreen_qws.h
+++ b/src/opengl/qglscreen_qws.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index bcc6c61..0b7fe87 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -246,18 +246,11 @@ QT_BEGIN_NAMESPACE
#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9
#endif
-inline bool qt_check_sharing_with_current_context(QGLContextGroup *group)
-{
- const QGLContext *context = QGLContext::currentContext();
- return context && QGLContextPrivate::contextGroup(context) == group;
-}
-
class QGLShaderPrivate
{
public:
- QGLShaderPrivate(QGLShader::ShaderType type)
- : ctx(0)
- , shader(0)
+ QGLShaderPrivate(const QGLContext *context, QGLShader::ShaderType type)
+ : shaderGuard(context)
, shaderType(type)
, compiled(false)
, isPartial((type & QGLShader::PartialShader) != 0)
@@ -265,8 +258,7 @@ public:
{
}
- QGLContextGroup *ctx;
- GLuint shader;
+ QGLSharedResourceGuard shaderGuard;
QGLShader::ShaderType shaderType;
bool compiled;
bool isPartial;
@@ -274,20 +266,22 @@ public:
QString log;
QByteArray partialSource;
- bool create(const QGLContext *context);
+ bool create();
bool compile(QGLShader *q);
+ void deleteShader();
};
-bool QGLShaderPrivate::create(const QGLContext *context)
+#define ctx shaderGuard.context()
+
+bool QGLShaderPrivate::create()
{
- if (!context)
- context = QGLContext::currentContext();
+ const QGLContext *context = shaderGuard.context();
if (!context)
return false;
- ctx = QGLContextPrivate::contextGroup(context);
if (isPartial)
return true;
if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
+ GLuint shader;
if (shaderType == QGLShader::VertexShader)
shader = glCreateShader(GL_VERTEX_SHADER);
else
@@ -296,6 +290,7 @@ bool QGLShaderPrivate::create(const QGLContext *context)
qWarning() << "QGLShader: could not create shader";
return false;
}
+ shaderGuard.setId(shader);
return true;
} else {
return false;
@@ -309,6 +304,7 @@ bool QGLShaderPrivate::compile(QGLShader *q)
compiled = true;
return true;
}
+ GLuint shader = shaderGuard.id();
if (!shader)
return false;
glCompileShader(shader);
@@ -332,6 +328,17 @@ bool QGLShaderPrivate::compile(QGLShader *q)
return compiled;
}
+void QGLShaderPrivate::deleteShader()
+{
+ if (shaderGuard.id()) {
+ glDeleteShader(shaderGuard.id());
+ shaderGuard.setId(0);
+ }
+}
+
+#undef ctx
+#define ctx d->shaderGuard.context()
+
/*!
Constructs a new QGLShader object of the specified \a type
and attaches it to \a parent. If shader programs are not supported,
@@ -347,8 +354,8 @@ bool QGLShaderPrivate::compile(QGLShader *q)
QGLShader::QGLShader(QGLShader::ShaderType type, QObject *parent)
: QObject(parent)
{
- d = new QGLShaderPrivate(type);
- d->create(QGLContext::currentContext());
+ d = new QGLShaderPrivate(QGLContext::currentContext(), type);
+ d->create();
}
/*!
@@ -364,14 +371,9 @@ QGLShader::QGLShader
(const QString& fileName, QGLShader::ShaderType type, QObject *parent)
: QObject(parent)
{
- d = new QGLShaderPrivate(type);
- if (d->create(QGLContext::currentContext()) && !compileFile(fileName)) {
- if (d->shader) {
- QGLContextGroup *ctx = d->ctx;
- glDeleteShader(d->shader);
- }
- d->shader = 0;
- }
+ d = new QGLShaderPrivate(QGLContext::currentContext(), type);
+ if (d->create() && !compileFile(fileName))
+ d->deleteShader();
}
/*!
@@ -389,14 +391,16 @@ QGLShader::QGLShader
QGLShader::QGLShader(QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
: QObject(parent)
{
- d = new QGLShaderPrivate(type);
+ if (!context)
+ context = QGLContext::currentContext();
+ d = new QGLShaderPrivate(context, type);
#ifndef QT_NO_DEBUG
if (context && !qgl_share_reg()->checkSharing(context, QGLContext::currentContext())) {
qWarning("QGLShader::QGLShader: \'context\' must be the currect context or sharing with it.");
return;
}
#endif
- d->create(context);
+ d->create();
}
/*!
@@ -412,20 +416,17 @@ QGLShader::QGLShader
(const QString& fileName, QGLShader::ShaderType type, const QGLContext *context, QObject *parent)
: QObject(parent)
{
- d = new QGLShaderPrivate(type);
+ if (!context)
+ context = QGLContext::currentContext();
+ d = new QGLShaderPrivate(context, type);
#ifndef QT_NO_DEBUG
if (context && !qgl_share_reg()->checkSharing(context, QGLContext::currentContext())) {
qWarning("QGLShader::QGLShader: \'context\' must be currect context or sharing with it.");
return;
}
#endif
- if (d->create(context) && !compileFile(fileName)) {
- if (d->shader) {
- QGLContextGroup *ctx = d->ctx;
- glDeleteShader(d->shader);
- }
- d->shader = 0;
- }
+ if (d->create() && !compileFile(fileName))
+ d->deleteShader();
}
/*!
@@ -435,14 +436,9 @@ QGLShader::QGLShader
*/
QGLShader::~QGLShader()
{
- if (d->shader) {
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx))
- qWarning("QGLShader::~QGLShader: Shader is not associated with current context.");
- else
-#endif
- glDeleteShader(d->shader);
+ if (d->shaderGuard.id()) {
+ QGLShareContextScope scope(d->shaderGuard.context());
+ glDeleteShader(d->shaderGuard.id());
}
delete d;
}
@@ -489,17 +485,11 @@ static const char redefineHighp[] =
*/
bool QGLShader::compile(const char *source)
{
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(d->ctx)) {
- qWarning("QGLShader::compile: Shader is not associated with current context.");
- return false;
- }
-#endif
if (d->isPartial) {
d->partialSource = QByteArray(source);
d->hasPartialSource = true;
return d->compile(this);
- } else if (d->shader) {
+ } else if (d->shaderGuard.id()) {
QVarLengthArray<const char *> src;
int headerLen = 0;
while (source && source[headerLen] == '#') {
@@ -529,8 +519,7 @@ bool QGLShader::compile(const char *source)
src.append(redefineHighp);
#endif
src.append(source + headerLen);
- QGLContextGroup *ctx = d->ctx;
- glShaderSource(d->shader, src.size(), src.data(), 0);
+ glShaderSource(d->shaderGuard.id(), src.size(), src.data(), 0);
return d->compile(this);
} else {
return false;
@@ -612,22 +601,15 @@ bool QGLShader::compileFile(const QString& fileName)
*/
bool QGLShader::setShaderBinary(GLenum format, const void *binary, int length)
{
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx)) {
- qWarning("QGLShader::setShaderBinary: Shader is not associated with current context.");
- return false;
- }
-#endif
-
#if !defined(QT_OPENGL_ES_2)
if (!glShaderBinary)
return false;
#endif
- if (d->isPartial || !d->shader)
+ GLuint shader = d->shaderGuard.id();
+ if (d->isPartial || !shader)
return false;
glGetError(); // Clear error state.
- glShaderBinary(1, &(d->shader), format, binary, length);
+ glShaderBinary(1, &shader, format, binary, length);
d->compiled = (glGetError() == GL_NO_ERROR);
return d->compiled;
}
@@ -652,26 +634,18 @@ bool QGLShader::setShaderBinary(GLenum format, const void *binary, int length)
bool QGLShader::setShaderBinary
(QGLShader& otherShader, GLenum format, const void *binary, int length)
{
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx)) {
- qWarning("QGLShader::setShaderBinary: Shader is not associated with current context.");
- return false;
- }
-#endif
-
#if !defined(QT_OPENGL_ES_2)
if (!glShaderBinary)
return false;
#endif
- if (d->isPartial || !d->shader)
+ if (d->isPartial || !d->shaderGuard.id())
return false;
- if (otherShader.d->isPartial || !otherShader.d->shader)
+ if (otherShader.d->isPartial || !otherShader.d->shaderGuard.id())
return false;
glGetError(); // Clear error state.
GLuint shaders[2];
- shaders[0] = d->shader;
- shaders[1] = otherShader.d->shader;
+ shaders[0] = d->shaderGuard.id();
+ shaders[1] = otherShader.d->shaderGuard.id();
glShaderBinary(2, shaders, format, binary, length);
d->compiled = (glGetError() == GL_NO_ERROR);
otherShader.d->compiled = d->compiled;
@@ -706,25 +680,18 @@ QList<GLenum> QGLShader::shaderBinaryFormats()
*/
QByteArray QGLShader::sourceCode() const
{
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(d->ctx)) {
- qWarning("QGLShader::sourceCode: Shader is not associated with current context.");
- return false;
- }
-#endif
-
if (d->isPartial)
return d->partialSource;
- if (!d->shader)
+ GLuint shader = d->shaderGuard.id();
+ if (!shader)
return QByteArray();
GLint size = 0;
- QGLContextGroup *ctx = d->ctx;
- glGetShaderiv(d->shader, GL_SHADER_SOURCE_LENGTH, &size);
+ glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
if (size <= 0)
return QByteArray();
GLint len = 0;
char *source = new char [size];
- glGetShaderSource(d->shader, size, &len, source);
+ glGetShaderSource(shader, size, &len, source);
QByteArray src(source);
delete [] source;
return src;
@@ -761,15 +728,17 @@ QString QGLShader::log() const
*/
GLuint QGLShader::shaderId() const
{
- return d->shader;
+ return d->shaderGuard.id();
}
+#undef ctx
+#define ctx programGuard.context()
+
class QGLShaderProgramPrivate
{
public:
QGLShaderProgramPrivate(const QGLContext *context)
- : ctx(context ? QGLContextPrivate::contextGroup(context) : 0)
- , program(0)
+ : programGuard(context)
, linked(false)
, inited(false)
, hasPartialShaders(false)
@@ -780,8 +749,7 @@ public:
}
~QGLShaderProgramPrivate();
- QGLContextGroup *ctx;
- GLuint program;
+ QGLSharedResourceGuard programGuard;
bool linked;
bool inited;
bool hasPartialShaders;
@@ -795,16 +763,14 @@ public:
QGLShaderProgramPrivate::~QGLShaderProgramPrivate()
{
- if (program) {
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx))
- qWarning("QGLShaderProgram: Shader program is not associated with current context.");
- else
-#endif
- glDeleteProgram(program);
+ if (programGuard.id()) {
+ QGLShareContextScope scope(programGuard.context());
+ glDeleteProgram(programGuard.id());
}
}
+#undef ctx
+#define ctx d->programGuard.context()
/*!
Constructs a new shader program and attaches it to \a parent.
@@ -844,27 +810,23 @@ QGLShaderProgram::~QGLShaderProgram()
bool QGLShaderProgram::init()
{
- if (d->program || d->inited)
+ if (d->programGuard.id() || d->inited)
return true;
d->inited = true;
- const QGLContext *context = QGLContext::currentContext();
+ const QGLContext *context = d->programGuard.context();
+ if (!context) {
+ context = QGLContext::currentContext();
+ d->programGuard.setContext(context);
+ }
if (!context)
return false;
- if (!d->ctx)
- d->ctx = QGLContextPrivate::contextGroup(context);
-#ifndef QT_NO_DEBUG
- else if (!qt_check_sharing_with_current_context(d->ctx)) {
- qWarning("QGLShaderProgram: Shader program is not associated with current context.");
- return false;
- }
-#endif
if (qt_resolve_glsl_extensions(const_cast<QGLContext *>(context))) {
- QGLContextGroup *ctx = d->ctx;
- d->program = glCreateProgram();
- if (!(d->program)) {
+ GLuint program = glCreateProgram();
+ if (!program) {
qWarning() << "QGLShaderProgram: could not create shader program";
return false;
}
+ d->programGuard.setId(program);
return true;
} else {
qWarning() << "QGLShaderProgram: shader programs are not supported";
@@ -889,24 +851,18 @@ bool QGLShaderProgram::addShader(QGLShader *shader)
return false;
if (d->shaders.contains(shader))
return true; // Already added to this shader program.
- if (d->program && shader) {
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(d->ctx)) {
- qWarning("QGLShaderProgram::addShader: Program is not associated with current context.");
- return false;
- }
-#endif
- if (shader->d->ctx != d->ctx) {
+ if (d->programGuard.id() && shader) {
+ if (!qgl_share_reg()->checkSharing(shader->d->shaderGuard.context(),
+ d->programGuard.context())) {
qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context.");
return false;
}
if (!shader->d->compiled)
return false;
if (!shader->d->isPartial) {
- if (!shader->d->shader)
+ if (!shader->d->shaderGuard.id())
return false;
- QGLContextGroup *ctx = d->ctx;
- glAttachShader(d->program, shader->d->shader);
+ glAttachShader(d->programGuard.id(), shader->d->shaderGuard.id());
} else {
d->hasPartialShaders = true;
}
@@ -1017,14 +973,9 @@ bool QGLShaderProgram::addShaderFromFile
*/
void QGLShaderProgram::removeShader(QGLShader *shader)
{
- if (d->program && shader && shader->d->shader) {
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx))
- qWarning("QGLShaderProgram::removeShader: Program is not associated with current context.");
- else
-#endif
- glDetachShader(d->program, shader->d->shader);
+ if (d->programGuard.id() && shader && shader->d->shaderGuard.id()) {
+ QGLShareContextScope scope(d->programGuard.context());
+ glDetachShader(d->programGuard.id(), shader->d->shaderGuard.id());
}
d->linked = false; // Program needs to be relinked.
if (shader) {
@@ -1056,15 +1007,9 @@ QList<QGLShader *> QGLShaderProgram::shaders() const
void QGLShaderProgram::removeAllShaders()
{
d->removingShaders = true;
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx))
- qWarning("QGLShaderProgram::removeAllShaders: Program is not associated with current context.");
- else
-#endif
foreach (QGLShader *shader, d->shaders) {
- if (d->program && shader && shader->d->shader)
- glDetachShader(d->program, shader->d->shader);
+ if (d->programGuard.id() && shader && shader->d->shaderGuard.id())
+ glDetachShader(d->programGuard.id(), shader->d->shaderGuard.id());
}
foreach (QGLShader *shader, d->anonShaders) {
// Delete shader objects that were created anonymously.
@@ -1113,22 +1058,17 @@ QByteArray QGLShaderProgram::programBinary(int *format) const
if (!isLinked())
return QByteArray();
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx))
- qWarning("QGLShaderProgram::programBinary: Program is not associated with current context.");
-#endif
-
// Get the length of the binary data, bailing out if there is none.
GLint length = 0;
- glGetProgramiv(d->program, GL_PROGRAM_BINARY_LENGTH_OES, &length);
+ GLuint program = d->programGuard.id();
+ glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH_OES, &length);
if (length <= 0)
return QByteArray();
// Retrieve the binary data.
QByteArray binary(length, 0);
GLenum binaryFormat;
- glGetProgramBinaryOES(d->program, length, 0, &binaryFormat, binary.data());
+ glGetProgramBinaryOES(program, length, 0, &binaryFormat, binary.data());
if (format)
*format = (int)binaryFormat;
return binary;
@@ -1149,25 +1089,22 @@ QByteArray QGLShaderProgram::programBinary(int *format) const
bool QGLShaderProgram::setProgramBinary(int format, const QByteArray& binary)
{
#if defined(QT_OPENGL_ES_2)
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx))
- qWarning("QGLShaderProgram::setProgramBinary: Program is not associated with current context.");
-#endif
-
// Load the binary and check that it was linked correctly.
- glProgramBinaryOES(d->program, (GLenum)format,
+ GLuint program = d->programGuard.id();
+ if (!program)
+ return false;
+ glProgramBinaryOES(program, (GLenum)format,
binary.constData(), binary.size());
GLint value = 0;
- glGetProgramiv(d->program, GL_LINK_STATUS, &value);
+ glGetProgramiv(program, GL_LINK_STATUS, &value);
d->linked = (value != 0);
value = 0;
- glGetProgramiv(d->program, GL_INFO_LOG_LENGTH, &value);
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
d->log = QString();
if (value > 1) {
char *logbuf = new char [value];
GLint len;
- glGetProgramInfoLog(d->program, value, &len, logbuf);
+ glGetProgramInfoLog(program, value, &len, logbuf);
d->log = QString::fromLatin1(logbuf);
QString name = objectName();
if (name.isEmpty())
@@ -1222,16 +1159,9 @@ QList<int> QGLShaderProgram::programBinaryFormats()
*/
bool QGLShaderProgram::link()
{
- if (!d->program)
- return false;
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx)) {
- qWarning("QGLShaderProgram::link: Program is not associated with current context.");
+ GLuint program = d->programGuard.id();
+ if (!program)
return false;
- }
-#endif
-
if (d->hasPartialShaders) {
// Compile the partial vertex and fragment shaders.
QByteArray vertexSource;
@@ -1244,7 +1174,7 @@ bool QGLShaderProgram::link()
}
if (vertexSource.isEmpty()) {
if (d->vertexShader) {
- glDetachShader(d->program, d->vertexShader->d->shader);
+ glDetachShader(program, d->vertexShader->d->shaderGuard.id());
delete d->vertexShader;
d->vertexShader = 0;
}
@@ -1257,11 +1187,11 @@ bool QGLShaderProgram::link()
d->log = d->vertexShader->log();
return false;
}
- glAttachShader(d->program, d->vertexShader->d->shader);
+ glAttachShader(program, d->vertexShader->d->shaderGuard.id());
}
if (fragmentSource.isEmpty()) {
if (d->fragmentShader) {
- glDetachShader(d->program, d->fragmentShader->d->shader);
+ glDetachShader(program, d->fragmentShader->d->shaderGuard.id());
delete d->fragmentShader;
d->fragmentShader = 0;
}
@@ -1274,20 +1204,20 @@ bool QGLShaderProgram::link()
d->log = d->fragmentShader->log();
return false;
}
- glAttachShader(d->program, d->fragmentShader->d->shader);
+ glAttachShader(program, d->fragmentShader->d->shaderGuard.id());
}
}
- glLinkProgram(d->program);
+ glLinkProgram(program);
GLint value = 0;
- glGetProgramiv(d->program, GL_LINK_STATUS, &value);
+ glGetProgramiv(program, GL_LINK_STATUS, &value);
d->linked = (value != 0);
value = 0;
- glGetProgramiv(d->program, GL_INFO_LOG_LENGTH, &value);
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
d->log = QString();
if (value > 1) {
char *logbuf = new char [value];
GLint len;
- glGetProgramInfoLog(d->program, value, &len, logbuf);
+ glGetProgramInfoLog(program, value, &len, logbuf);
d->log = QString::fromLatin1(logbuf);
QString name = objectName();
if (name.isEmpty())
@@ -1330,21 +1260,18 @@ QString QGLShaderProgram::log() const
*/
bool QGLShaderProgram::enable()
{
- if (!d->program)
+ GLuint program = d->programGuard.id();
+ if (!program)
return false;
if (!d->linked && !link())
return false;
- QGLContextGroup *ctx = d->ctx;
-#ifndef QT_NO_DEBUG
- if (!qt_check_sharing_with_current_context(ctx)) {
- qWarning("QGLShaderProgram::enable: Program is not associated with current context.");
- return false;
- }
-#endif
- glUseProgram(d->program);
+ glUseProgram(program);
return true;
}
+#undef ctx
+#define ctx QGLContext::currentContext()
+
/*!
Disables the active shader program in the current QGLContext.
This is equivalent to calling \c{glUseProgram(0)}.
@@ -1353,7 +1280,6 @@ bool QGLShaderProgram::enable()
*/
void QGLShaderProgram::disable()
{
- const QGLContext *ctx = QGLContext::currentContext();
#if defined(QT_OPENGL_ES_2)
glUseProgram(0);
#else
@@ -1362,7 +1288,8 @@ void QGLShaderProgram::disable()
#endif
}
-#define ctx d->ctx
+#undef ctx
+#define ctx d->programGuard.context()
/*!
Returns the OpenGL identifier associated with this shader program.
@@ -1371,7 +1298,7 @@ void QGLShaderProgram::disable()
*/
GLuint QGLShaderProgram::programId() const
{
- return d->program;
+ return d->programGuard.id();
}
/*!
@@ -1384,7 +1311,7 @@ GLuint QGLShaderProgram::programId() const
*/
void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
{
- glBindAttribLocation(d->program, location, name);
+ glBindAttribLocation(d->programGuard.id(), location, name);
}
/*!
@@ -1399,7 +1326,7 @@ void QGLShaderProgram::bindAttributeLocation(const char *name, int location)
*/
void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
{
- glBindAttribLocation(d->program, location, name.constData());
+ glBindAttribLocation(d->programGuard.id(), location, name.constData());
}
/*!
@@ -1414,7 +1341,7 @@ void QGLShaderProgram::bindAttributeLocation(const QByteArray& name, int locatio
*/
void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
{
- glBindAttribLocation(d->program, location, name.toLatin1().constData());
+ glBindAttribLocation(d->programGuard.id(), location, name.toLatin1().constData());
}
/*!
@@ -1427,7 +1354,7 @@ void QGLShaderProgram::bindAttributeLocation(const QString& name, int location)
int QGLShaderProgram::attributeLocation(const char *name) const
{
if (d->linked) {
- return glGetAttribLocation(d->program, name);
+ return glGetAttribLocation(d->programGuard.id(), name);
} else {
qWarning() << "QGLShaderProgram::attributeLocation(" << name
<< "): shader program is not linked";
@@ -1887,7 +1814,7 @@ void QGLShaderProgram::disableAttributeArray(const char *name)
int QGLShaderProgram::uniformLocation(const char *name) const
{
if (d->linked) {
- return glGetUniformLocation(d->program, name);
+ return glGetUniformLocation(d->programGuard.id(), name);
} else {
qWarning() << "QGLShaderProgram::uniformLocation(" << name
<< "): shader program is not linked";
diff --git a/src/opengl/qglshaderprogram.h b/src/opengl/qglshaderprogram.h
index 8fa0580..f2d70fa 100644
--- a/src/opengl/qglshaderprogram.h
+++ b/src/opengl/qglshaderprogram.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglwindowsurface_qws.cpp b/src/opengl/qglwindowsurface_qws.cpp
index e4c521c..6bf3257 100644
--- a/src/opengl/qglwindowsurface_qws.cpp
+++ b/src/opengl/qglwindowsurface_qws.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qglwindowsurface_qws_p.h b/src/opengl/qglwindowsurface_qws_p.h
index e8ad946..0c7682a 100644
--- a/src/opengl/qglwindowsurface_qws_p.h
+++ b/src/opengl/qglwindowsurface_qws_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgraphicsshadereffect.cpp b/src/opengl/qgraphicsshadereffect.cpp
index f733109..1c02fd0 100644
--- a/src/opengl/qgraphicsshadereffect.cpp
+++ b/src/opengl/qgraphicsshadereffect.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgraphicsshadereffect_p.h b/src/opengl/qgraphicsshadereffect_p.h
index a313846..de7f00c 100644
--- a/src/opengl/qgraphicsshadereffect_p.h
+++ b/src/opengl/qgraphicsshadereffect_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
index 68ef72c..3e7fece 100644
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ b/src/opengl/qgraphicssystem_gl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h
index 7821a7f..b80e7a3 100644
--- a/src/opengl/qgraphicssystem_gl_p.h
+++ b/src/opengl/qgraphicssystem_gl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 8c545d2..0219b55 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -49,6 +49,7 @@
#include "qbrush.h"
#include "qgl.h"
#include <private/qgl_p.h>
+#include <private/qglpaintdevice_p.h>
#include <private/qpainter_p.h>
#include "qmap.h"
#include <private/qpaintengine_opengl_p.h>
@@ -75,7 +76,7 @@
#include "qgl_cl_p.h"
#endif
-#define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(drawable.context());
+#define QGL_FUNC_CONTEXT QGLContext *ctx = const_cast<QGLContext *>(device->context());
#include <stdlib.h>
#include "qpaintengine_opengl_p.h"
@@ -286,7 +287,7 @@ public Q_SLOTS:
}
private:
- QGLDrawable drawable;
+ QGLPaintDevice* device;
QGLFramebufferObject *offscreen;
QGLContext *ctx;
@@ -305,7 +306,13 @@ private:
inline void QGLOffscreen::setDevice(QPaintDevice *pdev)
{
- drawable.setDevice(pdev);
+ if (pdev->devType() == QInternal::OpenGL)
+ device = static_cast<QGLPaintDevice*>(pdev);
+ else
+ device = QGLPaintDevice::getDevice(pdev);
+
+ if (!device)
+ return;
drawable_fbo = (pdev->devType() == QInternal::FramebufferObject);
}
@@ -329,12 +336,12 @@ void QGLOffscreen::initialize()
activated = true;
initialized = true;
- int dim = qMax(2048, static_cast<int>(qt_next_power_of_two(qMax(drawable.size().width(), drawable.size().height()))));
+ int dim = qMax(2048, static_cast<int>(qt_next_power_of_two(qMax(device->size().width(), device->size().height()))));
- bool shared_context = qgl_share_reg()->checkSharing(drawable.context(), ctx);
+ bool shared_context = qgl_share_reg()->checkSharing(device->context(), ctx);
bool would_fail = last_failed_size.isValid() &&
- (drawable.size().width() >= last_failed_size.width() ||
- drawable.size().height() >= last_failed_size.height());
+ (device->size().width() >= last_failed_size.width() ||
+ device->size().height() >= last_failed_size.height());
bool needs_refresh = dim > mask_dim || !shared_context;
if (needs_refresh && !would_fail) {
@@ -348,13 +355,13 @@ void QGLOffscreen::initialize()
delete offscreen;
offscreen = 0;
mask_dim = 0;
- last_failed_size = drawable.size();
+ last_failed_size = device->size();
}
}
qt_mask_texture_cache()->setOffscreenSize(offscreenSize());
- qt_mask_texture_cache()->setDrawableSize(drawable.size());
- ctx = drawable.context();
+ qt_mask_texture_cache()->setDrawableSize(device->size());
+ ctx = device->context();
#endif
}
@@ -428,11 +435,11 @@ inline void QGLOffscreen::release()
DEBUG_ONCE_STR("QGLOffscreen: releasing offscreen");
if (drawable_fbo)
- drawable.makeCurrent();
+ device->ensureActiveTarget(); //###
else
offscreen->release();
- QSize sz(drawable.size());
+ QSize sz(device->size());
glViewport(0, 0, sz.width(), sz.height());
glMatrixMode(GL_PROJECTION);
@@ -455,7 +462,7 @@ inline bool QGLOffscreen::isBound() const
inline QSize QGLOffscreen::drawableSize() const
{
- return drawable.size();
+ return device->size();
}
inline QSize QGLOffscreen::offscreenSize() const
@@ -757,7 +764,7 @@ public:
GLubyte pen_color[4];
GLubyte brush_color[4];
QTransform::TransformationType txop;
- QGLDrawable drawable;
+ QGLPaintDevice* device;
QGLOffscreen offscreen;
qreal inverseScale;
@@ -1070,6 +1077,7 @@ protected:
}
void cleanCache() {
+ QGLShareContextScope scope(buffer_ctx);
QGLGradientColorTableHash::const_iterator it = cache.constBegin();
for (; it != cache.constEnd(); ++it) {
const CacheInfo &cache_info = it.value();
@@ -1167,7 +1175,7 @@ void QOpenGLPaintEnginePrivate::createGradientPaletteTexture(const QGradient& g)
#ifdef QT_OPENGL_ES //###
Q_UNUSED(g);
#else
- GLuint texId = qt_opengl_gradient_cache()->getBuffer(g, opacity, drawable.context());
+ GLuint texId = qt_opengl_gradient_cache()->getBuffer(g, opacity, device->context());
glBindTexture(GL_TEXTURE_1D, texId);
grad_palette = texId;
if (g.spread() == QGradient::RepeatSpread || g.type() == QGradient::ConicalGradient)
@@ -1236,12 +1244,19 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
{
Q_D(QOpenGLPaintEngine);
- d->drawable.setDevice(pdev);
+ if (pdev->devType() == QInternal::OpenGL)
+ d->device = static_cast<QGLPaintDevice*>(pdev);
+ else
+ d->device = QGLPaintDevice::getDevice(pdev);
+
+ if (!d->device)
+ return false;
+
d->offscreen.setDevice(pdev);
d->has_fast_pen = false;
d->inverseScale = 1;
d->opacity = 1;
- d->drawable.makeCurrent();
+ d->device->beginPaint();
d->matrix = QTransform();
d->has_antialiasing = false;
d->high_quality_antialiasing = false;
@@ -1256,7 +1271,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
bool has_frag_program = (QGLExtensions::glExtensions & QGLExtensions::FragmentProgram)
&& (pdev->devType() != QInternal::Pixmap);
- QGLContext *ctx = const_cast<QGLContext *>(d->drawable.context());
+ QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
if (!ctx) {
qWarning() << "QOpenGLPaintEngine: paint device doesn't have a valid GL context.";
return false;
@@ -1265,9 +1280,9 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
if (has_frag_program)
has_frag_program = qt_resolve_frag_program_extensions(ctx) && qt_resolve_version_1_3_functions(ctx);
- d->use_stencil_method = d->drawable.format().stencil()
+ d->use_stencil_method = d->device->format().stencil()
&& (QGLExtensions::glExtensions & QGLExtensions::StencilWrap);
- if (d->drawable.format().directRendering()
+ if (d->device->format().directRendering()
&& (d->use_stencil_method && QGLExtensions::glExtensions & QGLExtensions::StencilTwoSide))
d->has_stencil_face_ext = qt_resolve_stencil_face_extension(ctx);
@@ -1333,23 +1348,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
d->offscreen.begin();
- if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) {
-
- if (d->drawable.hasTransparentBackground())
- glClearColor(0.0, 0.0, 0.0, 0.0);
- else {
- const QColor &c = d->drawable.backgroundColor();
- glClearColor(c.redF(), c.greenF(), c.blueF(), 1.0);
- }
-
- GLbitfield clearBits = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
-#ifndef QT_OPENGL_ES
- clearBits |= GL_ACCUM_BUFFER_BIT;
-#endif
- glClear(clearBits);
- }
-
- QSize sz(d->drawable.size());
+ QSize sz(d->device->size());
glViewport(0, 0, sz.width(), sz.height()); // XXX (Embedded): We need a solution for GLWidgets that draw in a part or a bigger surface...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -1366,7 +1365,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
#ifdef QT_OPENGL_ES
d->max_texture_size = ctx->d_func()->maxTextureSize();
#else
- bool shared_ctx = qgl_share_reg()->checkSharing(d->drawable.context(), d->shader_ctx);
+ bool shared_ctx = qgl_share_reg()->checkSharing(d->device->context(), d->shader_ctx);
if (shared_ctx) {
d->max_texture_size = d->shader_ctx->d_func()->maxTextureSize();
@@ -1382,7 +1381,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
glDeleteTextures(1, &d->drawable_texture);
ctx->makeCurrent();
}
- d->shader_ctx = d->drawable.context();
+ d->shader_ctx = d->device->context();
glGenTextures(1, &d->grad_palette);
qt_mask_texture_cache()->clearCache();
@@ -1417,7 +1416,7 @@ bool QOpenGLPaintEngine::end()
Q_D(QOpenGLPaintEngine);
d->flushDrawQueue();
d->offscreen.end();
- QGLContext *ctx = const_cast<QGLContext *>(d->drawable.context());
+ QGLContext *ctx = const_cast<QGLContext *>(d->device->context());
if (!ctx->d_ptr->internal_context) {
glMatrixMode(GL_TEXTURE);
glPopMatrix();
@@ -1434,8 +1433,7 @@ bool QOpenGLPaintEngine::end()
glPopClientAttrib();
}
#endif
- d->drawable.swapBuffers();
- d->drawable.doneCurrent();
+ d->device->endPaint();
qt_mask_texture_cache()->maintainCache();
return true;
@@ -1961,7 +1959,7 @@ void QOpenGLPaintEnginePrivate::fillVertexArray(Qt::FillRule fillRule)
const int left = rect.left();
const int width = rect.width();
- const int bottom = drawable.size().height() - (rect.bottom() + 1);
+ const int bottom = device->size().height() - (rect.bottom() + 1);
const int height = rect.height();
glScissor(left, bottom, width, height);
@@ -2242,7 +2240,7 @@ void QOpenGLPaintEnginePrivate::updateDepthClip()
const int left = fastClip.left();
const int width = fastClip.width();
- const int bottom = drawable.size().height() - (fastClip.bottom() + 1);
+ const int bottom = device->size().height() - (fastClip.bottom() + 1);
const int height = fastClip.height();
glScissor(left, bottom, width, height);
@@ -2325,7 +2323,7 @@ void QOpenGLPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOpe
// clipping is only supported when a stencil or depth buffer is
// available
- if (!d->drawable.format().depth())
+ if (!d->device->format().depth())
return;
d->use_system_clip = false;
@@ -2362,7 +2360,7 @@ void QOpenGLPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOpe
path.addRect(untransformedRects[0]);
path = d->matrix.map(path);
- if (path.contains(QRectF(QPointF(), d->drawable.size())))
+ if (path.contains(QRectF(QPointF(), d->device->size())))
isScreenClip = true;
}
}
@@ -3369,7 +3367,7 @@ void QOpenGLPaintEnginePrivate::drawOffscreenPath(const QPainterPath &path)
disableClipping();
- GLuint program = qt_gl_program_cache()->getProgram(drawable.context(),
+ GLuint program = qt_gl_program_cache()->getProgram(device->context(),
FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
QGLPathMaskGenerator maskGenerator(path, matrix, offscreen, program);
addItem(qt_mask_texture_cache()->getMask(maskGenerator, this));
@@ -3506,7 +3504,7 @@ void QOpenGLPaintEngine::drawRects(const QRectF *rects, int rectCount)
if (d->has_brush) {
d->disableClipping();
- GLuint program = qt_gl_program_cache()->getProgram(d->drawable.context(),
+ GLuint program = qt_gl_program_cache()->getProgram(d->device->context(),
FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
if (d->matrix.type() >= QTransform::TxProject) {
@@ -3916,7 +3914,7 @@ void QOpenGLPaintEnginePrivate::strokeLines(const QPainterPath &path)
qreal penWidth = cpen.widthF();
- GLuint program = qt_gl_program_cache()->getProgram(drawable.context(),
+ GLuint program = qt_gl_program_cache()->getProgram(device->context(),
FRAGMENT_PROGRAM_MASK_TRAPEZOID_AA, 0, true);
QGLLineMaskGenerator maskGenerator(path, matrix, penWidth == 0 ? 1.0 : penWidth,
offscreen, program);
@@ -4302,7 +4300,7 @@ void QOpenGLPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QR
else {
GLenum target = qt_gl_preferredTextureTarget();
d->flushDrawQueue();
- d->drawable.bindTexture(pm, target);
+ d->device->context()->bindTexture(pm, target);
drawTextureRect(pm.width(), pm.height(), r, sr, target);
}
}
@@ -4337,9 +4335,11 @@ void QOpenGLPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, con
QGLTexture *tex;
if (scaled.isNull())
- tex = d->drawable.bindTexture(pm);
+ tex = d->device->context()->d_func()->bindTexture(pm, GL_TEXTURE_2D, GL_RGBA,
+ QGLContext::InternalBindOption);
else
- tex = d->drawable.bindTexture(scaled);
+ tex = d->device->context()->d_func()->bindTexture(scaled, GL_TEXTURE_2D, GL_RGBA,
+ QGLContext::InternalBindOption);
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, d->use_smooth_pixmap_transform);
#ifndef QT_OPENGL_ES
@@ -4416,7 +4416,7 @@ void QOpenGLPaintEngine::drawImage(const QRectF &r, const QImage &image, const Q
else {
GLenum target = qt_gl_preferredTextureTarget();
d->flushDrawQueue();
- d->drawable.bindTexture(image, target);
+ d->device->context()->bindTexture(image, target);
drawTextureRect(image.width(), image.height(), r, sr, target);
}
}
@@ -4883,7 +4883,7 @@ void QOpenGLPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
// make sure the glyphs we want to draw are in the cache
- qt_glyph_cache()->cacheGlyphs(d->drawable.context(), ti, glyphs);
+ qt_glyph_cache()->cacheGlyphs(d->device->context(), ti, glyphs);
d->setGradientOps(Qt::SolidPattern, QRectF()); // turns off gradient ops
qt_glColor4ubv(d->pen_color);
@@ -4961,7 +4961,7 @@ void QOpenGLPaintEngine::drawEllipse(const QRectF &rect)
glPushMatrix();
glLoadIdentity();
- GLuint program = qt_gl_program_cache()->getProgram(d->drawable.context(),
+ GLuint program = qt_gl_program_cache()->getProgram(d->device->context(),
FRAGMENT_PROGRAM_MASK_ELLIPSE_AA, 0, true);
QGLEllipseMaskGenerator maskGenerator(rect,
d->matrix,
@@ -5096,10 +5096,10 @@ void QOpenGLPaintEnginePrivate::copyDrawable(const QRectF &rect)
QRectF screen_rect = rect.adjusted(-1, -1, 1, 1);
int left = qMax(0, static_cast<int>(screen_rect.left()));
- int width = qMin(drawable.size().width() - left, static_cast<int>(screen_rect.width()) + 1);
+ int width = qMin(device->size().width() - left, static_cast<int>(screen_rect.width()) + 1);
- int bottom = qMax(0, static_cast<int>(drawable.size().height() - screen_rect.bottom()));
- int height = qMin(drawable.size().height() - bottom, static_cast<int>(screen_rect.height()) + 1);
+ int bottom = qMax(0, static_cast<int>(device->size().height() - screen_rect.bottom()));
+ int height = qMin(device->size().height() - bottom, static_cast<int>(screen_rect.height()) + 1);
glBindTexture(GL_TEXTURE_2D, drawable_texture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, left, bottom, left, bottom, width, height);
@@ -5193,9 +5193,9 @@ void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType *
glActiveTexture(GL_TEXTURE0 + brush_texture_location);
if (current_style == Qt::TexturePattern)
- drawable.bindTexture(cbrush.textureImage());
+ device->context()->bindTexture(cbrush.textureImage());
else
- drawable.bindTexture(qt_imageForBrush(current_style, true));
+ device->context()->bindTexture(qt_imageForBrush(current_style, true));
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, use_smooth_pixmap_transform);
}
@@ -5203,7 +5203,7 @@ void QOpenGLPaintEnginePrivate::composite(GLuint primitive, const q_vertexType *
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, q_vertexTypeEnum, 0, vertexArray);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
- GLuint program = qt_gl_program_cache()->getProgram(drawable.context(),
+ GLuint program = qt_gl_program_cache()->getProgram(device->context(),
fragment_brush,
fragment_composition_mode, false);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, program);
@@ -5275,7 +5275,7 @@ void QOpenGLPaintEnginePrivate::drawItem(const QDrawQueueItem &item)
setGradientOps(item.brush, item.location.screen_rect);
composite(item.location.screen_rect, item.location.rect.topLeft() - item.location.screen_rect.topLeft()
- - QPoint(0, offscreen.offscreenSize().height() - drawable.size().height()));
+ - QPoint(0, offscreen.offscreenSize().height() - device->size().height()));
}
void QOpenGLPaintEnginePrivate::flushDrawQueue()
diff --git a/src/opengl/qpaintengine_opengl_p.h b/src/opengl/qpaintengine_opengl_p.h
index 2e67691..1cac3ad 100644
--- a/src/opengl/qpaintengine_opengl_p.h
+++ b/src/opengl/qpaintengine_opengl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp
index d63d2ad..fa1b815 100644
--- a/src/opengl/qpixmapdata_gl.cpp
+++ b/src/opengl/qpixmapdata_gl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -80,12 +80,7 @@ QGLFramebufferObject *QGLFramebufferObjectPool::acquire(const QSize &requestSize
for (int i = 0; !chosen && i < m_fbos.size(); ++i) {
QGLFramebufferObject *fbo = m_fbos.at(i);
- QGLFramebufferObjectFormat format = fbo->format();
- if (format.samples() == requestFormat.samples()
- && format.attachment() == requestFormat.attachment()
- && format.textureTarget() == requestFormat.textureTarget()
- && format.internalTextureFormat() == requestFormat.internalTextureFormat())
- {
+ 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;
@@ -132,6 +127,76 @@ void QGLFramebufferObjectPool::release(QGLFramebufferObject *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();
+ 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.
+
+ // Pass false to tell bind to _not_ copy the FBO into the texture!
+ GLuint texId = data->bind(false);
+
+ QGL2PaintEngineEx* pe = static_cast<QGL2PaintEngineEx*>(data->paintEngine());
+ QRect rect(0, 0, data->width(), data->height());
+ pe->drawTexture(QRectF(rect), texId, rect.size(), QRectF(rect));
+ }
+}
+
+void QGLPixmapGLPaintDevice::endPaint()
+{
+ if (!data->isValid())
+ return;
+
+ data->copyBackFromRenderFbo(false);
+
+ data->m_renderFbo->release();
+ qgl_fbo_pool()->release(data->m_renderFbo);
+ data->m_renderFbo = 0;
+
+ // Base's endPaint will restore the previous FBO binding
+ QGLPaintDevice::endPaint();
+}
+
+QGLContext* QGLPixmapGLPaintDevice::context() const
+{
+ data->ensureCreated();
+ return data->m_ctx;
+}
+
+QSize QGLPixmapGLPaintDevice::size() const
+{
+ return data->size();
+}
+
+void QGLPixmapGLPaintDevice::setPixmapData(QGLPixmapData* d)
+{
+ data = d;
+}
+
static int qt_gl_pixmap_serial = 0;
QGLPixmapData::QGLPixmapData(PixelType type)
@@ -144,6 +209,7 @@ QGLPixmapData::QGLPixmapData(PixelType type)
, m_hasAlpha(false)
{
setSerialNumber(++qt_gl_pixmap_serial);
+ m_glDevice.setPixmapData(this);
}
QGLPixmapData::~QGLPixmapData()
@@ -237,11 +303,6 @@ void QGLPixmapData::ensureCreated() const
m_texture.options &= ~QGLContext::MemoryManagedBindOption;
}
-QGLFramebufferObject *QGLPixmapData::fbo() const
-{
- return m_renderFbo;
-}
-
void QGLPixmapData::fromImage(const QImage &image,
Qt::ImageConversionFlags)
{
@@ -417,31 +478,6 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->current_fbo);
}
-void QGLPixmapData::swapBuffers()
-{
- if (!isValid())
- return;
-
- copyBackFromRenderFbo(false);
- m_renderFbo->release();
-
- qgl_fbo_pool()->release(m_renderFbo);
-
- m_renderFbo = 0;
-}
-
-void QGLPixmapData::makeCurrent()
-{
- if (isValid() && m_renderFbo)
- m_renderFbo->bind();
-}
-
-void QGLPixmapData::doneCurrent()
-{
- if (isValid() && m_renderFbo)
- m_renderFbo->release();
-}
-
bool QGLPixmapData::useFramebufferObjects()
{
return QGLFramebufferObject::hasOpenGLFramebufferObjects()
@@ -490,6 +526,10 @@ QPaintEngine* QGLPixmapData::paintEngine() const
return m_source.paintEngine();
}
+
+// 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) {
@@ -509,12 +549,6 @@ GLuint QGLPixmapData::bind(bool copyBack) const
return id;
}
-GLuint QGLPixmapData::textureId() const
-{
- ensureCreated();
- return m_texture.id;
-}
-
QGLTexture* QGLPixmapData::texture() const
{
return &m_texture;
@@ -553,4 +587,9 @@ int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
}
}
+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
index ab1ff47..f67a7c2 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -57,12 +57,14 @@
#include "qgl.h"
#include "private/qpixmapdata_p.h"
+#include "private/qglpaintdevice_p.h"
QT_BEGIN_NAMESPACE
class QPaintEngine;
class QGLFramebufferObject;
class QGLFramebufferObjectFormat;
+class QGLPixmapData;
class QGLFramebufferObjectPool
{
@@ -76,31 +78,50 @@ private:
QGLFramebufferObjectPool* qgl_fbo_pool();
+
+class QGLPixmapGLPaintDevice : public QGLPaintDevice
+{
+public:
+ QPaintEngine* paintEngine() const;
+
+ void beginPaint();
+ void endPaint();
+ QGLContext* context() const;
+ QSize size() const;
+
+ void setPixmapData(QGLPixmapData*);
+private:
+ QGLPixmapData *data;
+};
+
+
class QGLPixmapData : public QPixmapData
{
public:
QGLPixmapData(PixelType type);
~QGLPixmapData();
- bool isValid() const;
-
+ // Re-implemented from QPixmapData:
void resize(int width, int height);
- void fromImage(const QImage &image,
- Qt::ImageConversionFlags flags);
+ void fromImage(const QImage &image, 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;
- GLuint textureId() const;
QGLTexture *texture() const;
- bool isValidContext(const QGLContext *ctx) const;
+private:
+ bool isValid() const;
void ensureCreated() const;
@@ -109,22 +130,13 @@ public:
bool needsFill() const { return m_hasFillColor; }
QColor fillColor() const { return m_fillColor; }
- QSize size() const { return QSize(w, h); }
-
- QGLFramebufferObject *fbo() const;
- void makeCurrent();
- void doneCurrent();
- void swapBuffers();
-protected:
- int metric(QPaintDevice::PaintDeviceMetric metric) const;
-
-private:
QGLPixmapData(const QGLPixmapData &other);
QGLPixmapData &operator=(const QGLPixmapData &other);
void copyBackFromRenderFbo(bool keepCurrentFboBound) const;
+ QSize size() const { return QSize(w, h); }
static bool useFramebufferObjects();
@@ -145,6 +157,10 @@ private:
mutable bool m_hasFillColor;
mutable bool m_hasAlpha;
+
+ mutable QGLPixmapGLPaintDevice m_glDevice;
+
+ friend class QGLPixmapGLPaintDevice;
};
QT_END_NAMESPACE
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index a85b9ae..efea369 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -229,6 +229,7 @@ QGLWidget* qt_gl_share_widget()
return _qt_gl_share_widget()->shareWidget();
}
+
struct QGLWindowSurfacePrivate
{
QGLFramebufferObject *fbo;
@@ -248,10 +249,49 @@ struct QGLWindowSurfacePrivate
QSize size;
QList<QImage> buffers;
+ QGLWindowSurfaceGLPaintDevice glDevice;
+ QGLWindowSurface* q_ptr;
};
QGLFormat QGLWindowSurface::surfaceFormat;
+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
+{
+ return d->q_ptr->window()->metric(m);
+}
+
+Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_2_engine)
+
+#if !defined (QT_OPENGL_ES_2)
+Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_engine)
+#endif
+
+QPaintEngine *QGLWindowSurfaceGLPaintDevice::paintEngine() const
+{
+#if !defined(QT_OPENGL_ES_2)
+ if (!qt_gl_preferGL2Engine())
+ return qt_gl_window_surface_engine();
+#endif
+ return qt_gl_window_surface_2_engine();
+}
+
QGLWindowSurface::QGLWindowSurface(QWidget *window)
: QWindowSurface(window), d_ptr(new QGLWindowSurfacePrivate)
{
@@ -263,6 +303,8 @@ QGLWindowSurface::QGLWindowSurface(QWidget *window)
d_ptr->tried_fbo = false;
d_ptr->tried_pb = false;
d_ptr->destructive_swap_buffers = qgetenv("QT_GL_SWAPBUFFER_PRESERVE").isNull();
+ d_ptr->glDevice.d = d_ptr;
+ d_ptr->q_ptr = this;
}
QGLWindowSurface::~QGLWindowSurface()
@@ -320,27 +362,6 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
}
-Q_GLOBAL_STATIC(QGL2PaintEngineEx, qt_gl_window_surface_2_engine)
-
-#if !defined (QT_OPENGL_ES_2)
-Q_GLOBAL_STATIC(QOpenGLPaintEngine, qt_gl_window_surface_engine)
-#endif
-
-/*! \reimp */
-QPaintEngine *QGLWindowSurface::paintEngine() const
-{
-#if !defined(QT_OPENGL_ES_2)
- if (!qt_gl_preferGL2Engine())
- return qt_gl_window_surface_engine();
-#endif
- return qt_gl_window_surface_2_engine();
-}
-
-int QGLWindowSurface::metric(PaintDeviceMetric m) const
-{
- return window()->metric(m);
-}
-
QGLContext *QGLWindowSurface::context() const
{
return d_ptr->ctx;
@@ -354,7 +375,7 @@ QPaintDevice *QGLWindowSurface::paintDevice()
return d_ptr->pb;
if (d_ptr->ctx)
- return this;
+ return &d_ptr->glDevice;
QGLContext *ctx = reinterpret_cast<QGLContext *>(window()->d_func()->extraData()->glContext);
ctx->makeCurrent();
diff --git a/src/opengl/qwindowsurface_gl_p.h b/src/opengl/qwindowsurface_gl_p.h
index ad583b2..5a9f38c 100644
--- a/src/opengl/qwindowsurface_gl_p.h
+++ b/src/opengl/qwindowsurface_gl_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
@@ -56,6 +56,7 @@
#include <qglobal.h>
#include <qgl.h>
#include <private/qwindowsurface_p.h>
+#include <private/qglpaintdevice_p.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +66,18 @@ class QRegion;
class QWidget;
struct QGLWindowSurfacePrivate;
-class QGLWindowSurface : public QObject, public QWindowSurface, public QPaintDevice
+class QGLWindowSurfaceGLPaintDevice : public QGLPaintDevice
+{
+public:
+ QPaintEngine* paintEngine() const;
+ void endPaint();
+ QSize size() const;
+ int metric(PaintDeviceMetric m) const;
+ QGLContext* context() const;
+ QGLWindowSurfacePrivate* d;
+};
+
+class QGLWindowSurface : public QObject, public QWindowSurface // , public QPaintDevice
{
Q_OBJECT
public:
@@ -87,11 +99,6 @@ public:
static QGLFormat surfaceFormat;
- QPaintEngine *paintEngine() const;
-
-protected:
- int metric(PaintDeviceMetric metric) const;
-
private slots:
void deleted(QObject *object);
diff --git a/src/opengl/util/fragmentprograms_p.h b/src/opengl/util/fragmentprograms_p.h
index b02c600..dad8795 100644
--- a/src/opengl/util/fragmentprograms_p.h
+++ b/src/opengl/util/fragmentprograms_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/util/generator.cpp b/src/opengl/util/generator.cpp
index 3c2c672..548a97b 100644
--- a/src/opengl/util/generator.cpp
+++ b/src/opengl/util/generator.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2009 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.
@@ -20,10 +21,9 @@
** 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.
+** 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
diff --git a/src/opengl/util/glsl_to_include.sh b/src/opengl/util/glsl_to_include.sh
index 083ad1e..e0421c5 100755
--- a/src/opengl/util/glsl_to_include.sh
+++ b/src/opengl/util/glsl_to_include.sh
@@ -2,6 +2,7 @@
#############################################################################
##
## Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+## All rights reserved.
## Contact: Nokia Corporation (qt-info@nokia.com)
##
## This file is the build configuration utility of the Qt Toolkit.
@@ -21,10 +22,9 @@
## 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.
+## 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.
##
## If you have questions regarding the use of this file, please contact
## Nokia at qt-info@nokia.com.