summaryrefslogtreecommitdiffstats
path: root/src/opengl/qglframebufferobject.cpp
diff options
context:
space:
mode:
authorTom Cooksey <thomas.cooksey@nokia.com>2009-09-01 13:52:44 (GMT)
committerTom Cooksey <thomas.cooksey@nokia.com>2009-09-08 16:36:14 (GMT)
commite8b5bfa8a86b2d7c79aabcc4566f740f0a9afe7c (patch)
treeb11a5707ef080a8ef94fb3e7a2e79ce38d7576a4 /src/opengl/qglframebufferobject.cpp
parentb7963df603a315136b32297b861f089c0cd49acd (diff)
downloadQt-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.
Diffstat (limited to 'src/opengl/qglframebufferobject.cpp')
-rw-r--r--src/opengl/qglframebufferobject.cpp113
1 files changed, 41 insertions, 72 deletions
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