diff options
author | Tom Cooksey <thomas.cooksey@nokia.com> | 2009-09-01 13:52:44 (GMT) |
---|---|---|
committer | Tom Cooksey <thomas.cooksey@nokia.com> | 2009-09-08 16:36:14 (GMT) |
commit | e8b5bfa8a86b2d7c79aabcc4566f740f0a9afe7c (patch) | |
tree | b11a5707ef080a8ef94fb3e7a2e79ce38d7576a4 | |
parent | b7963df603a315136b32297b861f089c0cd49acd (diff) | |
download | Qt-e8b5bfa8a86b2d7c79aabcc4566f740f0a9afe7c.zip Qt-e8b5bfa8a86b2d7c79aabcc4566f740f0a9afe7c.tar.gz Qt-e8b5bfa8a86b2d7c79aabcc4566f740f0a9afe7c.tar.bz2 |
Make QGLFramebufferObject work again using new QGLPaintDevice API
This patch also refactors QGL2PaintEngineEx::ensureActive() and the
logic which handles multiple paint engines rendering to the same
QGLContext. In a nut-shell:
* QGLPaintDevice::beginPaint() stores the currently bound FBO
* QGLPaintDevice::ensureActiveTarget() makes sure that GL rendering will
end up in the paint device (I.e. the right context is current and the
right FBO is bound). If a different context or FBO was bound, it is
_not_ remembered.
* QGLPaintDevice::endPaint() restores whatever FBO was bound when
beginPaint() was called.
This logic allows interleaved painter rendering to multiple FBOs and
contexts to work as expected. It also allows a stacked begin/end to work
properly when it's mixed with native GL rendering (as far as current
render target is concerened. GL state clobbering is obviously a
different topic).
QGLPaintDevice::context() also had to be made virtual as there's no good
place to call setContext. This might be possible to change in the future
though.
Finally, to make this work, QGLFramebufferObjectPrivate had to be moved
into it's own private header.
-rw-r--r-- | src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 28 | ||||
-rw-r--r-- | src/opengl/opengl.pro | 1 | ||||
-rw-r--r-- | src/opengl/qgl.h | 4 | ||||
-rw-r--r-- | src/opengl/qgl_x11.cpp | 2 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.cpp | 113 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject.h | 4 | ||||
-rw-r--r-- | src/opengl/qglframebufferobject_p.h | 151 | ||||
-rw-r--r-- | src/opengl/qglpaintdevice.cpp | 82 | ||||
-rw-r--r-- | src/opengl/qglpaintdevice_p.h | 10 | ||||
-rw-r--r-- | src/opengl/qglpixelbuffer.cpp | 12 | ||||
-rw-r--r-- | src/opengl/qglpixelbuffer_p.h | 2 |
11 files changed, 257 insertions, 152 deletions
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 8fee83d..fcfd818 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1318,13 +1318,6 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) 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->device->context()->doneCurrent(); - } - d->ctx->d_ptr->active_engine = this; d->last_created_state = 0; @@ -1397,15 +1390,6 @@ 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->device->context()->doneCurrent(); - } - d->device->context()->makeCurrent(); - } glUseProgram(0); d->transferMode(BrushDrawingMode); @@ -1435,20 +1419,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->device->context()->doneCurrent(); - } - d->device->context()->makeCurrent(); - ctx->d_ptr->active_engine = this; d->needsSync = true; - } else { - d->device->context()->makeCurrent(); } + d->device->ensureActiveTarget(); + if (d->needsSync) { glViewport(0, 0, d->width, d->height); glDepthMask(false); diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro index 2aefe41..d479c2e 100644 --- a/src/opengl/opengl.pro +++ b/src/opengl/opengl.pro @@ -22,6 +22,7 @@ HEADERS += qgl.h \ qglpixelbuffer.h \ qglpixelbuffer_p.h \ qglframebufferobject.h \ + qglframebufferobject_p.h \ qglextensions_p.h \ qglpaintdevice_p.h \ diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 46efe23..ce50c58 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -385,7 +385,7 @@ private: friend class QGLPixelBuffer; friend class QGLPixelBufferPrivate; friend class QGLWidget; - friend class QGLDrawable; +// friend class QGLDrawable; friend class QGLWidgetPrivate; friend class QGLGlyphCache; friend class QOpenGLPaintEngine; @@ -407,6 +407,8 @@ private: #endif friend class QGLFramebufferObject; friend class QGLFramebufferObjectPrivate; + friend class QGLFBOGLPaintDevice; + friend class QGLPaintDevice; private: Q_DISABLE_COPY(QGLContext) }; diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 5da128d..fc29264 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1308,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 +// d->glDevice.setContext(context); // ### Do this for all platforms if (parentWidget()) { // force creation of delay-created widgets diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 9990586..f60eb62 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qglframebufferobject.h" +#include "qglframebufferobject_p.h" #include <qdebug.h> #include <private/qgl_p.h> @@ -74,47 +75,6 @@ extern QImage qt_gl_read_framebuffer(const QSize&, bool, bool); } \ } -#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 QGLFramebufferObjectFormat \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL @@ -339,28 +299,32 @@ bool QGLFramebufferObjectFormat::operator!=(const QGLFramebufferObjectFormat& ot return !(*this == other); } -class QGLFramebufferObjectPrivate +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() { -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; - QGLContextGroup *ctx; // for Windows extension ptrs - GLuint previous_fbo; - mutable QPaintEngine *engine; -}; + if (!wasBound) + fbo->release(); +} bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const { @@ -406,11 +370,13 @@ 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) { QGLContext *currentContext = const_cast<QGLContext *>(QGLContext::currentContext()); ctx = QGLContextPrivate::contextGroup(currentContext); + glDevice.setFBO(q); bool ext_detected = (QGLExtensions::glExtensions & QGLExtensions::FramebufferObject); if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(currentContext))) return; @@ -669,7 +635,8 @@ QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target) : d_ptr(new QGLFramebufferObjectPrivate) { Q_D(QGLFramebufferObject); - d->init(size, NoAttachment, target, DEFAULT_FORMAT); + d->glDevice.setFBO(this); + d->init(this, size, NoAttachment, target, DEFAULT_FORMAT); } #ifdef Q_MAC_COMPAT_GL_FUNCTIONS @@ -693,7 +660,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 @@ -706,7 +673,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 @@ -719,7 +687,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 @@ -728,7 +697,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 @@ -749,7 +718,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 @@ -759,7 +728,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 @@ -780,7 +749,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 @@ -790,7 +759,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 diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h index 2778ec5..29b1f97 100644 --- a/src/opengl/qglframebufferobject.h +++ b/src/opengl/qglframebufferobject.h @@ -130,7 +130,9 @@ protected: private: Q_DISABLE_COPY(QGLFramebufferObject) QScopedPointer<QGLFramebufferObjectPrivate> d_ptr; - friend class QGLDrawable; +// friend class QGLDrawable; + friend class QGLPaintDevice; + friend class QGLFBOGLPaintDevice; }; class QGLFramebufferObjectFormatPrivate; diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h new file mode 100644 index 0000000..65fcf54 --- /dev/null +++ b/src/opengl/qglframebufferobject_p.h @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** 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 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());} + void setFBO(QGLFramebufferObject* f) {fbo = f; } + virtual void ensureActiveTarget(); + virtual void beginPaint(); + virtual void endPaint(); + +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 index 9815add..51f9627 100644 --- a/src/opengl/qglpaintdevice.cpp +++ b/src/opengl/qglpaintdevice.cpp @@ -42,9 +42,9 @@ #include <private/qglpaintdevice_p.h> #include <private/qgl_p.h> #include <private/qglpixelbuffer_p.h> +#include <private/qglframebufferobject_p.h> QGLPaintDevice::QGLPaintDevice() - : m_context(0) { } @@ -52,41 +52,38 @@ 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(); + // Record the currently bound FBO so we can restore it again + // in endPaint() + QGLContext *ctx = context(); + ctx->makeCurrent(); + m_previousFBO = ctx->d_func()->current_fbo; + if (m_previousFBO != 0) { + ctx->d_ptr->current_fbo = 0; + glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); + } +} + +void QGLPaintDevice::ensureActiveTarget() +{ + QGLContext* ctx = context(); + if (ctx != QGLContext::currentContext()) + ctx->makeCurrent(); + + if (ctx->d_ptr->current_fbo != 0) + glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0); } void QGLPaintDevice::endPaint() { - glFlush(); + // 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); + } } QColor QGLPaintDevice::backgroundColor() const @@ -104,14 +101,9 @@ bool QGLPaintDevice::hasTransparentBackground() const return false; } -QGLContext* QGLPaintDevice::context() const -{ - return m_context; -} - QGLFormat QGLPaintDevice::format() const { - return m_context->format(); + return context()->format(); } QSize QGLPaintDevice::size() const @@ -119,12 +111,6 @@ QSize QGLPaintDevice::size() const return QSize(); } -void QGLPaintDevice::setContext(QGLContext* c) -{ - m_context = c; -} - - QGLWidgetGLPaintDevice::QGLWidgetGLPaintDevice() { @@ -155,15 +141,11 @@ void QGLWidgetGLPaintDevice::setWidget(QGLWidget* w) glWidget = w; } -//void QGLWidgetGLPaintDevice::beginPaint() -//{ -// glWidget->makeCurrent(); -//} - void QGLWidgetGLPaintDevice::endPaint() { if (glWidget->autoBufferSwap()) glWidget->swapBuffers(); + QGLPaintDevice::endPaint(); } @@ -172,6 +154,11 @@ 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) { @@ -186,6 +173,9 @@ QGLPaintDevice* QGLPaintDevice::getDevice(QPaintDevice* pd) case QInternal::Pbuffer: glpd = &(static_cast<QGLPixelBuffer*>(pd)->d_func()->glDevice); break; + case QInternal::FramebufferObject: + glpd = &(static_cast<QGLFramebufferObject*>(pd)->d_func()->glDevice); + break; default: qWarning("QGLPaintDevice::getDevice() - Unknown device type %d", pd->devType()); break; diff --git a/src/opengl/qglpaintdevice_p.h b/src/opengl/qglpaintdevice_p.h index ad680a9..c5fa626 100644 --- a/src/opengl/qglpaintdevice_p.h +++ b/src/opengl/qglpaintdevice_p.h @@ -63,14 +63,14 @@ public: virtual ~QGLPaintDevice(); virtual void beginPaint(); + virtual void ensureActiveTarget(); virtual void endPaint(); virtual QColor backgroundColor() const; virtual bool autoFillBackground() const; virtual bool hasTransparentBackground() const; - // inline these? - QGLContext* context() const; + virtual QGLContext* context() const = 0; QGLFormat format() const; virtual QSize size() const; @@ -79,10 +79,11 @@ public: protected: // Inline? - void setContext(QGLContext* c); +// void setContext(QGLContext* c); private: - QGLContext* m_context; +// QGLContext* m_context; + GLuint m_previousFBO; }; @@ -102,6 +103,7 @@ public: // QGLWidgets need to do swapBufers in endPaint: virtual void endPaint(); virtual QSize size() const; + virtual QGLContext* context() const; void setWidget(QGLWidget*); diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index f7cb3cc..45ab3bc 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -101,10 +101,20 @@ 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; - setContext(pb->d_func()->qctx); +// setContext(pb->d_func()->qctx); } void QGLPixelBufferPrivate::common_init(const QSize &size, const QGLFormat &format, QGLWidget *shareWidget) diff --git a/src/opengl/qglpixelbuffer_p.h b/src/opengl/qglpixelbuffer_p.h index e24d1ea..96d41d7 100644 --- a/src/opengl/qglpixelbuffer_p.h +++ b/src/opengl/qglpixelbuffer_p.h @@ -142,6 +142,8 @@ 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; |