summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2017-01-03 09:05:43 +0100
committerJani Heikkinen <jani.heikkinen@qt.io>2017-01-03 12:49:45 +0000
commitcf1f4f00f5fb3868a44727f0b214e8e6ece47e2c (patch)
tree2d4e27e0cacd8963fd97ee5f52718752d0f7668e
parent8730660d83dfa5c4d83a5b86b1892029bda14216 (diff)
BufferManager: prevent race on buffersToRelease vector
Dirty buffers to release are added in the QAspectThread::syncChanges but we may be rendering/cleaning up resources at the same time in the render thread. Now protecting any call that could modify the buffers with a mutex. Task-number: QTBUG-57655 Change-Id: If98702b901bab0e092c039d4da2f0c3f3cdca7cc Reviewed-by: Kevin Ottens <kevin.ottens@kdab.com>
-rw-r--r--src/render/backend/renderer.cpp2
-rw-r--r--src/render/geometry/buffermanager.cpp9
-rw-r--r--src/render/geometry/buffermanager_p.h3
3 files changed, 10 insertions, 4 deletions
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
index e4ad7d181..59c1c05eb 100644
--- a/src/render/backend/renderer.cpp
+++ b/src/render/backend/renderer.cpp
@@ -1472,7 +1472,7 @@ bool Renderer::requiresVAOAttributeUpdate(Geometry *geometry,
void Renderer::cleanGraphicsResources()
{
// Clean buffers
- const QVector<Qt3DCore::QNodeId> buffersToRelease = std::move(m_nodesManager->bufferManager()->buffersToRelease());
+ const QVector<Qt3DCore::QNodeId> buffersToRelease = m_nodesManager->bufferManager()->takeBuffersToRelease();
for (Qt3DCore::QNodeId bufferId : buffersToRelease)
m_graphicsContext->releaseBuffer(bufferId);
diff --git a/src/render/geometry/buffermanager.cpp b/src/render/geometry/buffermanager.cpp
index 09d9cfd50..78c2c0082 100644
--- a/src/render/geometry/buffermanager.cpp
+++ b/src/render/geometry/buffermanager.cpp
@@ -65,14 +65,19 @@ QVector<Qt3DCore::QNodeId> BufferManager::dirtyBuffers()
return vector;
}
+// Called in QAspectThread::syncChanges
void BufferManager::addBufferToRelease(Qt3DCore::QNodeId bufferId)
{
+ QMutexLocker lock(&m_mutex);
m_buffersToRelease.push_back(bufferId);
}
-QVector<Qt3DCore::QNodeId> &BufferManager::buffersToRelease()
+// Called in Render thread
+QVector<Qt3DCore::QNodeId> BufferManager::takeBuffersToRelease()
{
- return m_buffersToRelease;
+ QMutexLocker lock(&m_mutex);
+ // Clears the m_buffersToRelease vector
+ return std::move(m_buffersToRelease);
}
} // namespace Render
diff --git a/src/render/geometry/buffermanager_p.h b/src/render/geometry/buffermanager_p.h
index 754d65fe6..6862cd973 100644
--- a/src/render/geometry/buffermanager_p.h
+++ b/src/render/geometry/buffermanager_p.h
@@ -78,11 +78,12 @@ public:
// Aspect Thread
void addBufferToRelease(Qt3DCore::QNodeId bufferId);
// Render Thread (no concurrent access)
- QVector<Qt3DCore::QNodeId> &buffersToRelease();
+ QVector<Qt3DCore::QNodeId> takeBuffersToRelease();
private:
QVector<Qt3DCore::QNodeId> m_dirtyBuffers;
QVector<Qt3DCore::QNodeId> m_buffersToRelease;
+ QMutex m_mutex;
};
} // namespace Render