summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2019-03-27 13:07:28 +0200
committerTomi Korpipää <tomi.korpipaa@qt.io>2019-03-28 04:17:15 +0000
commitfbb0642d7da044d3f61382e6e2d74e1529dc81e6 (patch)
treec1826e38741a4fd539eb543dbfb83c8933c4b68a
parent92079605819c10de4d950ed4a5254da8546b140a (diff)
Fix async loading
Protect some shared resources with mutexes. Task-number: QT3DS-3226 Change-Id: I270457f9df336592227b343e0e3c39dab9965410 Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/runtime/q3dsengine.cpp45
-rw-r--r--src/runtime/q3dsengine_p.h3
-rw-r--r--src/runtime/shadergenerator/q3dsshadermanager.cpp2
-rw-r--r--src/runtime/shadergenerator/q3dsshadermanager_p.h2
4 files changed, 40 insertions, 12 deletions
diff --git a/src/runtime/q3dsengine.cpp b/src/runtime/q3dsengine.cpp
index 329a214..ef72f00 100644
--- a/src/runtime/q3dsengine.cpp
+++ b/src/runtime/q3dsengine.cpp
@@ -903,12 +903,18 @@ void Q3DSEngine::beginAsyncLoad(Q3DSSubPresentation &sp, SceneLoaderAsync *loade
qCDebug(lcScene, "Subpresentation %s loaded in %lld ms",
qPrintable(loader->pres->subPres.id), timer.elapsed());
});
+ QMutexLocker locker(&m_asyncLoadLock);
m_asyncSceneLoaders.push_back(loader);
}
void Q3DSEngine::finishAsyncLoadForSubpresentation(const QString &name)
{
- for (auto &item : qAsConst(m_asyncSceneLoaders)) {
+ QVector<SceneLoaderAsync *> loaders;
+ {
+ QMutexLocker locker(&m_asyncLoadLock);
+ loaders = m_asyncSceneLoaders;
+ }
+ for (auto &item : qAsConst(loaders)) {
if (item->done == false && item->pres->subPres.id == name) {
item->future.waitForFinished();
item->done = true;
@@ -920,25 +926,35 @@ void Q3DSEngine::finishAsyncLoadForSubpresentation(const QString &name)
void Q3DSEngine::finishAsyncLoad(bool wait)
{
+ QThread *currentThread = QThread::currentThread();
+ QVector<SceneLoaderAsync *> loaders;
+ {
+ QMutexLocker locker(&m_asyncLoadLock);
+ loaders = m_asyncSceneLoaders;
+ }
if (wait) {
- QElapsedTimer timer;
- timer.start();
{
QFutureSynchronizer<void> sync;
- for (auto &item : qAsConst(m_asyncSceneLoaders)) {
+ for (auto &item : qAsConst(loaders)) {
if (item->done == false)
sync.addFuture(item->future);
}
}
- for (auto &item : qAsConst(m_asyncSceneLoaders)) {
- item->done = true;
- item->function();
+ for (auto &item : qAsConst(loaders)) {
+ // Finalize only in target thread to make reparenting events succeed
+ if (item->targetThread == currentThread) {
+ item->done = true;
+ item->function();
+ }
}
} else {
- for (auto &item : qAsConst(m_asyncSceneLoaders)) {
+ for (auto &item : qAsConst(loaders)) {
if (!item->done && item->future.isFinished()) {
- item->done = true;
- item->function();
+ // Finalize only in target thread to make reparenting events succeed
+ if (item->targetThread == currentThread) {
+ item->done = true;
+ item->function();
+ }
}
}
}
@@ -946,8 +962,13 @@ void Q3DSEngine::finishAsyncLoad(bool wait)
void Q3DSEngine::loadSlideResources(Q3DSSlide *slide, Q3DSUipPresentation *presentation)
{
- m_resourceReferenceCounter.handleLoadSlide(slide, presentation);
- Q3DSImageManager::instance().beginImageLoad(m_resourceReferenceCounter.createSet);
+ QSet<QUrl> createSet;
+ {
+ QMutexLocker locker(&m_slideResourceMutex);
+ m_resourceReferenceCounter.handleLoadSlide(slide, presentation);
+ createSet = m_resourceReferenceCounter.createSet;
+ }
+ Q3DSImageManager::instance().beginImageLoad(createSet);
}
void Q3DSEngine::unloadSlideResources(Q3DSSlide *slide, Q3DSUipPresentation *presentation)
diff --git a/src/runtime/q3dsengine_p.h b/src/runtime/q3dsengine_p.h
index f72191e..ae76bb4 100644
--- a/src/runtime/q3dsengine_p.h
+++ b/src/runtime/q3dsengine_p.h
@@ -42,6 +42,7 @@
//
#include <QObject>
+#include <QThread>
#include <QElapsedTimer>
#include <QSurfaceFormat>
#include <Qt3DCore/QAspectEngine>
@@ -471,6 +472,8 @@ private:
QVector<SceneLoaderAsync *> m_asyncSceneLoaders;
SlideResourceCounter m_resourceReferenceCounter;
+ QMutex m_slideResourceMutex;
+ QMutex m_asyncLoadLock;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Q3DSEngine::Flags)
diff --git a/src/runtime/shadergenerator/q3dsshadermanager.cpp b/src/runtime/shadergenerator/q3dsshadermanager.cpp
index b0ca6ce..a9bfcee 100644
--- a/src/runtime/shadergenerator/q3dsshadermanager.cpp
+++ b/src/runtime/shadergenerator/q3dsshadermanager.cpp
@@ -56,6 +56,7 @@ Qt3DRender::QShaderProgram *Q3DSShaderManager::generateShaderProgram(Q3DSDefault
bool hasTransparency,
const Q3DSShaderFeatureSet &featureSet)
{
+ QMutexLocker locker(&m_generatorMutex);
Q3DSSubsetMaterialVertexPipeline pipeline(*m_materialShaderGenerator, *m_shaderProgramGenerator, false);
return m_materialShaderGenerator->generateShader(material, referencedMaterial, pipeline, featureSet, lights, hasTransparency,
QString(QLatin1String("default material %1")).arg(QString::fromLatin1(material.id())));
@@ -68,6 +69,7 @@ Qt3DRender::QShaderProgram *Q3DSShaderManager::generateShaderProgram(Q3DSCustomM
const Q3DSShaderFeatureSet &featureSet,
const QString &shaderName)
{
+ QMutexLocker locker(&m_generatorMutex);
Q3DSCustomMaterialVertexPipeline pipeline(*m_materialShaderGenerator, *m_shaderProgramGenerator, false);
return m_customMaterialShaderGenerator->generateShader(material, referencedMaterial, pipeline, featureSet, lights, hasTransparency, shaderName);
}
diff --git a/src/runtime/shadergenerator/q3dsshadermanager_p.h b/src/runtime/shadergenerator/q3dsshadermanager_p.h
index e38ae69..cd7baaa 100644
--- a/src/runtime/shadergenerator/q3dsshadermanager_p.h
+++ b/src/runtime/shadergenerator/q3dsshadermanager_p.h
@@ -47,6 +47,7 @@
#include "q3dsuippresentation_p.h"
#include <Qt3DRender/QShaderProgram>
#include <QMap>
+#include <QMutex>
QT_BEGIN_NAMESPACE
@@ -121,6 +122,7 @@ private:
QMap<int, Qt3DRender::QShaderProgram *> m_blendOverlayShader;
QMap<int, Qt3DRender::QShaderProgram *> m_blendColorBurnShader;
QMap<int, Qt3DRender::QShaderProgram *> m_blendColorDodgeShader;
+ QMutex m_generatorMutex;
};
QT_END_NAMESPACE