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 /src/opengl/qglpaintdevice.cpp | |
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.
Diffstat (limited to 'src/opengl/qglpaintdevice.cpp')
-rw-r--r-- | src/opengl/qglpaintdevice.cpp | 82 |
1 files changed, 36 insertions, 46 deletions
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; |