summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qnamespace.h3
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp65
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h3
-rw-r--r--src/opengl/opengl.pro6
-rw-r--r--src/opengl/qgl.cpp5
-rw-r--r--src/opengl/qgl.h2
-rw-r--r--src/opengl/qgl_p.h7
-rw-r--r--src/opengl/qgl_x11.cpp3
-rw-r--r--src/opengl/qglpaintdevice.cpp192
-rw-r--r--src/opengl/qglpaintdevice_p.h168
-rw-r--r--src/opengl/qpaintengine_opengl.cpp113
11 files changed, 483 insertions, 84 deletions
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index 8f34e30..93de911 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1655,7 +1655,8 @@ public:
FramebufferObject = 0x07, // GL framebuffer object
CustomRaster = 0x08,
MacQuartz = 0x09,
- PaintBuffer = 0x0a
+ PaintBuffer = 0x0a,
+ OpenGL = 0x0b
};
enum RelayoutType {
RelayoutNormal,
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index e24539b..8fee83d 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -710,7 +710,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();
@@ -1308,21 +1308,28 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
Q_D(QGL2PaintEngineEx);
// qDebug("QGL2PaintEngineEx::begin()");
- d->drawable.setDevice(pdev);
- d->ctx = d->drawable.context();
+ 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();
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();
+ p->device->context()->doneCurrent();
}
d->ctx->d_ptr->active_engine = this;
d->last_created_state = 0;
- d->drawable.makeCurrent();
- QSize sz = d->drawable.size();
+ d->device->beginPaint();
+ QSize sz = d->device->size();
d->width = sz.width();
d->height = sz.height();
d->mode = BrushDrawingMode;
@@ -1358,28 +1365,29 @@ 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())
+// QGLPixmapData *source = d->drawable.copyOnBegin();
+ if (d->ctx->d_func()->clear_on_painter_begin && d->device->autoFillBackground()) {
+ if (d->device->hasTransparentBackground())
glClearColor(0.0, 0.0, 0.0, 0.0);
else {
- const QColor &c = d->drawable.backgroundColor();
+ const QColor &c = d->device->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);
}
+// 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;
@@ -1394,14 +1402,15 @@ bool QGL2PaintEngineEx::end()
if (engine && engine->isActive()) {
QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr.data());
p->transferMode(BrushDrawingMode);
- p->drawable.doneCurrent();
+ p->device->context()->doneCurrent();
}
- d->drawable.makeCurrent();
+ d->device->context()->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
@@ -1410,7 +1419,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();
@@ -1431,15 +1439,14 @@ void QGL2PaintEngineEx::ensureActive()
if (engine && engine->isActive()) {
QGL2PaintEngineExPrivate *p = static_cast<QGL2PaintEngineExPrivate *>(engine->d_ptr.data());
p->transferMode(BrushDrawingMode);
- p->drawable.doneCurrent();
+ p->device->context()->doneCurrent();
}
- d->drawable.context()->makeCurrent();
- d->drawable.makeCurrent();
+ d->device->context()->makeCurrent();
ctx->d_ptr->active_engine = this;
d->needsSync = true;
} else {
- d->drawable.context()->makeCurrent();
+ d->device->context()->makeCurrent();
}
if (d->needsSync) {
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index cb23b11..2fbee1b 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -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..2aefe41 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -22,13 +22,17 @@ HEADERS += qgl.h \
qglpixelbuffer.h \
qglpixelbuffer_p.h \
qglframebufferobject.h \
- qglextensions_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 02bb8f9..ad54298 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -4815,6 +4815,8 @@ void QGLWidgetPrivate::initContext(QGLContext *context, const QGLWidget* shareWi
{
Q_Q(QGLWidget);
+ glDevice.setWidget(q);
+
QGLExtensions::init();
glcx = 0;
autoSwap = true;
@@ -4850,6 +4852,7 @@ Q_OPENGL_EXPORT const QString qt_gl_library_name()
}
#endif
+#if 0
void QGLDrawable::setDevice(QPaintDevice *pdev)
{
wasBound = false;
@@ -5084,7 +5087,7 @@ bool QGLDrawable::autoFillBackground() const
else
return false;
}
-
+#endif
bool QGLShareRegister::checkSharing(const QGLContext *context1, const QGLContext *context2) {
bool sharing = (context1 && context2 && context1->d_ptr->group == context2->d_ptr->group);
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index b110665..46efe23 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -542,6 +542,8 @@ private:
friend class QGLContext;
friend class QGLOverlayWidget;
friend class QOpenGLPaintEngine;
+ friend class QGLPaintDevice;
+ friend class QGLWidgetGLPaintDevice;
};
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index f8158a0..03532c8 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -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
@@ -189,7 +190,8 @@ public:
bool renderCxPm(QPixmap *pixmap);
void cleanupColormaps();
- QGLContext *glcx;
+ QGLContext *glcx; // ### Keep for compatability with QGLDrawable (if that gets left in)
+ QGLWidgetGLPaintDevice glDevice;
bool autoSwap;
QGLColormap cmap;
@@ -337,6 +339,7 @@ Q_SIGNALS:
void aboutToDestroyContext(const QGLContext *context);
};
+#if 0
class QGLPixelBuffer;
class QGLFramebufferObject;
class QWSGLWindowSurface;
@@ -388,6 +391,8 @@ private:
int previous_fbo;
};
+#endif
+
// GL extension definitions
class QGLExtensions {
public:
diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp
index 81985cd..5da128d 100644
--- a/src/opengl/qgl_x11.cpp
+++ b/src/opengl/qgl_x11.cpp
@@ -41,6 +41,7 @@
#include "qgl.h"
#include "qgl_p.h"
+#include "qglpaintdevice_p.h"
#include "qmap.h"
#include "qapplication.h"
@@ -1307,7 +1308,7 @@ void QGLWidget::setContext(QGLContext *context,
d->glcx->doneCurrent();
QGLContext* oldcx = d->glcx;
d->glcx = context;
-
+ d->glDevice.setContext(context); // ### Do this for all platforms
if (parentWidget()) {
// force creation of delay-created widgets
diff --git a/src/opengl/qglpaintdevice.cpp b/src/opengl/qglpaintdevice.cpp
new file mode 100644
index 0000000..f7bd2a3
--- /dev/null
+++ b/src/opengl/qglpaintdevice.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <private/qglpaintdevice_p.h>
+#include <private/qgl_p.h>
+
+QGLPaintDevice::QGLPaintDevice()
+ : m_context(0)
+{
+}
+
+QGLPaintDevice::~QGLPaintDevice()
+{
+}
+
+//extern QPaintEngine* qt_gl_engine(); // in qgl.cpp
+//extern QPaintEngine* qt_gl_2_engine(); // in qgl.cpp
+
+//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
+//}
+
+//QPaintEngine* QGLPaintDevice::paintEngine() const
+//{
+//#if defined(QT_OPENGL_ES_1) || defined(QT_OPENGL_ES_1_CL)
+// return qt_gl_engine();
+//#elif defined(QT_OPENGL_ES_2)
+// return qt_gl_2_engine();
+//#else
+// if (!qt_gl_preferGL2Engine())
+// return qt_gl_engine();
+// else
+// return qt_gl_2_engine();
+//#endif
+//}
+
+void QGLPaintDevice::beginPaint()
+{
+ m_context->makeCurrent();
+}
+
+void QGLPaintDevice::endPaint()
+{
+}
+
+QColor QGLPaintDevice::backgroundColor() const
+{
+ return QColor();
+}
+
+bool QGLPaintDevice::autoFillBackground() const
+{
+ return false;
+}
+
+bool QGLPaintDevice::hasTransparentBackground() const
+{
+ return false;
+}
+
+QGLContext* QGLPaintDevice::context() const
+{
+ return m_context;
+}
+
+QGLFormat QGLPaintDevice::format() const
+{
+ return m_context->format();
+}
+
+QSize QGLPaintDevice::size() const
+{
+ return QSize();
+}
+
+void QGLPaintDevice::setContext(QGLContext* c)
+{
+ m_context = c;
+}
+
+
+
+QGLWidgetGLPaintDevice::QGLWidgetGLPaintDevice()
+{
+}
+
+QPaintEngine* QGLWidgetGLPaintDevice::paintEngine() const
+{
+ return glWidget->paintEngine();
+}
+
+QColor QGLWidgetGLPaintDevice::backgroundColor() const
+{
+ return glWidget->palette().brush(glWidget->backgroundRole()).color();
+}
+
+bool QGLWidgetGLPaintDevice::autoFillBackground() const
+{
+ return glWidget->autoFillBackground();
+}
+
+bool QGLWidgetGLPaintDevice::hasTransparentBackground() const
+{
+ return glWidget->testAttribute(Qt::WA_TranslucentBackground);
+}
+
+void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w)
+{
+ glWidget = w;
+}
+
+//void QGLWidgetGLPaintDevice::beginPaint()
+//{
+// glWidget->makeCurrent();
+//}
+
+void QGLWidgetGLPaintDevice::endPaint()
+{
+ if (glWidget->autoBufferSwap())
+ glWidget->swapBuffers();
+}
+
+
+QSize QGLWidgetGLPaintDevice::size() const
+{
+ return glWidget->size();
+}
+
+// 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;
+ default:
+ qWarning("QGLPaintDevice::getDevice() - Unknown device type %d", pd->devType());
+ break;
+ }
+
+ return glpd;
+}
+
+
diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h
new file mode 100644
index 0000000..ad680a9
--- /dev/null
+++ b/src/opengl/qglpaintdevice_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+** $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>
+
+class QGLPaintDevice : public QPaintDevice
+{
+public:
+ QGLPaintDevice();
+ virtual ~QGLPaintDevice();
+
+ virtual void beginPaint();
+ virtual void endPaint();
+
+ virtual QColor backgroundColor() const;
+ virtual bool autoFillBackground() const;
+ virtual bool hasTransparentBackground() const;
+
+ // inline these?
+ QGLContext* context() const;
+ QGLFormat format() const;
+ virtual QSize size() const;
+
+ // returns the QGLPaintDevice for the given QPaintDevice
+ static QGLPaintDevice* getDevice(QPaintDevice*);
+
+protected:
+ // Inline?
+ void setContext(QGLContext* c);
+
+private:
+ QGLContext* m_context;
+};
+
+
+// Wraps a QGLWidget
+class QGLWidget;
+class QGLWidgetGLPaintDevice : public QGLPaintDevice
+{
+public:
+ QGLWidgetGLPaintDevice();
+
+ virtual QPaintEngine* paintEngine() const;
+
+ virtual QColor backgroundColor() const;
+ virtual bool autoFillBackground() const;
+ virtual bool hasTransparentBackground() const;
+
+ // QGLWidgets need to do swapBufers in endPaint:
+ virtual void endPaint();
+ virtual QSize size() const;
+
+ void setWidget(QGLWidget*);
+
+private:
+ friend class QGLWidget;
+ QGLWidget *glWidget;
+};
+
+
+
+/*
+Replaces:
+
+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;
+ GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
+ GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
+ 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;
+};
+*/
+
+#endif // QGLPAINTDEVICE_P_H
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index bf4d4b9..634067d 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -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,8 @@ public Q_SLOTS:
}
private:
- QGLDrawable drawable;
+// QGLDrawable drawable;
+ QGLPaintDevice* device;
QGLFramebufferObject *offscreen;
QGLContext *ctx;
@@ -305,7 +307,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 +337,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 +356,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 +436,11 @@ inline void QGLOffscreen::release()
DEBUG_ONCE_STR("QGLOffscreen: releasing offscreen");
if (drawable_fbo)
- drawable.makeCurrent();
+ device->context()->makeCurrent(); //###
else
offscreen->release();
- QSize sz(drawable.size());
+ QSize sz(device->size());
glViewport(0, 0, sz.width(), sz.height());
glMatrixMode(GL_PROJECTION);
@@ -455,7 +463,7 @@ inline bool QGLOffscreen::isBound() const
inline QSize QGLOffscreen::drawableSize() const
{
- return drawable.size();
+ return device->size();
}
inline QSize QGLOffscreen::offscreenSize() const
@@ -757,7 +765,8 @@ public:
GLubyte pen_color[4];
GLubyte brush_color[4];
QTransform::TransformationType txop;
- QGLDrawable drawable;
+// QGLDrawable drawable;
+ QGLPaintDevice* device;
QGLOffscreen offscreen;
qreal inverseScale;
@@ -1167,7 +1176,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 +1245,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 +1272,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 +1281,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,12 +1349,12 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
d->offscreen.begin();
- if (d->drawable.context()->d_func()->clear_on_painter_begin && d->drawable.autoFillBackground()) {
+ if (d->device->context()->d_func()->clear_on_painter_begin && d->device->autoFillBackground()) {
- if (d->drawable.hasTransparentBackground())
+ if (d->device->hasTransparentBackground())
glClearColor(0.0, 0.0, 0.0, 0.0);
else {
- const QColor &c = d->drawable.backgroundColor();
+ const QColor &c = d->device->backgroundColor();
glClearColor(c.redF(), c.greenF(), c.blueF(), 1.0);
}
@@ -1349,7 +1365,7 @@ bool QOpenGLPaintEngine::begin(QPaintDevice *pdev)
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 +1382,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 +1398,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 +1433,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 +1450,7 @@ bool QOpenGLPaintEngine::end()
glPopClientAttrib();
}
#endif
- d->drawable.swapBuffers();
- d->drawable.doneCurrent();
+ d->device->endPaint();
qt_mask_texture_cache()->maintainCache();
return true;
@@ -1961,7 +1976,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 +2257,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 +2340,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 +2377,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 +3384,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 +3521,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 +3931,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 +4317,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);
}
}
@@ -4336,9 +4351,9 @@ void QOpenGLPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, con
d->flushDrawQueue();
if (scaled.isNull())
- d->drawable.bindTexture(pm);
+ d->device->context()->bindTexture(pm);
else
- d->drawable.bindTexture(scaled);
+ d->device->context()->bindTexture(scaled);
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, d->use_smooth_pixmap_transform);
#ifndef QT_OPENGL_ES
@@ -4404,7 +4419,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);
}
}
@@ -4871,7 +4886,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);
@@ -4949,7 +4964,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,
@@ -5084,10 +5099,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);
@@ -5181,9 +5196,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);
}
@@ -5191,7 +5206,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);
@@ -5263,7 +5278,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()