diff options
-rw-r--r-- | src/corelib/global/qnamespace.h | 3 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 65 | ||||
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h | 3 | ||||
-rw-r--r-- | src/opengl/opengl.pro | 6 | ||||
-rw-r--r-- | src/opengl/qgl.cpp | 5 | ||||
-rw-r--r-- | src/opengl/qgl.h | 2 | ||||
-rw-r--r-- | src/opengl/qgl_p.h | 7 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 3 | ||||
-rw-r--r-- | src/opengl/qglpaintdevice.cpp | 192 | ||||
-rw-r--r-- | src/opengl/qglpaintdevice_p.h | 168 | ||||
-rw-r--r-- | src/opengl/qpaintengine_opengl.cpp | 113 |
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() |