summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMäättä Antti <antti.maatta@qt.io>2018-02-05 16:36:44 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2018-02-08 07:24:45 +0000
commit156afc0f9dad1c16ee9a0ed31307121941443491 (patch)
treed2a989470d7a7b3a4dc201e5410dbe4971614c27
parentb923dae74e9baf75aae99f87b19568ec1dc39f82 (diff)
Fix crash if sharecontext is requested before initailization
Scene2D can sometimes receive the render initialization event before the qt3d renderer has been initialized. This causes crash because the sharecontext hasn't been set yet. Add safeguard against this. Task-number: QT3DS-904 Change-Id: Ib50a60ed89c12ac54c9165266466d9804affe77c Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: Paul Lemire <paul.lemire@kdab.com> Reviewed-by: Sean Harmer <sean.harmer@kdab.com> (cherry picked from commit 13f340c92bdf725d214ab4840fc2e071d12d6e00) Reviewed-by: Antti Määttä <antti.maatta@qt.io>
-rw-r--r--src/render/backend/renderer.cpp75
-rw-r--r--src/render/backend/renderer_p.h1
2 files changed, 42 insertions, 34 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index b5b387cc5..6217338eb 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -307,7 +307,11 @@ NodeManagers *Renderer::nodeManagers() const
*/
QOpenGLContext *Renderer::shareContext() const
{
- return m_shareContext ? m_shareContext : m_graphicsContext->openGLContext()->shareContext();
+ QMutexLocker lock(&m_shareContextMutex);
+ return m_shareContext ? m_shareContext
+ : (m_graphicsContext->openGLContext()
+ ? m_graphicsContext->openGLContext()->shareContext()
+ : nullptr);
}
void Renderer::setOpenGLContext(QOpenGLContext *context)
@@ -325,45 +329,48 @@ void Renderer::initialize()
QOpenGLContext* ctx = m_glContext;
- // If we are using our own context (not provided by QtQuick),
- // we need to create it
- if (!m_glContext) {
- ctx = new QOpenGLContext;
- ctx->setShareContext(qt_gl_global_share_context());
-
- // TO DO: Shouldn't we use the highest context available and trust
- // QOpenGLContext to fall back on the best lowest supported ?
- const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING");
+ {
+ QMutexLocker lock(&m_shareContextMutex);
+ // If we are using our own context (not provided by QtQuick),
+ // we need to create it
+ if (!m_glContext) {
+ ctx = new QOpenGLContext;
+ ctx->setShareContext(qt_gl_global_share_context());
+
+ // TO DO: Shouldn't we use the highest context available and trust
+ // QOpenGLContext to fall back on the best lowest supported ?
+ const QByteArray debugLoggingMode = qgetenv("QT3DRENDER_DEBUG_LOGGING");
+
+ if (!debugLoggingMode.isEmpty()) {
+ QSurfaceFormat sf = ctx->format();
+ sf.setOption(QSurfaceFormat::DebugContext);
+ ctx->setFormat(sf);
+ }
- if (!debugLoggingMode.isEmpty()) {
- QSurfaceFormat sf = ctx->format();
- sf.setOption(QSurfaceFormat::DebugContext);
- ctx->setFormat(sf);
+ // Create OpenGL context
+ if (ctx->create())
+ qCDebug(Backend) << "OpenGL context created with actual format" << ctx->format();
+ else
+ qCWarning(Backend) << Q_FUNC_INFO << "OpenGL context creation failed";
+ m_ownedContext = true;
+ } else {
+ // Context is not owned by us, so we need to know if it gets destroyed
+ m_contextConnection = QObject::connect(m_glContext, &QOpenGLContext::aboutToBeDestroyed,
+ [this] { releaseGraphicsResources(); });
}
- // Create OpenGL context
- if (ctx->create())
- qCDebug(Backend) << "OpenGL context created with actual format" << ctx->format();
- else
- qCWarning(Backend) << Q_FUNC_INFO << "OpenGL context creation failed";
- m_ownedContext = true;
- } else {
- // Context is not owned by us, so we need to know if it gets destroyed
- m_contextConnection = QObject::connect(m_glContext, &QOpenGLContext::aboutToBeDestroyed,
- [this] { releaseGraphicsResources(); });
- }
+ if (!ctx->shareContext()) {
+ m_shareContext = new QOpenGLContext;
+ m_shareContext->setFormat(ctx->format());
+ m_shareContext->setShareContext(ctx);
+ m_shareContext->create();
+ }
- if (!ctx->shareContext()) {
- m_shareContext = new QOpenGLContext;
- m_shareContext->setFormat(ctx->format());
- m_shareContext->setShareContext(ctx);
- m_shareContext->create();
+ // Note: we don't have a surface at this point
+ // The context will be made current later on (at render time)
+ m_graphicsContext->setOpenGLContext(ctx);
}
- // Note: we don't have a surface at this point
- // The context will be made current later on (at render time)
- m_graphicsContext->setOpenGLContext(ctx);
-
// Store the format used by the context and queue up creating an
// offscreen surface in the main thread so that it is available
// for use when we want to shutdown the renderer. We need to create
diff --git a/src/render/backend/renderer_p.h b/src/render/backend/renderer_p.h
index 987576059..cbc686ab1 100644
--- a/src/render/backend/renderer_p.h
+++ b/src/render/backend/renderer_p.h
@@ -319,6 +319,7 @@ private:
QAtomicInt m_lastFrameCorrect;
QOpenGLContext *m_glContext;
QOpenGLContext *m_shareContext;
+ mutable QMutex m_shareContextMutex;
PickBoundingVolumeJobPtr m_pickBoundingVolumeJob;
qint64 m_time;