diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2019-05-27 11:49:33 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2019-08-07 08:51:10 +0200 |
commit | 8daa8bcb8e9a7110289d15c94f53a4be9adac1ac (patch) | |
tree | 56330947d547e59efd9b08182a51589d82be5049 /src/core/aspects/qaspectengine.cpp | |
parent | fd64e870fad0e619704e79689f20645760dbdc0e (diff) |
Remove the Aspect Thread
This now makes the Qt3D simulation loop run in the Main Thread.
In theory having the Aspect Thread allowed Qt3D to continue rendering
even if the main thread got locked. In practice however this leads to
a large amount of complexities in the Qt3D implementations and provides
little value as in most cases blocking the main thread would block animations
driven by frontend nodes.
Removing the Aspect Thread will allow to remove the backend tree copies each
aspect had to make which will allow to reduce memory. In addition, getting direct
access to frontend nodes, will now be possible without introducing races which
should allow to make more optimizations and reduce latencies on some operations.
Change-Id: I80e4cd6427de06ddedfa1bb50d40710b91867b24
Reviewed-by: Mike Krus <mike.krus@kdab.com>
Diffstat (limited to 'src/core/aspects/qaspectengine.cpp')
-rw-r--r-- | src/core/aspects/qaspectengine.cpp | 45 |
1 files changed, 12 insertions, 33 deletions
diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp index 222c4c2af..2e7e51247 100644 --- a/src/core/aspects/qaspectengine.cpp +++ b/src/core/aspects/qaspectengine.cpp @@ -47,7 +47,6 @@ #include <QtCore/QMetaObject> #include <Qt3DCore/private/corelogging_p.h> -#include <Qt3DCore/private/qaspectthread_p.h> #include <Qt3DCore/private/qaspectmanager_p.h> #include <Qt3DCore/private/qchangearbiter_p.h> #include <Qt3DCore/private/qeventfilterservice_p.h> @@ -74,6 +73,7 @@ QAspectEnginePrivate *QAspectEnginePrivate::get(QAspectEngine *q) QAspectEnginePrivate::QAspectEnginePrivate() : QObjectPrivate() + , m_aspectManager(nullptr) , m_postman(nullptr) , m_scene(nullptr) , m_initialized(false) @@ -185,8 +185,7 @@ QAspectEngine::QAspectEngine(QObject *parent) d->m_scene = new QScene(this); d->m_postman = new QPostman(this); d->m_postman->setScene(d->m_scene); - d->m_aspectThread = new QAspectThread(this); - d->m_aspectThread->waitForStart(QThread::HighestPriority); + d->m_aspectManager = new QAspectManager(this); } /*! @@ -206,11 +205,6 @@ QAspectEngine::~QAspectEngine() for (auto aspect : aspects) unregisterAspect(aspect); - // Wait for thread to have completed it's final loop of execution - d->m_aspectThread->aspectManager()->quit(); - d->m_aspectThread->wait(); - - delete d->m_aspectThread; delete d->m_postman; delete d->m_scene; } @@ -225,15 +219,12 @@ void QAspectEnginePrivate::initNodeTree(QNode *node) void QAspectEnginePrivate::initialize() { - QChangeArbiter *arbiter = m_aspectThread->aspectManager()->changeArbiter(); + m_aspectManager->initialize(); + QChangeArbiter *arbiter = m_aspectManager->changeArbiter(); m_scene->setArbiter(arbiter); QChangeArbiter::createUnmanagedThreadLocalChangeQueue(arbiter); - QMetaObject::invokeMethod(arbiter, - "setPostman", - Q_ARG(Qt3DCore::QAbstractPostman*, m_postman)); - QMetaObject::invokeMethod(arbiter, - "setScene", - Q_ARG(Qt3DCore::QScene*, m_scene)); + arbiter->setPostman(m_postman); + arbiter->setScene(m_scene); m_initialized = true; #if QT_CONFIG(qt3d_profile_jobs) m_commandDebugger->setAspectEngine(q_func()); @@ -263,14 +254,14 @@ void QAspectEnginePrivate::shutdown() // Cleanup the scene before quitting the backend m_scene->setArbiter(nullptr); - QChangeArbiter *arbiter = m_aspectThread->aspectManager()->changeArbiter(); + QChangeArbiter *arbiter = m_aspectManager->changeArbiter(); QChangeArbiter::destroyUnmanagedThreadLocalChangeQueue(arbiter); m_initialized = false; } void QAspectEnginePrivate::exitSimulationLoop() { - m_aspectThread->aspectManager()->exitSimulationLoop(); + m_aspectManager->exitSimulationLoop(); } /*! @@ -285,12 +276,8 @@ void QAspectEngine::registerAspect(QAbstractAspect *aspect) // AspectManager::registerAspect is called in the context // of the AspectThread. This is turns call aspect->onInitialize // still in the same AspectThread context - aspect->moveToThread(d->m_aspectThread); d->m_aspects << aspect; - QMetaObject::invokeMethod(d->m_aspectThread->aspectManager(), - "registerAspect", - Qt::BlockingQueuedConnection, - Q_ARG(Qt3DCore::QAbstractAspect*, aspect)); + d->m_aspectManager->registerAspect(aspect); } /*! @@ -327,10 +314,7 @@ void QAspectEngine::unregisterAspect(QAbstractAspect *aspect) // Tell the aspect manager to give the aspect a chance to do some cleanup // in its QAbstractAspect::onUnregistered() virtual - QMetaObject::invokeMethod(d->m_aspectThread->aspectManager(), - "unregisterAspect", - Qt::BlockingQueuedConnection, - Q_ARG(Qt3DCore::QAbstractAspect*, aspect)); + d->m_aspectManager->unregisterAspect(aspect); // Remove from our collection of named aspects (if present) const auto it = std::find_if(d->m_namedAspects.begin(), d->m_namedAspects.end(), @@ -455,14 +439,9 @@ void QAspectEngine::setRootEntity(QEntityPtr root) // TODO: Pass the creation changes via the arbiter rather than relying upon // an invokeMethod call. qCDebug(Aspects) << "Begin setting scene root on aspect manager"; - QMetaObject::invokeMethod(d->m_aspectThread->aspectManager(), - "setRootEntity", - Qt::BlockingQueuedConnection, - Q_ARG(Qt3DCore::QEntity*, root.data()), - Q_ARG(QVector<Qt3DCore::QNodeCreatedChangeBasePtr>, d->m_creationChanges)); + d->m_aspectManager->setRootEntity(root.data(), d->m_creationChanges); qCDebug(Aspects) << "Done setting scene root on aspect manager"; - - d->m_aspectThread->aspectManager()->enterSimulationLoop(); + d->m_aspectManager->enterSimulationLoop(); } /*! |