summaryrefslogtreecommitdiffstats
path: root/src/opengl/qglframebufferobject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qglframebufferobject.cpp')
-rw-r--r--src/opengl/qglframebufferobject.cpp136
1 files changed, 71 insertions, 65 deletions
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index 452f155..9dbf5c8 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,40 +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)
- {
- }
-
- QAtomicInt ref;
- int samples;
- QGLFramebufferObject::Attachment attachment;
- GLenum target;
- GLenum internal_format;
-};
-
/*!
\class QGLFramebufferObjectFormat
\brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL
@@ -311,28 +278,59 @@ void QGLFramebufferObjectFormat::setInternalTextureFormat(QMacCompatGLenum inter
}
#endif
-class QGLFramebufferObjectPrivate
+/*!
+ Returns true if all the options of this framebuffer object format
+ are the same as \a other; otherwise returns false.
+*/
+bool QGLFramebufferObjectFormat::operator==(const QGLFramebufferObjectFormat& other) const
+{
+ if (d == other.d)
+ return true;
+ else
+ return d->equals(other.d);
+}
+
+/*!
+ Returns false if all the options of this framebuffer object format
+ are the same as \a other; otherwise returns true.
+*/
+bool QGLFramebufferObjectFormat::operator!=(const QGLFramebufferObjectFormat& other) const
+{
+ return !(*this == other);
+}
+
+void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f)
+{
+ fbo = f;
+ m_thisFBO = fbo->d_func()->fbo; // This shouldn't be needed
+}
+
+void QGLFBOGLPaintDevice::ensureActiveTarget()
{
-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;
-};
+ QGLContext* ctx = const_cast<QGLContext*>(QGLContext::currentContext());
+ Q_ASSERT(ctx);
+ const GLuint fboId = fbo->d_func()->fbo;
+ if (ctx->d_func()->current_fbo != fboId) {
+ ctx->d_func()->current_fbo = fboId;
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId);
+ }
+}
+
+void QGLFBOGLPaintDevice::beginPaint()
+{
+ // We let QFBO track the previously bound FBO rather than doing it
+ // ourselves here. This has the advantage that begin/release & bind/end
+ // work as expected.
+ wasBound = fbo->isBound();
+ if (!wasBound)
+ fbo->bind();
+}
+
+void QGLFBOGLPaintDevice::endPaint()
+{
+ if (!wasBound)
+ fbo->release();
+}
bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
{
@@ -378,11 +376,14 @@ 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;
@@ -395,6 +396,8 @@ void QGLFramebufferObjectPrivate::init(const QSize &sz, QGLFramebufferObject::At
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
+ glDevice.setFBO(q);
+
QT_CHECK_GLERROR();
// init texture
if (samples == 0) {
@@ -641,7 +644,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
@@ -665,7 +669,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
@@ -678,7 +682,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
@@ -691,7 +696,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
@@ -700,7 +706,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
@@ -721,7 +727,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
@@ -731,7 +737,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
@@ -752,7 +758,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
@@ -762,7 +768,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