From 65ed4fa2ff95b54eacd82a7fb91f213464796756 Mon Sep 17 00:00:00 2001 From: Mike Krus Date: Tue, 10 Dec 2019 09:38:00 +0000 Subject: Use animation rather than event to drive simulation Using events can be problematic as they contribute to flooding of the event queue leading to issues with running animations. So we now use an actual animation which runs in a loop and triggers every 1ms (rendering still vsync locked though). If animation have not been enabled for the qt build, we fall back to using events as before. Tests were changes since frame progress is no longer driven by events, so processEvents does not trigger a frame update. Change-Id: I89b11862ef432dffae0c3dfb140eedd61754697e Reviewed-by: Paul Lemire --- src/core/aspects/qaspectmanager.cpp | 48 ++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'src/core/aspects/qaspectmanager.cpp') diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp index f24248399..74803349c 100644 --- a/src/core/aspects/qaspectmanager.cpp +++ b/src/core/aspects/qaspectmanager.cpp @@ -65,6 +65,7 @@ #include #include +#include #if defined(QT3D_CORE_JOB_TIMING) #include @@ -74,6 +75,23 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { +#if QT_CONFIG(animation) +class RequestFrameAnimation final : public QAbstractAnimation +{ +public: + RequestFrameAnimation(QObject *parent) + : QAbstractAnimation(parent) + { + } + + ~RequestFrameAnimation() override; + + int duration() const override { return 1; } + void updateCurrentTime(int currentTime) override { Q_UNUSED(currentTime) } +}; + +RequestFrameAnimation::~RequestFrameAnimation() = default; +#else namespace { class RequestFrameEvent : public QEvent @@ -92,7 +110,7 @@ private: int RequestFrameEvent::requestEventType = QEvent::registerEventType(); } // anonymous - +#endif /*! \class Qt3DCore::QAspectManager @@ -108,6 +126,9 @@ QAspectManager::QAspectManager(QObject *parent) , m_simulationLoopRunning(false) , m_driveMode(QAspectEngine::Automatic) , m_postConstructorInit(nullptr) +#if QT_CONFIG(animation) + , m_simulationAnimation(nullptr) +#endif { qRegisterMetaType("QSurface*"); qCDebug(Aspects) << Q_FUNC_INFO; @@ -149,8 +170,19 @@ void QAspectManager::enterSimulationLoop() qCDebug(Aspects) << "Done calling onEngineStartup() for each aspect"; // Start running loop if Qt3D is in charge of driving it - if (m_driveMode == QAspectEngine::Automatic) + if (m_driveMode == QAspectEngine::Automatic) { +#if QT_CONFIG(animation) + if (!m_simulationAnimation) { + m_simulationAnimation = new RequestFrameAnimation(this); + connect(m_simulationAnimation, &QAbstractAnimation::finished, this, [this]() { + processFrame(); + if (m_simulationLoopRunning && m_driveMode == QAspectEngine::Automatic) + requestNextFrame(); + }); + } +#endif requestNextFrame(); + } } // Main thread (called by QAspectEngine) @@ -164,6 +196,11 @@ void QAspectManager::exitSimulationLoop() return; } +#if QT_CONFIG(animation) + if (m_simulationAnimation) + m_simulationAnimation->stop(); +#endif + QAbstractFrameAdvanceService *frameAdvanceService = m_serviceLocator->service(QServiceLocator::FrameAdvanceService); if (frameAdvanceService) @@ -193,7 +230,6 @@ void QAspectManager::exitSimulationLoop() } qCDebug(Aspects) << "Done calling onEngineShutdown() for each aspect"; - m_simulationLoopRunning = false; qCDebug(Aspects) << "exitSimulationLoop completed"; } @@ -399,6 +435,7 @@ QVector QAspectManager::lookupNodes(const QVector &ids) const return d->m_scene ? d->m_scene->lookupNodes(ids) : QVector{}; } +#if !QT_CONFIG(animation) /*! \internal \brief Drives the Qt3D simulation loop in the main thread @@ -420,13 +457,18 @@ bool QAspectManager::event(QEvent *e) return QObject::event(e); } +#endif void QAspectManager::requestNextFrame() { qCDebug(Aspects) << "Requesting new Frame"; // Post event in the event loop to force // next frame to be processed +#if QT_CONFIG(animation) + m_simulationAnimation->start(); +#else QCoreApplication::postEvent(this, new RequestFrameEvent()); +#endif } void QAspectManager::processFrame() -- cgit v1.2.3