summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2016-06-02 10:38:58 +0100
committerJani Heikkinen <jani.heikkinen@qt.io>2016-06-03 06:29:28 +0000
commit8bf76e51119aa49e745b078ceed3ffa67a89aea1 (patch)
tree43e9418ae41d111e5d2aa746681321823b460e11 /src
parent50dbac2d5960e8ec2a350c031f9ea4c3e3ac9822 (diff)
Mutex protect the RenderStateCollection
Without the mutex, this class will race when a framegraph contains multiple branches that result in renderview jobs being created. This is because one thread will call RenderStateCollection::renderStates() as part of building render commands. Then some time later (or at the same time) another thread could call this function too resulting in undefined behavior because the data changed by the first thread will not be pushed to the cpu cache of the second thread (or may be only partially updated) breaking the invariants of this class. Added a mutex to avoid the data race. In the future we should instead have the jobs maintain a local cache of such data so that we do not end up locking the QBackendNodes a lot in the jobs as this will kill parallelism just as QVariant does. Better to have the backend nodes as purely read only during job execution even if this means having an earlier job that populates an intermediate cache like we planned for the layer filtering (analogous to a relational databases temporary table concept). Task-number: QTBUG-53783 Change-Id: I33043dfd23d8b2e01369bdae25b933e3cfec78c8 Reviewed-by: Paul Lemire <paul.lemire@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/render/renderstates/renderstatecollection.cpp5
-rw-r--r--src/render/renderstates/renderstatecollection_p.h2
2 files changed, 7 insertions, 0 deletions
diff --git a/src/render/renderstates/renderstatecollection.cpp b/src/render/renderstates/renderstatecollection.cpp
index 17e794820..f9a7cb305 100644
--- a/src/render/renderstates/renderstatecollection.cpp
+++ b/src/render/renderstates/renderstatecollection.cpp
@@ -55,11 +55,13 @@ RenderStateCollection::~RenderStateCollection()
void RenderStateCollection::setDirty(bool dirty)
{
+ QMutexLocker lock(&m_mutex);
m_dirty = dirty;
}
QVector<RenderStateNode*> RenderStateCollection::renderStates(RenderStateManager *manager) const
{
+ QMutexLocker lock(&m_mutex);
if (m_dirty) {
m_renderStateNodes.clear();
@@ -79,11 +81,13 @@ QVector<RenderStateNode*> RenderStateCollection::renderStates(RenderStateManager
bool RenderStateCollection::hasRenderStates() const
{
+ QMutexLocker lock(&m_mutex);
return !m_renderStateIds.empty();
}
void RenderStateCollection::appendRenderState(Qt3DCore::QNodeId renderStateId)
{
+ QMutexLocker lock(&m_mutex);
if (!m_renderStateIds.contains(renderStateId)) {
m_renderStateIds.append(renderStateId);
m_dirty = true;
@@ -92,6 +96,7 @@ void RenderStateCollection::appendRenderState(Qt3DCore::QNodeId renderStateId)
void RenderStateCollection::removeRenderState(Qt3DCore::QNodeId renderStateId)
{
+ QMutexLocker lock(&m_mutex);
if (m_renderStateIds.removeAll(renderStateId) > 0) {
m_dirty = true;
}
diff --git a/src/render/renderstates/renderstatecollection_p.h b/src/render/renderstates/renderstatecollection_p.h
index b86f499fe..751d41250 100644
--- a/src/render/renderstates/renderstatecollection_p.h
+++ b/src/render/renderstates/renderstatecollection_p.h
@@ -49,6 +49,7 @@
//
#include <Qt3DRender/private/renderstatenode_p.h>
+#include <QtCore/qmutex.h>
QT_BEGIN_NAMESPACE
@@ -82,6 +83,7 @@ private:
mutable QVector<Qt3DCore::QNodeId> m_renderStateIds;
mutable QVector<RenderStateNode*> m_renderStateNodes;
mutable bool m_dirty;
+ mutable QMutex m_mutex;
};
} // namespace Render