QOpenGlContext: Always unset current context in doneCurrent()

Otherwise when no other context is made current until thread exit, the
QGuiGLThreadContext destructor will try to call doneCurrent() on an
already deleted context.

Pick-to: 6.8
Change-Id: If55dd69a72b8ab4012780a449f6a02729dd0ed43
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
(cherry picked from commit cd1686e55f706048286cbc962bbe02032c2396cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
David Redondo 2025-01-15 13:52:13 +01:00 committed by Qt Cherry-pick Bot
parent 7fbc340561
commit 10c195b864
2 changed files with 33 additions and 5 deletions

View File

@ -743,13 +743,13 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
void QOpenGLContext::doneCurrent()
{
Q_D(QOpenGLContext);
if (!isValid())
return;
if (QOpenGLContext::currentContext() == this)
d->shareGroup->d_func()->deletePendingResources(this);
if (isValid()) {
if (QOpenGLContext::currentContext() == this)
d->shareGroup->d_func()->deletePendingResources(this);
d->platformGLContext->doneCurrent();
}
d->platformGLContext->doneCurrent();
QOpenGLContextPrivate::setCurrentContext(nullptr);
d->surface = nullptr;

View File

@ -84,6 +84,9 @@ private slots:
void bufferCreate();
void bufferMapRange();
void defaultQGLCurrentBuffer();
#if QT_CONFIG(egl)
void dontCrashOnInvalidContextThreadTeardown();
#endif
};
struct SharedResourceTracker
@ -1751,6 +1754,31 @@ void tst_QOpenGL::clipRect()
//QCOMPARE(fb.pixelColor(clipRect.right(), clipRect.top() + 1), QColor(Qt::red));
}
#if QT_CONFIG(egl)
void tst_QOpenGL::dontCrashOnInvalidContextThreadTeardown()
{
class Thread : public QThread
{
void run() override
{
auto context = std::make_unique<QOpenGLContext>();
QVERIFY(context->create());
QScopedPointer<QSurface> surface(createSurface(int(QSurface::Window)));
QVERIFY(context->makeCurrent(surface.data()));
auto eglContext = context->nativeInterface<QNativeInterface::QEGLContext>();
if (!eglContext) {
QSKIP("Need an egl context for this test");
}
eglContext->invalidateContext();
context->doneCurrent();
}
};
Thread thread;
thread.start();
thread.wait();
}
#endif
QTEST_MAIN(tst_QOpenGL)
#include "tst_qopengl.moc"