From d6661ca409ebf1e4a2fa21fa4f084f63f70052e3 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs <laszlo.agocs@digia.com> Date: Mon, 20 Oct 2014 13:46:13 +0200 Subject: [PATCH] Fix failing makeCurrent in basic renderloop when closing windows The makeCurrent() call can fail if there is no underlying platform window present anymore (due to close()). Just continuing with the cleanup is wrong: There may be another context current (from the application or from some other component of Qt) and there are GL calls issued which would mess up the state in that context. Therefore we ensure there's a context/surface by using a temporary QOffscreenSurface. Task-number: QTBUG-41942 Change-Id: I79f35a1f5bbe7a8a14943e8603764575ed119f93 Reviewed-by: Gunnar Sletta <gunnar@sletta.org> --- src/quick/scenegraph/qsgrenderloop.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index cd92d12d43..f2586b1e40 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -41,6 +41,7 @@ #include <QtCore/private/qabstractanimation_p.h> #include <QtGui/QOpenGLContext> +#include <QtGui/QOffscreenSurface> #include <QtGui/private/qguiapplication_p.h> #include <qpa/qplatformintegration.h> @@ -274,15 +275,30 @@ void QSGGuiThreadRenderLoop::windowDestroyed(QQuickWindow *window) m_windows.remove(window); hide(window); QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); - if (gl) - gl->makeCurrent(window); + + bool current = false; + QScopedPointer<QOffscreenSurface> offscreenSurface; + if (gl) { + QSurface *surface = window; + // There may be no platform window if the window got closed. + if (!window->handle()) { + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(gl->format()); + offscreenSurface->create(); + surface = offscreenSurface.data(); + } + current = gl->makeCurrent(surface); + } + if (Q_UNLIKELY(!current)) + qCDebug(QSG_LOG_RENDERLOOP) << "cleanup without an OpenGL context"; + d->cleanupNodesOnShutdown(); if (m_windows.size() == 0) { rc->invalidate(); QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete gl; gl = 0; - } else if (gl && window == gl->surface()) { + } else if (gl && window == gl->surface() && current) { gl->doneCurrent(); } } -- GitLab