Unset qgl_current_fbo when the default FBO is bound

Previously when a new QOpenGLFramebufferObject was bound, the
QOpenGLContextPrivate::qgl_current_fbo member was also updated to point
to this new object.
But if a user called QOpenGLFramebufferObject::bindDefault(),
qgl_current_fbo was not unset, meaning that if the FBO object would be
deleted at some point, qgl_current_fbo would be a dangling pointer.

This patch makes sure to clear the value of qgl_current_fbo when
bindDefault() is called. It is cleared, and not set to point to another
object because the default platform OpenGL FBO is not backed by a
QOpenGLFramebufferObject.

Task-number: QTBUG-56296
Change-Id: I68b53d8b446660accdf5841df3d168ee2f133a90
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Alexandru Croitor 2016-09-30 18:36:15 +02:00
parent 51767affb3
commit cd1d114140
2 changed files with 29 additions and 0 deletions

View File

@ -1490,6 +1490,7 @@ bool QOpenGLFramebufferObject::bindDefault()
if (ctx) {
ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject());
QOpenGLContextPrivate::get(ctx)->qgl_current_fbo_invalid = true;
QOpenGLContextPrivate::get(ctx)->qgl_current_fbo = Q_NULLPTR;
}
#ifdef QT_DEBUG
else

View File

@ -114,6 +114,7 @@ private slots:
void vaoCreate();
void bufferCreate();
void bufferMapRange();
void defaultQGLCurrentBuffer();
};
struct SharedResourceTracker
@ -1525,6 +1526,33 @@ void tst_QOpenGL::bufferMapRange()
ctx->doneCurrent();
}
void tst_QOpenGL::defaultQGLCurrentBuffer()
{
QScopedPointer<QSurface> surface(createSurface(QSurface::Window));
QScopedPointer<QOpenGLContext> ctx(new QOpenGLContext);
ctx->create();
ctx->makeCurrent(surface.data());
// Bind default FBO on the current context, and record what's the current QGL FBO. It should
// be Q_NULLPTR because the default platform OpenGL FBO is not backed by a
// QOpenGLFramebufferObject.
QOpenGLFramebufferObject::bindDefault();
QOpenGLFramebufferObject *defaultQFBO = QOpenGLContextPrivate::get(ctx.data())->qgl_current_fbo;
// Create new FBO, bind it, and see that the QGL FBO points to the newly created FBO.
QScopedPointer<QOpenGLFramebufferObject> obj(new QOpenGLFramebufferObject(128, 128));
obj->bind();
QOpenGLFramebufferObject *customQFBO = QOpenGLContextPrivate::get(ctx.data())->qgl_current_fbo;
QVERIFY(defaultQFBO != customQFBO);
// Bind the default FBO, and check that the QGL FBO points to the original FBO object.
QOpenGLFramebufferObject::bindDefault();
QOpenGLFramebufferObject *finalQFBO = QOpenGLContextPrivate::get(ctx.data())->qgl_current_fbo;
QCOMPARE(defaultQFBO, finalQFBO);
ctx->doneCurrent();
}
void tst_QOpenGL::nullTextureInitializtion()
{
QScopedPointer<QSurface> surface(createSurface(QSurface::Window));