diff options
Diffstat (limited to 'src/core/aspects/qaspectmanager.cpp')
-rw-r--r-- | src/core/aspects/qaspectmanager.cpp | 106 |
1 files changed, 52 insertions, 54 deletions
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp index 71e05b34f..f276d633e 100644 --- a/src/core/aspects/qaspectmanager.cpp +++ b/src/core/aspects/qaspectmanager.cpp @@ -57,6 +57,7 @@ #include <Qt3DCore/private/qchangearbiter_p.h> #include <Qt3DCore/private/qscheduler_p.h> #include <Qt3DCore/private/qservicelocator_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p_p.h> #include <Qt3DCore/private/qthreadpooler_p.h> #include <Qt3DCore/private/qtickclock_p.h> #include <Qt3DCore/private/qtickclockservice_p.h> @@ -98,15 +99,18 @@ int RequestFrameEvent::requestEventType = QEvent::registerEventType(); \class Qt3DCore::QAspectManager \internal */ -QAspectManager::QAspectManager(QObject *parent) +QAspectManager::QAspectManager(QAspectEngine *parent) : QObject(parent) + , m_engine(parent) , m_root(nullptr) , m_scheduler(new QScheduler(this)) , m_jobManager(new QAspectJobManager(this)) , m_changeArbiter(new QChangeArbiter(this)) - , m_serviceLocator(new QServiceLocator()) + , m_serviceLocator(new QServiceLocator(parent)) , m_simulationLoopRunning(false) , m_driveMode(QAspectEngine::Automatic) + , m_postConstructorInit(nullptr) + , m_jobsInLastFrame(0) { qRegisterMetaType<QSurface *>("QSurface*"); qCDebug(Aspects) << Q_FUNC_INFO; @@ -413,6 +417,8 @@ bool QAspectManager::event(QEvent *e) // the loop if (m_simulationLoopRunning && m_driveMode == QAspectEngine::Automatic) requestNextFrame(); + + return true; } return QObject::event(e); @@ -423,7 +429,7 @@ void QAspectManager::requestNextFrame() qCDebug(Aspects) << "Requesting new Frame"; // Post event in the event loop to force // next frame to be processed - qApp->postEvent(this, new RequestFrameEvent()); + QCoreApplication::postEvent(this, new RequestFrameEvent()); } void QAspectManager::processFrame() @@ -435,6 +441,8 @@ void QAspectManager::processFrame() m_serviceLocator->service<QAbstractFrameAdvanceService>(QServiceLocator::FrameAdvanceService); const qint64 t = frameAdvanceService->waitForNextFrame(); + if (t < 0) + return; // Distribute accumulated changes. This includes changes sent from the frontend // to the backend nodes. We call this before the call to m_scheduler->update() to ensure @@ -444,57 +452,49 @@ void QAspectManager::processFrame() // // Doing this as the first call in the new frame ensures the lock free approach works // without any such data race. -#if QT_CONFIG(qt3d_profile_jobs) - const quint32 arbiterId = 4096; - JobRunStats changeArbiterStats; - changeArbiterStats.jobId.typeAndInstance[0] = arbiterId; - changeArbiterStats.jobId.typeAndInstance[1] = 0; - changeArbiterStats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId()); - changeArbiterStats.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed(); -#endif - - // Tell the NodePostConstructorInit to process any pending nodes which will add them to our list of - // tree changes - m_postConstructorInit->processNodes(); - - // Add and Remove Nodes - const QVector<NodeTreeChange> nodeTreeChanges = std::move(m_nodeTreeChanges); - for (const NodeTreeChange &change : nodeTreeChanges) { - // Buckets ensure that even if we have intermingled node added / removed - // buckets, we preserve the order of the sequences - - for (QAbstractAspect *aspect : qAsConst(m_aspects)) { - switch (change.type) { - case NodeTreeChange::Added: - aspect->d_func()->createBackendNode(change); - break; - case NodeTreeChange::Removed: - aspect->d_func()->clearBackendNode(change); - break; + { + // scope for QTaskLogger + QTaskLogger logger(m_serviceLocator->systemInformation(), 4096, 0); + + // Tell the NodePostConstructorInit to process any pending nodes which will add them to our list of + // tree changes + m_postConstructorInit->processNodes(); + + // Add and Remove Nodes + const QVector<NodeTreeChange> nodeTreeChanges = std::move(m_nodeTreeChanges); + for (const NodeTreeChange &change : nodeTreeChanges) { + // Buckets ensure that even if we have intermingled node added / removed + // buckets, we preserve the order of the sequences + + for (QAbstractAspect *aspect : qAsConst(m_aspects)) { + switch (change.type) { + case NodeTreeChange::Added: + aspect->d_func()->createBackendNode(change); + break; + case NodeTreeChange::Removed: + aspect->d_func()->clearBackendNode(change); + break; + } } } - } - - // Sync node / subnode relationship changes - const auto dirtySubNodes = m_changeArbiter->takeDirtyFrontEndSubNodes(); - if (dirtySubNodes.size()) - for (QAbstractAspect *aspect : qAsConst(m_aspects)) - aspect->syncDirtyFrontEndSubNodes(dirtySubNodes); - // Sync property updates - const auto dirtyFrontEndNodes = m_changeArbiter->takeDirtyFrontEndNodes(); - if (dirtyFrontEndNodes.size()) - for (QAbstractAspect *aspect : qAsConst(m_aspects)) - aspect->syncDirtyFrontEndNodes(dirtyFrontEndNodes); - - // TO DO: Having this done in the main thread actually means aspects could just - // as simply read info out of the Frontend classes without risk of introducing - // races. This could therefore be removed for Qt 6. - m_changeArbiter->syncChanges(); -#if QT_CONFIG(qt3d_profile_jobs) - changeArbiterStats.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed(); - QThreadPooler::addJobLogStatsEntry(changeArbiterStats); -#endif + // Sync node / subnode relationship changes + const auto dirtySubNodes = m_changeArbiter->takeDirtyFrontEndSubNodes(); + if (dirtySubNodes.size()) + for (QAbstractAspect *aspect : qAsConst(m_aspects)) + QAbstractAspectPrivate::get(aspect)->syncDirtyFrontEndSubNodes(dirtySubNodes); + + // Sync property updates + const auto dirtyFrontEndNodes = m_changeArbiter->takeDirtyFrontEndNodes(); + if (dirtyFrontEndNodes.size()) + for (QAbstractAspect *aspect : qAsConst(m_aspects)) + QAbstractAspectPrivate::get(aspect)->syncDirtyFrontEndNodes(dirtyFrontEndNodes); + + // TO DO: Having this done in the main thread actually means aspects could just + // as simply read info out of the Frontend classes without risk of introducing + // races. This could therefore be removed for Qt 6. + m_changeArbiter->syncChanges(); + } // For each Aspect // Ask them to launch set of jobs for the current frame @@ -503,12 +503,10 @@ void QAspectManager::processFrame() QElapsedTimer timer; timer.start(); #endif - m_scheduler->scheduleAndWaitForFrameAspectJobs(t); + m_jobsInLastFrame = m_scheduler->scheduleAndWaitForFrameAspectJobs(t); #if defined(QT3D_CORE_JOB_TIMING) qDebug() << "Jobs took" << timer.nsecsElapsed() / 1.0e6; #endif - - // TODO sync backend changes to frontend } } // namespace Qt3DCore |