summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2018-03-22 16:06:00 +0100
committerPaul Lemire <paul.lemire@kdab.com>2018-03-23 09:43:39 +0000
commit2bf1f907e9e6ac87fc039d674eaca5179c5029f6 (patch)
tree94426d918d34849556e634eae8f561bc0da5effd
parent96d7e81706114084e850f0215351d85be0486b5c (diff)
Fix race in startup/shutdown
When the AspectEngine with a QRenderAspect (and RenderThread) is started and stopped within the same loop, there was a race in which Renderer::shutdown would possibly be called while Renderer::initialize wasn't complete. Apart from testing, such starting and stopping within the same loop is strongly discouraged as Qt3D doesn't have time to create an offscreen surface to properly release GL resources. Change-Id: Ie6f0a0698c213e3015bc9c51efc48d8706f20b3b Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/render/renderers/opengl/renderer/commandthread.cpp1
-rw-r--r--src/render/renderers/opengl/renderer/renderer.cpp8
-rw-r--r--src/render/renderers/opengl/renderer/renderer_p.h1
3 files changed, 10 insertions, 0 deletions
diff --git a/src/render/renderers/opengl/renderer/commandthread.cpp b/src/render/renderers/opengl/renderer/commandthread.cpp
index 387fc1113..fc654097c 100644
--- a/src/render/renderers/opengl/renderer/commandthread.cpp
+++ b/src/render/renderers/opengl/renderer/commandthread.cpp
@@ -69,6 +69,7 @@ CommandThread::CommandThread(Renderer *renderer)
CommandThread::~CommandThread()
{
+ Q_ASSERT(!isRunning());
}
void CommandThread::setShaderCache(ShaderCache *shaderCache)
diff --git a/src/render/renderers/opengl/renderer/renderer.cpp b/src/render/renderers/opengl/renderer/renderer.cpp
index 493e602f5..57b5b559c 100644
--- a/src/render/renderers/opengl/renderer/renderer.cpp
+++ b/src/render/renderers/opengl/renderer/renderer.cpp
@@ -163,6 +163,7 @@ Renderer::Renderer(QRenderAspect::RenderType type)
, m_commandThread(new CommandThread(this))
, m_vsyncFrameAdvanceService(new VSyncFrameAdvanceService(m_renderThread != nullptr))
, m_waitForInitializationToBeCompleted(0)
+ , m_hasBeenInitializedMutex()
, m_pickEventFilter(new PickEventFilter())
, m_exposed(0)
, m_lastFrameCorrect(0)
@@ -339,6 +340,7 @@ void Renderer::setOpenGLContext(QOpenGLContext *context)
// method termintates
void Renderer::initialize()
{
+ QMutexLocker lock(&m_hasBeenInitializedMutex);
m_submissionContext.reset(new SubmissionContext);
m_submissionContext->setRenderer(this);
@@ -420,6 +422,10 @@ void Renderer::initialize()
*/
void Renderer::shutdown()
{
+ // Ensure we have waited to be fully initialized before trying to shut down
+ // (in case initialization is taking place at the same time)
+ QMutexLocker lock(&m_hasBeenInitializedMutex);
+
qCDebug(Backend) << Q_FUNC_INFO << "Requesting renderer shutdown";
m_running.store(0);
@@ -466,6 +472,8 @@ void Renderer::releaseGraphicsResources()
QOffscreenSurface *offscreenSurface = m_offscreenHelper->offscreenSurface();
if (!offscreenSurface) {
qWarning() << "Failed to make context current: OpenGL resources will not be destroyed";
+ // We still need to delete the submission context
+ m_submissionContext.reset(nullptr);
return;
}
diff --git a/src/render/renderers/opengl/renderer/renderer_p.h b/src/render/renderers/opengl/renderer/renderer_p.h
index 923f4edc4..1d459a15e 100644
--- a/src/render/renderers/opengl/renderer/renderer_p.h
+++ b/src/render/renderers/opengl/renderer/renderer_p.h
@@ -314,6 +314,7 @@ private:
QSemaphore m_submitRenderViewsSemaphore;
QSemaphore m_waitForInitializationToBeCompleted;
+ QMutex m_hasBeenInitializedMutex;
QAtomicInt m_running;