summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qopenglcontext.cpp
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2012-01-26 11:44:05 +0100
committerQt by Nokia <qt-info@nokia.com>2012-01-27 10:58:32 +0100
commit2d39471897f0a3a769406ec9c2b39558ebd45af3 (patch)
tree8c417f4ba814e9dbe70e56bdbf8a13cc46b3827f /src/gui/kernel/qopenglcontext.cpp
parent365b5f7a9271e5fc503b10e6c17371d76643fc94 (diff)
Introduced QOpenGLContext::defaultFramebufferObject().
Also add some debugging helpers to make sure applications are correctly written even on less restrictive platforms. Change-Id: Ie92e497c32e07b2b83662f7ab5540d8f37777fd0 Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
Diffstat (limited to 'src/gui/kernel/qopenglcontext.cpp')
-rw-r--r--src/gui/kernel/qopenglcontext.cpp71
1 files changed, 69 insertions, 2 deletions
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 29107d4261..cd4e8ebc01 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -68,6 +68,11 @@ public:
static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage;
+#ifndef QT_NO_DEBUG
+QHash<QOpenGLContext *, bool> QOpenGLContextPrivate::makeCurrentTracker;
+QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex;
+#endif
+
void QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context)
{
QGuiGLThreadContext *threadContext = qwindow_context_storage.localData();
@@ -204,6 +209,10 @@ void QOpenGLContext::destroy()
QOpenGLContext::~QOpenGLContext()
{
destroy();
+
+#ifndef QT_NO_DEBUG
+ QOpenGLContextPrivate::cleanMakeCurrentTracker(this);
+#endif
}
/*!
@@ -230,6 +239,29 @@ QOpenGLFunctions *QOpenGLContext::functions() const
}
/*!
+ Call this to get the default framebuffer object for the current surface.
+
+ On some platforms the default framebuffer object depends on the surface being rendered to,
+ and might be different from 0. Thus, instead of calling glBindFramebuffer(0), you should
+ call glBindFramebuffer(ctx->defaultFramebufferObject()) if you want your application to
+ work across different Qt platforms.
+
+ If you use the glBindFramebuffer() in QOpenGLFunctions you do not have to worry about this,
+ as it automatically binds the current context's defaultFramebufferObject() when 0 is passed.
+*/
+GLuint QOpenGLContext::defaultFramebufferObject() const
+{
+ if (!isValid())
+ return 0;
+
+ Q_D(const QOpenGLContext);
+ if (!d->surface || !d->surface->surfaceHandle())
+ return 0;
+
+ return d->platformGLContext->defaultFramebufferObject(d->surface->surfaceHandle());
+}
+
+/*!
If surface is 0 this is equivalent to calling doneCurrent().
Do not call this function from a different thread than the one the QOpenGLContext instance lives in. If
@@ -260,6 +292,10 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
d->shareGroup->d_func()->deletePendingResources(this);
+#ifndef QT_NO_DEBUG
+ QOpenGLContextPrivate::toggleMakeCurrentTracker(this, true);
+#endif
+
return true;
}
@@ -294,6 +330,17 @@ QSurface *QOpenGLContext::surface() const
}
+/*!
+ Swap the back and front buffers of the given surface.
+
+ Call this to finish a frame of OpenGL rendering, and make sure to
+ call makeCurrent() again before you begin a new frame.
+
+ If you have bound a non-default framebuffer object, you need to
+ use bindDefaultFramebufferObject() to make sure that the default
+ framebuffer object is bound before calling swapBuffers(), as
+ some Qt platforms assume that the default framebuffer object is bound.
+*/
void QOpenGLContext::swapBuffers(QSurface *surface)
{
Q_D(QOpenGLContext);
@@ -306,8 +353,28 @@ void QOpenGLContext::swapBuffers(QSurface *surface)
}
QPlatformSurface *surfaceHandle = surface->surfaceHandle();
- if (surfaceHandle)
- d->platformGLContext->swapBuffers(surfaceHandle);
+ if (!surfaceHandle)
+ return;
+
+#if !defined(QT_NO_DEBUG)
+ if (currentContext() != this)
+ qWarning() << "QOpenGLContext::swapBuffers() called with non-current surface";
+ else if (!QOpenGLContextPrivate::toggleMakeCurrentTracker(this, false))
+ qWarning() << "QOpenGLContext::swapBuffers() called without corresponding makeCurrent()";
+
+#ifndef GL_FRAMEBUFFER_BINDING
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#endif
+
+ GLint framebufferBinding = 0;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebufferBinding);
+
+ GLint platformFramebuffer = GLint(d->platformGLContext->defaultFramebufferObject(surfaceHandle));
+ if (framebufferBinding != platformFramebuffer)
+ qWarning() << "QOpenGLContext::swapBuffers() called with non-default framebuffer object bound";
+#endif
+
+ d->platformGLContext->swapBuffers(surfaceHandle);
}
QFunctionPointer QOpenGLContext::getProcAddress(const QByteArray &procName)