diff options
author | Samuel Rødal <samuel.rodal@nokia.com> | 2012-01-26 11:44:05 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-01-27 10:58:32 +0100 |
commit | 2d39471897f0a3a769406ec9c2b39558ebd45af3 (patch) | |
tree | 8c417f4ba814e9dbe70e56bdbf8a13cc46b3827f /src/gui/kernel/qopenglcontext.cpp | |
parent | 365b5f7a9271e5fc503b10e6c17371d76643fc94 (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.cpp | 71 |
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) |