diff options
author | Andy Nichols <andy.nichols@qt.io> | 2018-10-23 11:41:19 +0200 |
---|---|---|
committer | Fredrik Orderud <forderud@gmail.com> | 2018-10-30 12:49:53 +0000 |
commit | 1b9af84c1bb66770f607e157991375f7cb7ae0fb (patch) | |
tree | f81b146293cd1b55eb51fa38f21e16030f45cb80 | |
parent | 3b8075de3b3c842311c157476a85d2cf9ddff403 (diff) |
Don't create an offscreen surface when not on the GUI thread
When we try to gracefully destroy a QOpenGLVertexArrayObject it is not
possible to create an QOffscreenSurface from a thread that is not the
GUI thread. In this case we just need to bail out instead.
The side effect that was seen previously was that there would be a
warning and a deadlock on Windows when closing QQuickWindows that
contained a QQuickPaintedItem backed by a FrameBufferObject render
target (which would be using the OpenGL paint engine) when using the
threaded render loop.
Task-number: QTBUG-70148
Change-Id: I4a20d74d9af850bb90d243212ad9f65c3fc9e616
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r-- | src/gui/opengl/qopenglvertexarrayobject.cpp | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 0262538250..f0837aff96 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -40,8 +40,10 @@ #include "qopenglvertexarrayobject.h" #include <QtCore/private/qobject_p.h> +#include <QtCore/qthread.h> #include <QtGui/qopenglcontext.h> #include <QtGui/qoffscreensurface.h> +#include <QtGui/qguiapplication.h> #include <QtGui/qopenglfunctions_3_0.h> #include <QtGui/qopenglfunctions_3_2_core.h> @@ -204,18 +206,25 @@ void QOpenGLVertexArrayObjectPrivate::destroy() if (context && context != ctx) { oldContext = ctx; oldContextSurface = ctx ? ctx->surface() : 0; - // Cannot just make the current surface current again with another context. - // The format may be incompatible and some platforms (iOS) may impose - // restrictions on using a window with different contexts. Create an - // offscreen surface (a pbuffer or a hidden window) instead to be safe. - offscreenSurface.reset(new QOffscreenSurface); - offscreenSurface->setFormat(context->format()); - offscreenSurface->create(); - if (context->makeCurrent(offscreenSurface.data())) { - ctx = context; - } else { - qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current"); + // Before going through the effort of creating an offscreen surface + // check that we are on the GUI thread because otherwise many platforms + // will not able to create that offscreen surface. + if (QThread::currentThread() != qGuiApp->thread()) { ctx = 0; + } else { + // Cannot just make the current surface current again with another context. + // The format may be incompatible and some platforms (iOS) may impose + // restrictions on using a window with different contexts. Create an + // offscreen surface (a pbuffer or a hidden window) instead to be safe. + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(context->format()); + offscreenSurface->create(); + if (context->makeCurrent(offscreenSurface.data())) { + ctx = context; + } else { + qWarning("QOpenGLVertexArrayObject::destroy() failed to make VAO's context current"); + ctx = 0; + } } } @@ -224,7 +233,7 @@ void QOpenGLVertexArrayObjectPrivate::destroy() context = 0; } - if (vao) { + if (vao && ctx) { switch (vaoFuncsType) { #ifndef QT_OPENGL_ES_2 case Core_3_2: |