From: Laszlo Agocs Date: Mon, 20 Oct 2014 11:46:13 +0000 (+0200) Subject: Fix failing makeCurrent in basic renderloop when closing windows X-Git-Tag: v5.4.0~75 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d6661ca409ebf1e4a2fa21fa4f084f63f70052e3;p=platform%2Fupstream%2Fqtdeclarative.git 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 --- diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index cd92d12..f2586b1 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -41,6 +41,7 @@ #include #include +#include #include #include @@ -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 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(); } }