summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/aspects/aspects.pri6
-rw-r--r--src/core/aspects/qaspectengine.cpp45
-rw-r--r--src/core/aspects/qaspectengine_p.h4
-rw-r--r--src/core/aspects/qaspectmanager.cpp265
-rw-r--r--src/core/aspects/qaspectmanager_p.h16
-rw-r--r--src/core/aspects/qaspectthread.cpp99
-rw-r--r--src/core/aspects/qaspectthread_p.h88
-rw-r--r--src/core/qchangearbiter_p.h4
-rw-r--r--src/core/services/qdownloadhelperservice.cpp4
-rw-r--r--src/input/backend/eventsourcesetterhelper.cpp25
-rw-r--r--src/input/backend/eventsourcesetterhelper_p.h6
-rw-r--r--src/input/backend/inputhandler.cpp20
-rw-r--r--src/input/backend/mousedevice.cpp1
-rw-r--r--src/logic/executor.cpp6
-rw-r--r--src/logic/executor_p.h2
-rw-r--r--src/logic/manager.cpp6
-rw-r--r--src/logic/manager_p.h1
-rw-r--r--tests/benchmarks/render/jobs/tst_bench_jobs.cpp1
18 files changed, 177 insertions, 422 deletions
diff --git a/src/core/aspects/aspects.pri b/src/core/aspects/aspects.pri
index ced33f310..5e8327192 100644
--- a/src/core/aspects/aspects.pri
+++ b/src/core/aspects/aspects.pri
@@ -4,8 +4,7 @@ SOURCES += \
$$PWD/qabstractaspect.cpp \
$$PWD/qaspectengine.cpp \
$$PWD/qaspectfactory.cpp \
- $$PWD/qaspectmanager.cpp \
- $$PWD/qaspectthread.cpp
+ $$PWD/qaspectmanager.cpp
HEADERS += \
$$PWD/qabstractaspect.h \
@@ -13,8 +12,7 @@ HEADERS += \
$$PWD/qabstractaspect_p.h \
$$PWD/qaspectengine_p.h \
$$PWD/qaspectfactory_p.h \
- $$PWD/qaspectmanager_p.h \
- $$PWD/qaspectthread_p.h
+ $$PWD/qaspectmanager_p.h
INCLUDEPATH += $$PWD
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();
}
/*!
diff --git a/src/core/aspects/qaspectengine_p.h b/src/core/aspects/qaspectengine_p.h
index 2d7d0fe93..9c042b5a5 100644
--- a/src/core/aspects/qaspectengine_p.h
+++ b/src/core/aspects/qaspectengine_p.h
@@ -65,7 +65,7 @@ namespace Qt3DCore {
class QEntity;
class QNode;
class QAspectEngine;
-class QAspectThread;
+class QAspectManager;
class QPostman;
class QScene;
@@ -84,7 +84,7 @@ public:
Q_DECLARE_PUBLIC(QAspectEngine)
QAspectFactory m_factory;
- QAspectThread *m_aspectThread;
+ QAspectManager *m_aspectManager;
QPostman *m_postman;
QScene *m_scene;
QSharedPointer<QEntity> m_root;
diff --git a/src/core/aspects/qaspectmanager.cpp b/src/core/aspects/qaspectmanager.cpp
index e9642116a..a028e38cb 100644
--- a/src/core/aspects/qaspectmanager.cpp
+++ b/src/core/aspects/qaspectmanager.cpp
@@ -61,6 +61,8 @@
#include <Qt3DCore/private/qtickclock_p.h>
#include <Qt3DCore/private/qtickclockservice_p.h>
+#include <QtCore/QCoreApplication>
+
#if defined(QT3D_CORE_JOB_TIMING)
#include <QElapsedTimer>
#endif
@@ -69,6 +71,26 @@ QT_BEGIN_NAMESPACE
namespace Qt3DCore {
+namespace {
+
+class RequestFrameEvent : public QEvent
+{
+public:
+ RequestFrameEvent()
+ : QEvent(static_cast<QEvent::Type>(RequestFrameEvent::requestEventType))
+ {}
+
+ static int eventType() { return RequestFrameEvent::requestEventType; }
+
+private:
+ static int requestEventType;
+};
+
+int RequestFrameEvent::requestEventType = QEvent::registerEventType();
+
+} // anonymous
+
+
/*!
\class Qt3DCore::QAspectManager
\internal
@@ -80,14 +102,9 @@ QAspectManager::QAspectManager(QObject *parent)
, m_jobManager(new QAspectJobManager(this))
, m_changeArbiter(new QChangeArbiter(this))
, m_serviceLocator(new QServiceLocator())
- , m_waitForEndOfSimulationLoop(0)
- , m_waitForStartOfSimulationLoop(0)
- , m_waitForEndOfExecLoop(0)
- , m_waitForQuit(0)
+ , m_simulationLoopRunning(false)
{
qRegisterMetaType<QSurface *>("QSurface*");
- m_runSimulationLoop.fetchAndStoreOrdered(0);
- m_runMainLoop.fetchAndStoreOrdered(1);
qCDebug(Aspects) << Q_FUNC_INFO;
}
@@ -102,15 +119,26 @@ QAspectManager::~QAspectManager()
void QAspectManager::enterSimulationLoop()
{
qCDebug(Aspects) << Q_FUNC_INFO;
- m_runSimulationLoop.fetchAndStoreOrdered(1);
+ m_simulationLoopRunning = true;
- // Wake up QAspectThread's event loop
- thread()->eventDispatcher()->wakeUp();
+ // Retrieve the frame advance service. Defaults to timer based if there is no renderer.
+ QAbstractFrameAdvanceService *frameAdvanceService =
+ m_serviceLocator->service<QAbstractFrameAdvanceService>(QServiceLocator::FrameAdvanceService);
+
+ // Start the frameAdvanceService
+ frameAdvanceService->start();
+
+ // We are about to enter the simulation loop. Give aspects a chance to do any last
+ // pieces of initialization
+ qCDebug(Aspects) << "Calling onEngineStartup() for each aspect";
+ for (QAbstractAspect *aspect : qAsConst(m_aspects)) {
+ qCDebug(Aspects) << "\t" << aspect->objectName();
+ aspect->onEngineStartup();
+ }
+ qCDebug(Aspects) << "Done calling onEngineStartup() for each aspect";
- // We wait for the setRootEntity on the aspectManager to have completed
- // This ensures we cannot shutdown before the aspects have had a chance
- // to be initialized
- m_waitForStartOfSimulationLoop.acquire(1);
+ // Trigger event loop
+ requestNextFrame();
}
// Main thread (called by QAspectEngine)
@@ -119,7 +147,7 @@ void QAspectManager::exitSimulationLoop()
qCDebug(Aspects) << Q_FUNC_INFO;
// If this fails, simulation loop is already exited so nothing to do
- if (!m_runSimulationLoop.testAndSetOrdered(1, 0)) {
+ if (!m_simulationLoopRunning) {
qCDebug(Aspects) << "Simulation loop was not running. Nothing to do";
return;
}
@@ -141,17 +169,26 @@ void QAspectManager::exitSimulationLoop()
for (QAbstractAspect *aspect : qAsConst(m_aspects))
aspect->d_func()->onEngineAboutToShutdown();
+ // Process any pending changes from the frontend before we shut the aspects down
+ m_changeArbiter->syncChanges();
- qCDebug(Aspects) << "exitSimulationLoop waiting for exec loop to terminate";
- // Wait until the simulation loop is fully exited and the aspects are done
- // processing any final changes and have had onEngineShutdown() called on them
- m_waitForEndOfSimulationLoop.acquire(1);
+ // Give aspects a chance to perform any shutdown actions. This may include unqueuing
+ // any blocking work on the main thread that could potentially deadlock during shutdown.
+ qCDebug(Aspects) << "Calling onEngineShutdown() for each aspect";
+ for (QAbstractAspect *aspect : qAsConst(m_aspects)) {
+ qCDebug(Aspects) << "\t" << aspect->objectName();
+ aspect->onEngineShutdown();
+ }
+ qCDebug(Aspects) << "Done calling onEngineShutdown() for each aspect";
+
+
+ m_simulationLoopRunning = false;
qCDebug(Aspects) << "exitSimulationLoop completed";
}
bool QAspectManager::isShuttingDown() const
{
- return !m_runSimulationLoop.load();
+ return !m_simulationLoopRunning;
}
/*!
@@ -184,7 +221,7 @@ void QAspectManager::shutdown()
// Aspects must be deleted in the Thread they were created in
}
-// QAspectThread:: queued invoked by QAspectEngine::setRootEntity
+// MainThread called by QAspectEngine::setRootEntity
void QAspectManager::setRootEntity(Qt3DCore::QEntity *root, const QVector<Qt3DCore::QNodeCreatedChangeBasePtr> &changes)
{
qCDebug(Aspects) << Q_FUNC_INFO;
@@ -251,118 +288,6 @@ void QAspectManager::unregisterAspect(Qt3DCore::QAbstractAspect *aspect)
qCDebug(Aspects) << "Completed unregistering aspect";
}
-void QAspectManager::exec()
-{
- // Gentlemen, start your engines
- QEventLoop eventLoop;
-
- // Enter the engine loop
- qCDebug(Aspects) << Q_FUNC_INFO << "***** Entering main loop *****";
- while (m_runMainLoop.load()) {
- // Process events until we're told to start the simulation loop
- while (m_runMainLoop.load() && !m_runSimulationLoop.load())
- eventLoop.processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
-
- if (!m_runSimulationLoop.load())
- break;
-
- // Retrieve the frame advance service. Defaults to timer based if there is no renderer.
- QAbstractFrameAdvanceService *frameAdvanceService =
- m_serviceLocator->service<QAbstractFrameAdvanceService>(QServiceLocator::FrameAdvanceService);
-
- // Start the frameAdvanceService
- frameAdvanceService->start();
-
- // We are about to enter the simulation loop. Give aspects a chance to do any last
- // pieces of initialization
- qCDebug(Aspects) << "Calling onEngineStartup() for each aspect";
- for (QAbstractAspect *aspect : qAsConst(m_aspects)) {
- qCDebug(Aspects) << "\t" << aspect->objectName();
- aspect->onEngineStartup();
- }
- qCDebug(Aspects) << "Done calling onEngineStartup() for each aspect";
- m_waitForStartOfSimulationLoop.release(1);
-
- // Only enter main simulation loop once the renderer and other aspects are initialized
- while (m_runSimulationLoop.load()) {
- qint64 t = frameAdvanceService->waitForNextFrame();
-
- // 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
- // that any property changes do not set dirty flags in a data race with the renderer's
- // submission thread which may be looking for dirty flags, acting upon them and then
- // clearing the dirty flags.
- //
- // 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
- m_changeArbiter->syncChanges();
-#if QT_CONFIG(qt3d_profile_jobs)
- changeArbiterStats.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed();
- QThreadPooler::addJobLogStatsEntry(changeArbiterStats);
-#endif
-
- // For each Aspect
- // Ask them to launch set of jobs for the current frame
- // Updates matrices, bounding volumes, render bins ...
-#if defined(QT3D_CORE_JOB_TIMING)
- QElapsedTimer timer;
- timer.start();
-#endif
- m_scheduler->scheduleAndWaitForFrameAspectJobs(t);
-#if defined(QT3D_CORE_JOB_TIMING)
- qDebug() << "Jobs took" << timer.nsecsElapsed() / 1.0e6;
-#endif
-
- // Process any pending events
- eventLoop.processEvents();
- } // End of simulation loop
-
- // Process any pending changes from the frontend before we shut the aspects down
- m_changeArbiter->syncChanges();
-
- // Give aspects a chance to perform any shutdown actions. This may include unqueuing
- // any blocking work on the main thread that could potentially deadlock during shutdown.
- qCDebug(Aspects) << "Calling onEngineShutdown() for each aspect";
- for (QAbstractAspect *aspect : qAsConst(m_aspects)) {
- qCDebug(Aspects) << "\t" << aspect->objectName();
- aspect->onEngineShutdown();
- }
- qCDebug(Aspects) << "Done calling onEngineShutdown() for each aspect";
-
- // Wake up the main thread which is waiting for us inside of exitSimulationLoop()
- m_waitForEndOfSimulationLoop.release(1);
- } // End of main loop
- qCDebug(Aspects) << Q_FUNC_INFO << "***** Exited main loop *****";
-
- m_waitForEndOfExecLoop.release(1);
- m_waitForQuit.acquire(1);
-}
-
-void QAspectManager::quit()
-{
- qCDebug(Aspects) << Q_FUNC_INFO;
-
- Q_ASSERT_X(m_runSimulationLoop.load() == 0, "QAspectManagr::quit()", "Inner loop is still running");
- m_runMainLoop.fetchAndStoreOrdered(0);
-
- // Wake up QAspectThread's event loop if needed
- thread()->eventDispatcher()->wakeUp();
-
- // We need to wait for the QAspectManager exec loop to terminate
- m_waitForEndOfExecLoop.acquire(1);
- m_waitForQuit.release(1);
-
- qCDebug(Aspects) << Q_FUNC_INFO << "Exiting";
-}
-
const QVector<QAbstractAspect *> &QAspectManager::aspects() const
{
return m_aspects;
@@ -383,7 +308,81 @@ QServiceLocator *QAspectManager::serviceLocator() const
return m_serviceLocator.data();
}
+/*!
+ \internal
+ \brief Drives the Qt3D simulation loop in the main thread
+ */
+bool QAspectManager::event(QEvent *e)
+{
+ if (e->type() == RequestFrameEvent::eventType()) {
+
+ // Process current frame
+ processFrame();
+
+ // Request next frame if we are still running
+ if (m_simulationLoopRunning)
+ requestNextFrame();
+ }
+
+ return QObject::event(e);
+}
+
+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());
+}
+
+void QAspectManager::processFrame()
+{
+ qCDebug(Aspects) << "Processing Frame";
+
+ // Retrieve the frame advance service. Defaults to timer based if there is no renderer.
+ QAbstractFrameAdvanceService *frameAdvanceService =
+ m_serviceLocator->service<QAbstractFrameAdvanceService>(QServiceLocator::FrameAdvanceService);
+
+ const qint64 t = frameAdvanceService->waitForNextFrame();
+
+ // 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
+ // that any property changes do not set dirty flags in a data race with the renderer's
+ // submission thread which may be looking for dirty flags, acting upon them and then
+ // clearing the dirty flags.
+ //
+ // 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
+ // 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
+
+ // For each Aspect
+ // Ask them to launch set of jobs for the current frame
+ // Updates matrices, bounding volumes, render bins ...
+#if defined(QT3D_CORE_JOB_TIMING)
+ QElapsedTimer timer;
+ timer.start();
+#endif
+ m_scheduler->scheduleAndWaitForFrameAspectJobs(t);
+#if defined(QT3D_CORE_JOB_TIMING)
+ qDebug() << "Jobs took" << timer.nsecsElapsed() / 1.0e6;
+#endif
+}
+
} // namespace Qt3DCore
QT_END_NAMESPACE
-
diff --git a/src/core/aspects/qaspectmanager_p.h b/src/core/aspects/qaspectmanager_p.h
index de978b8e9..1c07ab797 100644
--- a/src/core/aspects/qaspectmanager_p.h
+++ b/src/core/aspects/qaspectmanager_p.h
@@ -95,9 +95,6 @@ public Q_SLOTS:
void registerAspect(Qt3DCore::QAbstractAspect *aspect);
void unregisterAspect(Qt3DCore::QAbstractAspect *aspect);
- void exec();
- void quit();
-
public:
const QVector<QAbstractAspect *> &aspects() const;
QAbstractAspectJobManager *jobManager() const;
@@ -105,19 +102,20 @@ public:
QServiceLocator *serviceLocator() const;
private:
+ bool event(QEvent *event) override;
+ void requestNextFrame();
+ void processFrame();
+
QVector<QAbstractAspect *> m_aspects;
QEntity *m_root;
QVariantMap m_data;
QScheduler *m_scheduler;
QAbstractAspectJobManager *m_jobManager;
QChangeArbiter *m_changeArbiter;
- QAtomicInt m_runSimulationLoop;
- QAtomicInt m_runMainLoop;
QScopedPointer<QServiceLocator> m_serviceLocator;
- QSemaphore m_waitForEndOfSimulationLoop;
- QSemaphore m_waitForStartOfSimulationLoop;
- QSemaphore m_waitForEndOfExecLoop;
- QSemaphore m_waitForQuit;
+ bool m_mainLoopRunning;
+ bool m_simulationLoopRunning;
+
};
} // namespace Qt3DCore
diff --git a/src/core/aspects/qaspectthread.cpp b/src/core/aspects/qaspectthread.cpp
deleted file mode 100644
index 31715b04e..000000000
--- a/src/core/aspects/qaspectthread.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qaspectthread_p.h"
-
-#include <QtCore/QMutexLocker>
-
-#include <Qt3DCore/private/qaspectmanager_p.h>
-#include <Qt3DCore/private/corelogging_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DCore {
-
-QAspectThread::QAspectThread(QObject *parent)
- : QThread(parent),
- m_aspectManager(nullptr),
- m_semaphore(0)
-{
- qCDebug(Aspects) << Q_FUNC_INFO;
-}
-
-QAspectThread::~QAspectThread()
-{
-}
-
-void QAspectThread::waitForStart(Priority priority)
-{
- qCDebug(Aspects) << "Starting QAspectThread and going to sleep until it is ready for us...";
- start(priority);
- m_semaphore.acquire();
- qCDebug(Aspects) << "QAspectThead is now ready & calling thread is now awake again";
-}
-
-void QAspectThread::run()
-{
- qCDebug(Aspects) << "Entering void QAspectThread::run()";
-
- m_aspectManager = new QAspectManager;
-
- // Load and initialize the aspects and any other core services
- // Done before releasing condition to make sure that Qml Components
- // Are exposed prior to Qml Engine source being set
- m_aspectManager->initialize();
-
- // Wake up the calling thread now that our worker objects are ready for action
- m_semaphore.release();
-
- // Enter the main loop
- m_aspectManager->exec();
-
- // Clean up
- m_aspectManager->shutdown();
-
- // Delete the aspect manager while we're still in the thread
- delete m_aspectManager;
-
- qCDebug(Aspects) << "Exiting void QAspectThread::run()";
-}
-
-} // namespace Qt3DCore
-
-QT_END_NAMESPACE
diff --git a/src/core/aspects/qaspectthread_p.h b/src/core/aspects/qaspectthread_p.h
deleted file mode 100644
index 8ae9ff86d..000000000
--- a/src/core/aspects/qaspectthread_p.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt3D module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QT3DCORE_QASPECTTHREAD_P_H
-#define QT3DCORE_QASPECTTHREAD_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <Qt3DCore/qt3dcore_global.h>
-#include <QtCore/QSemaphore>
-#include <QtCore/QThread>
-
-
-QT_BEGIN_NAMESPACE
-
-namespace Qt3DCore {
-
-class QAspectManager;
-
-class QAspectThread : public QThread
-{
- Q_OBJECT
-public:
- explicit QAspectThread(QObject *parent = 0);
- ~QAspectThread();
-
- void waitForStart(Priority priority);
-
- QAspectManager *aspectManager() const { return m_aspectManager; }
-
-protected:
- void run() override;
-
-private:
- QAspectManager *m_aspectManager;
- QSemaphore m_semaphore;
-};
-
-} // namespace Qt3DCore
-
-QT_END_NAMESPACE
-
-#endif // QT3DCORE_QASPECTTHREAD_P_H
diff --git a/src/core/qchangearbiter_p.h b/src/core/qchangearbiter_p.h
index 1f453ff56..c7d96b593 100644
--- a/src/core/qchangearbiter_p.h
+++ b/src/core/qchangearbiter_p.h
@@ -109,8 +109,8 @@ public:
void sceneChangeEventWithLock(const QSceneChangePtr &e) override; // QLockableObserverInterface impl
void sceneChangeEventWithLock(const QSceneChangeList &e) override; // QLockableObserverInterface impl
- Q_INVOKABLE void setPostman(Qt3DCore::QAbstractPostman *postman);
- Q_INVOKABLE void setScene(Qt3DCore::QScene *scene);
+ void setPostman(Qt3DCore::QAbstractPostman *postman);
+ void setScene(Qt3DCore::QScene *scene);
QAbstractPostman *postman() const final;
QScene *scene() const;
diff --git a/src/core/services/qdownloadhelperservice.cpp b/src/core/services/qdownloadhelperservice.cpp
index 4cd89c5d0..deddf3ae0 100644
--- a/src/core/services/qdownloadhelperservice.cpp
+++ b/src/core/services/qdownloadhelperservice.cpp
@@ -39,10 +39,10 @@
#include "qdownloadhelperservice_p.h"
#include "qdownloadnetworkworker_p.h"
+#include <QtCore/QThread>
#include <Qt3DCore/QAspectEngine>
#include <Qt3DCore/private/qabstractserviceprovider_p.h>
#include <Qt3DCore/private/qaspectengine_p.h>
-#include <Qt3DCore/private/qaspectthread_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DCore/private/qservicelocator_p.h>
@@ -196,7 +196,7 @@ QString QDownloadHelperService::urlToLocalFileOrQrc(const QUrl &url)
QDownloadHelperService *QDownloadHelperService::getService(QAspectEngine *engine)
{
auto enginePrivate = Qt3DCore::QAspectEnginePrivate::get(engine);
- return enginePrivate->m_aspectThread->aspectManager()->serviceLocator()->downloadHelperService();
+ return enginePrivate->m_aspectManager->serviceLocator()->downloadHelperService();
}
bool QDownloadHelperService::isLocal(const QUrl &url)
diff --git a/src/input/backend/eventsourcesetterhelper.cpp b/src/input/backend/eventsourcesetterhelper.cpp
index bbc7ea54c..fe800a1a4 100644
--- a/src/input/backend/eventsourcesetterhelper.cpp
+++ b/src/input/backend/eventsourcesetterhelper.cpp
@@ -56,21 +56,21 @@ EventSourceSetterHelper::EventSourceSetterHelper(InputHandler *inputHandler)
{
}
-// Aspect thread
+// Main thread
void EventSourceSetterHelper::setEventFilterService(Qt3DCore::QEventFilterService *service)
{
- QMutexLocker lock(&m_mutex);
m_service = service;
}
-// Any thread
+// Main thread
void EventSourceSetterHelper::setEventSource(QObject *eventSource)
{
if (eventSource && m_lastEventSource != eventSource) {
- QMetaObject::invokeMethod(this,
- "setEventSourceHelper",
- Qt::BlockingQueuedConnection,
- Q_ARG(QObject*, eventSource));
+ if (m_service) {
+ m_service->initialize(eventSource);
+ m_inputHandler->registerEventFilters(m_service);
+ m_lastEventSource = eventSource;
+ }
}
}
@@ -83,17 +83,6 @@ void EventSourceSetterHelper::unsetEventSource(QObject *eventSource)
}
}
-// Main Thread
-void EventSourceSetterHelper::setEventSourceHelper(QObject *eventSource)
-{
- QMutexLocker lock(&m_mutex);
- if (m_service) {
- m_service->initialize(eventSource);
- m_inputHandler->registerEventFilters(m_service);
- m_lastEventSource = eventSource;
- }
-}
-
} // Input
} // Qt3DInput
diff --git a/src/input/backend/eventsourcesetterhelper_p.h b/src/input/backend/eventsourcesetterhelper_p.h
index 48418f1b9..b8800d8a6 100644
--- a/src/input/backend/eventsourcesetterhelper_p.h
+++ b/src/input/backend/eventsourcesetterhelper_p.h
@@ -75,14 +75,10 @@ public:
// Called from aspect thread
void setEventFilterService(Qt3DCore::QEventFilterService *service);
- // Called from any thread
+ // Called from main thread
void setEventSource(QObject *eventSource);
void unsetEventSource(QObject *eventSource);
-private Q_SLOTS:
- // Called in main thread
- void setEventSourceHelper(QObject *);
-
private:
Qt3DCore::QEventFilterService *m_service;
InputHandler *m_inputHandler;
diff --git a/src/input/backend/inputhandler.cpp b/src/input/backend/inputhandler.cpp
index 18559e9d4..9484909ab 100644
--- a/src/input/backend/inputhandler.cpp
+++ b/src/input/backend/inputhandler.cpp
@@ -127,58 +127,55 @@ void InputHandler::unregisterEventFilters(Qt3DCore::QEventFilterService *service
// Called by the keyboardEventFilter in the main thread
void InputHandler::appendKeyEvent(const QT_PREPEND_NAMESPACE(QKeyEvent) &event)
{
- QMutexLocker lock(&m_mutex);
m_pendingKeyEvents.append(event);
}
-// Called by QInputASpect::jobsToExecute (aspectThread)
+// Called by QInputASpect::jobsToExecute (Main Thread)
QList<QT_PREPEND_NAMESPACE(QKeyEvent)> InputHandler::pendingKeyEvents()
{
- QMutexLocker lock(&m_mutex);
return std::move(m_pendingKeyEvents);
}
-// Called by QInputASpect::jobsToExecute (aspectThread)
+// Called by QInputASpect::jobsToExecute (Main Thread)
void InputHandler::clearPendingKeyEvents()
{
- QMutexLocker lock(&m_mutex);
m_pendingKeyEvents.clear();
}
+// Main Thread
void InputHandler::appendMouseEvent(const QT_PREPEND_NAMESPACE(QMouseEvent) &event)
{
- QMutexLocker lock(&m_mutex);
m_pendingMouseEvents.append(event);
}
+// Main Thread
QList<QT_PREPEND_NAMESPACE(QMouseEvent)> InputHandler::pendingMouseEvents()
{
- QMutexLocker lock(&m_mutex);
return std::move(m_pendingMouseEvents);
}
+// Main Thread
void InputHandler::clearPendingMouseEvents()
{
- QMutexLocker lock(&m_mutex);
m_pendingMouseEvents.clear();
}
#if QT_CONFIG(wheelevent)
+// Main Thread
void InputHandler::appendWheelEvent(const QT_PREPEND_NAMESPACE(QWheelEvent) &event)
{
- QMutexLocker lock(&m_mutex);
m_pendingWheelEvents.append(event);
}
+// Main Thread
QList<QT_PREPEND_NAMESPACE (QWheelEvent)> Qt3DInput::Input::InputHandler::pendingWheelEvents()
{
- QMutexLocker lock(&m_mutex);
return std::move(m_pendingWheelEvents);
}
+// Main Thread
void InputHandler::clearPendingWheelEvents()
{
- QMutexLocker lock(&m_mutex);
m_pendingWheelEvents.clear();
}
#endif
@@ -253,7 +250,6 @@ QVector<Qt3DCore::QAspectJobPtr> InputHandler::mouseJobs()
#if QT_CONFIG(wheelevent)
const QList<QT_PREPEND_NAMESPACE(QWheelEvent)> wheelEvents = pendingWheelEvents();
#endif
-
for (const HMouseDevice &cHandle : qAsConst(m_activeMouseDevices)) {
MouseDevice *controller = m_mouseDeviceManager->data(cHandle);
diff --git a/src/input/backend/mousedevice.cpp b/src/input/backend/mousedevice.cpp
index 128988637..e285783b7 100644
--- a/src/input/backend/mousedevice.cpp
+++ b/src/input/backend/mousedevice.cpp
@@ -150,6 +150,7 @@ void MouseDevice::updateWheelEvents(const QList<QT_PREPEND_NAMESPACE (QWheelEven
}
#endif
+// Main Thread
void MouseDevice::updateMouseEvents(const QList<QT_PREPEND_NAMESPACE(QMouseEvent)> &events)
{
// Reset axis values before we accumulate new values for this frame
diff --git a/src/logic/executor.cpp b/src/logic/executor.cpp
index 6134e801e..1c428db47 100644
--- a/src/logic/executor.cpp
+++ b/src/logic/executor.cpp
@@ -64,8 +64,6 @@ void Executor::clearQueueAndProceed()
// If the semaphore is acquired, release it to allow the logic job and hence the
// manager and frame to complete and shutdown to continue.
m_nodeIds.clear();
- if (m_semaphore->available() == 0)
- m_semaphore->release();
}
void Executor::enqueueLogicFrameUpdates(const QVector<Qt3DCore::QNodeId> &nodeIds)
@@ -92,16 +90,12 @@ bool Executor::event(QEvent *e)
void Executor::processLogicFrameUpdates(float dt)
{
Q_ASSERT(m_scene);
- Q_ASSERT(m_semaphore);
const QVector<QNode *> nodes = m_scene->lookupNodes(m_nodeIds);
for (QNode *node : nodes) {
QFrameAction *frameAction = qobject_cast<QFrameAction *>(node);
if (frameAction && frameAction->isEnabled())
frameAction->onTriggered(dt);
}
-
- // Release the semaphore so the calling Manager can continue
- m_semaphore->release();
}
} // namespace Logic
diff --git a/src/logic/executor_p.h b/src/logic/executor_p.h
index e33ff842e..27b9c60c8 100644
--- a/src/logic/executor_p.h
+++ b/src/logic/executor_p.h
@@ -87,7 +87,6 @@ public:
explicit Executor(QObject *parent = 0);
void setScene(Qt3DCore::QScene *scene) { m_scene = scene; }
- void setSemephore(QSemaphore *semaphore) { m_semaphore = semaphore; }
void clearQueueAndProceed();
public Q_SLOTS:
@@ -100,7 +99,6 @@ protected:
private:
QVector<Qt3DCore::QNodeId> m_nodeIds;
Qt3DCore::QScene *m_scene;
- QSemaphore *m_semaphore;
};
} // namespace Logic
diff --git a/src/logic/manager.cpp b/src/logic/manager.cpp
index e10ace592..3d096a342 100644
--- a/src/logic/manager.cpp
+++ b/src/logic/manager.cpp
@@ -56,10 +56,8 @@ namespace Logic {
Manager::Manager()
: m_logicHandlerManager(new HandlerManager)
- , m_semaphore(1)
, m_dt(0.0f)
{
- m_semaphore.acquire();
}
Manager::~Manager()
@@ -69,8 +67,6 @@ Manager::~Manager()
void Manager::setExecutor(Executor *executor)
{
m_executor = executor;
- if (m_executor)
- m_executor->setSemephore(&m_semaphore);
}
void Manager::appendHandler(Handler *handler)
@@ -93,6 +89,7 @@ bool Manager::hasFrameActions() const
return m_logicHandlers.count() > 0;
}
+// Called from Job Thread
void Manager::triggerLogicFrameUpdates()
{
Q_ASSERT(m_executor);
@@ -107,7 +104,6 @@ void Manager::triggerLogicFrameUpdates()
// release the semaphore when it has completed its work.
m_executor->enqueueLogicFrameUpdates(m_logicComponentIds);
qApp->postEvent(m_executor, new FrameUpdateEvent(m_dt));
- m_semaphore.acquire();
}
} // namespace Logic
diff --git a/src/logic/manager_p.h b/src/logic/manager_p.h
index 918bd57e0..e4fa08a47 100644
--- a/src/logic/manager_p.h
+++ b/src/logic/manager_p.h
@@ -95,7 +95,6 @@ private:
QVector<Qt3DCore::QNodeId> m_logicComponentIds;
QLogicAspect *m_logicAspect;
Executor *m_executor;
- QSemaphore m_semaphore;
float m_dt;
};
diff --git a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp
index 454cb9f6a..b1597b095 100644
--- a/tests/benchmarks/render/jobs/tst_bench_jobs.cpp
+++ b/tests/benchmarks/render/jobs/tst_bench_jobs.cpp
@@ -48,7 +48,6 @@
#include <Qt3DCore/private/qaspectjobmanager_p.h>
#include <Qt3DCore/private/qaspectengine_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
-#include <Qt3DCore/private/qaspectthread_p.h>
#include <Qt3DCore/private/qnodevisitor_p.h>
#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
#include <QQmlComponent>