diff options
Diffstat (limited to 'src/core')
67 files changed, 793 insertions, 529 deletions
diff --git a/src/core/aspects/aspectcommanddebugger.cpp b/src/core/aspects/aspectcommanddebugger.cpp index eceec1bbd..7635f44c0 100644 --- a/src/core/aspects/aspectcommanddebugger.cpp +++ b/src/core/aspects/aspectcommanddebugger.cpp @@ -39,12 +39,12 @@ #include "aspectcommanddebugger_p.h" -#include <Qt3DCore/qaspectengine.h> #include <QtNetwork/QTcpSocket> #include <QtCore/QJsonDocument> #include <QtCore/QJsonObject> #include <Qt3DCore/private/qabstractaspect_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p.h> QT_BEGIN_NAMESPACE @@ -64,13 +64,6 @@ struct CommandHeader } // anonymous -AspectCommandDebugger::ReadBuffer::ReadBuffer() - : buffer() - , startIdx(0) - , endIdx(0) -{ -} - void AspectCommandDebugger::ReadBuffer::insert(const QByteArray &array) { buffer.insert(endIdx, array); @@ -88,9 +81,9 @@ void AspectCommandDebugger::ReadBuffer::trim() } } -AspectCommandDebugger::AspectCommandDebugger(QObject *parent) +AspectCommandDebugger::AspectCommandDebugger(QSystemInformationService *parent) : QTcpServer(parent) - , m_aspectEngine(nullptr) + , m_service(parent) { } @@ -115,11 +108,6 @@ void AspectCommandDebugger::initialize() qWarning() << Q_FUNC_INFO << "failed to listen on port 8883"; } -void AspectCommandDebugger::setAspectEngine(QAspectEngine *engine) -{ - m_aspectEngine = engine; -} - void AspectCommandDebugger::asynchronousReplyFinished(AsynchronousCommandReply *reply) { Q_ASSERT(reply->isFinished()); @@ -189,7 +177,7 @@ void AspectCommandDebugger::executeCommand(const QString &command, QTcpSocket *socket) { // Only a single aspect is going to reply - const QVariant response = m_aspectEngine->executeCommand(command); + const QVariant response = m_service->executeCommand(command); if (response.userType() == qMetaTypeId<AsynchronousCommandReply *>()) { // AsynchronousCommand // Store the command | socket in a table AsynchronousCommandReply *reply = response.value<AsynchronousCommandReply *>(); diff --git a/src/core/aspects/aspectcommanddebugger_p.h b/src/core/aspects/aspectcommanddebugger_p.h index bb6100df5..b39708ab1 100644 --- a/src/core/aspects/aspectcommanddebugger_p.h +++ b/src/core/aspects/aspectcommanddebugger_p.h @@ -54,32 +54,30 @@ // #include <QTcpServer> +#include <Qt3DCore/private/qt3dcore_global_p.h> QT_BEGIN_NAMESPACE namespace Qt3DCore { -class QAspectEngine; +class QSystemInformationService; namespace Debug { class AsynchronousCommandReply; -class Q_AUTOTEST_EXPORT AspectCommandDebugger : public QTcpServer +class Q_3DCORE_PRIVATE_EXPORT AspectCommandDebugger : public QTcpServer { Q_OBJECT public: - explicit AspectCommandDebugger(QObject *parent = nullptr); + explicit AspectCommandDebugger(QSystemInformationService *parent = nullptr); void initialize(); - void setAspectEngine(QAspectEngine *engine); - - struct ReadBuffer { - ReadBuffer(); + struct Q_3DCORE_PRIVATE_EXPORT ReadBuffer { QByteArray buffer; - int startIdx; - int endIdx; + int startIdx = 0; + int endIdx = 0; inline int size() const { return endIdx - startIdx; } void insert(const QByteArray &array); @@ -95,7 +93,7 @@ private: void executeCommand(const QString &command, QTcpSocket *socket); QVector<QTcpSocket *> m_connections; - QAspectEngine *m_aspectEngine; + QSystemInformationService *m_service; ReadBuffer m_readBuffer; QHash<AsynchronousCommandReply *, QTcpSocket *> m_asyncCommandToSocketEntries; diff --git a/src/core/aspects/aspects.pri b/src/core/aspects/aspects.pri index 5e8327192..068f74389 100644 --- a/src/core/aspects/aspects.pri +++ b/src/core/aspects/aspects.pri @@ -4,7 +4,8 @@ SOURCES += \ $$PWD/qabstractaspect.cpp \ $$PWD/qaspectengine.cpp \ $$PWD/qaspectfactory.cpp \ - $$PWD/qaspectmanager.cpp + $$PWD/qaspectmanager.cpp \ + $$PWD/aspectcommanddebugger.cpp HEADERS += \ $$PWD/qabstractaspect.h \ @@ -12,13 +13,10 @@ HEADERS += \ $$PWD/qabstractaspect_p.h \ $$PWD/qaspectengine_p.h \ $$PWD/qaspectfactory_p.h \ - $$PWD/qaspectmanager_p.h + $$PWD/qaspectmanager_p.h \ + $$PWD/aspectcommanddebugger_p.h INCLUDEPATH += $$PWD include($$QT3D_BUILD_ROOT/src/core/qt3dcore-config.pri) QT_FOR_CONFIG += 3dcore-private -qtConfig(qt3d-profile-jobs): { - HEADERS += $$PWD/aspectcommanddebugger_p.h - SOURCES += $$PWD/aspectcommanddebugger.cpp -} diff --git a/src/core/aspects/qabstractaspect.cpp b/src/core/aspects/qabstractaspect.cpp index 05afdd293..a2aed732b 100644 --- a/src/core/aspects/qabstractaspect.cpp +++ b/src/core/aspects/qabstractaspect.cpp @@ -198,28 +198,16 @@ void QAbstractAspect::unregisterBackendType(const QMetaObject &obj) QVariant QAbstractAspect::executeCommand(const QStringList &args) { - Q_UNUSED(args); + Q_UNUSED(args) return QVariant(); } QVector<QAspectJobPtr> QAbstractAspect::jobsToExecute(qint64 time) { - Q_UNUSED(time); + Q_UNUSED(time) return QVector<QAspectJobPtr>(); } -void QAbstractAspect::syncDirtyFrontEndNodes(const QVector<QNode *> &nodes) -{ - Q_D(QAbstractAspect); - d->syncDirtyFrontEndNodes(nodes); -} - -void QAbstractAspect::syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes) -{ - Q_D(QAbstractAspect); - d->syncDirtyFrontEndSubNodes(nodes); -} - QAbstractAspectPrivate::BackendNodeMapperAndInfo QAbstractAspectPrivate::mapperForNode(const QMetaObject *metaObj) const { Q_ASSERT(metaObj); @@ -520,6 +508,11 @@ QVector<QAspectJobPtr> QAbstractAspectPrivate::jobsToExecute(qint64 time) return res; } +void QAbstractAspectPrivate::jobsDone(QAspectManager *manager) +{ + Q_UNUSED(manager) +} + /*! * Called in the context of the aspect thread once the aspect has been registered. * This provides an opportunity for the aspect to do any initialization tasks that diff --git a/src/core/aspects/qabstractaspect.h b/src/core/aspects/qabstractaspect.h index 8059421a6..3b2f31c50 100644 --- a/src/core/aspects/qabstractaspect.h +++ b/src/core/aspects/qabstractaspect.h @@ -87,9 +87,6 @@ protected: void unregisterBackendType(const QMetaObject &); private: - void syncDirtyFrontEndNodes(const QVector<QNode *> &nodes); - void syncDirtyFrontEndSubNodes(const QVector<NodeRelationshipChange> &nodes); - virtual QVariant executeCommand(const QStringList &args); virtual QVector<QAspectJobPtr> jobsToExecute(qint64 time); diff --git a/src/core/aspects/qabstractaspect_p.h b/src/core/aspects/qabstractaspect_p.h index 670302cfa..9435f2bc6 100644 --- a/src/core/aspects/qabstractaspect_p.h +++ b/src/core/aspects/qabstractaspect_p.h @@ -57,6 +57,7 @@ #include <Qt3DCore/private/qaspectjobproviderinterface_p.h> #include <Qt3DCore/private/qbackendnode_p.h> #include <Qt3DCore/private/qt3dcore_global_p.h> +#include <Qt3DCore/private/qscenechange_p.h> #include <QtCore/private/qobject_p.h> #include <QMutex> @@ -126,6 +127,7 @@ public: QAbstractAspectJobManager *jobManager() const; QVector<QAspectJobPtr> jobsToExecute(qint64 time) override; + void jobsDone(Qt3DCore::QAspectManager *manager) override; QBackendNode *createBackendNode(const NodeTreeChange &change) const; void clearBackendNode(const NodeTreeChange &change) const; diff --git a/src/core/aspects/qaspectengine.cpp b/src/core/aspects/qaspectengine.cpp index 426741a61..d28306197 100644 --- a/src/core/aspects/qaspectengine.cpp +++ b/src/core/aspects/qaspectengine.cpp @@ -55,12 +55,9 @@ #include <Qt3DCore/private/qpostman_p.h> #include <Qt3DCore/private/qscene_p.h> #include <Qt3DCore/private/qservicelocator_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p.h> #include <Qt3DCore/qt3dcore-config.h> -#if QT_CONFIG(qt3d_profile_jobs) -#include <Qt3DCore/private/aspectcommanddebugger_p.h> -#endif - QT_BEGIN_NAMESPACE namespace{ @@ -122,9 +119,6 @@ QAspectEnginePrivate::QAspectEnginePrivate() , m_scene(nullptr) , m_initialized(false) , m_runMode(QAspectEngine::Automatic) - #if QT_CONFIG(qt3d_profile_jobs) - , m_commandDebugger(new Debug::AspectCommandDebugger(q_func())) - #endif { qRegisterMetaType<Qt3DCore::QAbstractAspect *>(); qRegisterMetaType<Qt3DCore::QObserverInterface *>(); @@ -276,10 +270,6 @@ void QAspectEnginePrivate::initialize() arbiter->setScene(m_scene); m_initialized = true; m_aspectManager->setPostConstructorInit(m_scene->postConstructorInit()); -#if QT_CONFIG(qt3d_profile_jobs) - m_commandDebugger->setAspectEngine(q_func()); - m_commandDebugger->initialize(); -#endif } /*! @@ -419,16 +409,8 @@ QVariant QAspectEngine::executeCommand(const QString &command) if (d->m_aspects.isEmpty()) return QLatin1String("No loaded aspect"); - QString reply; - reply += QLatin1String("Loaded aspects:"); - for (QAbstractAspect *aspect : qAsConst(d->m_aspects)) { - const QString name = d->m_factory.aspectName(aspect); - if (!name.isEmpty()) - reply += QLatin1String("\n * ") + name; - else - reply += QLatin1String("\n * <unnamed>"); - } - return reply; + const QStringList names = d->m_aspectManager->serviceLocator()->systemInformation()->aspectNames(); + return names.join(QLatin1String("\n")); } QStringList args = command.split(QLatin1Char(' ')); diff --git a/src/core/aspects/qaspectengine_p.h b/src/core/aspects/qaspectengine_p.h index c83940435..8f3abcd38 100644 --- a/src/core/aspects/qaspectengine_p.h +++ b/src/core/aspects/qaspectengine_p.h @@ -69,12 +69,6 @@ class QAspectManager; class QPostman; class QScene; -#if QT_CONFIG(qt3d_profile_jobs) -namespace Debug { -class AspectCommandDebugger; -} // Debug -#endif - class Q_3DCORE_PRIVATE_EXPORT QAspectEnginePrivate : public QObjectPrivate { public: @@ -93,10 +87,6 @@ public: bool m_initialized; QAspectEngine::RunMode m_runMode; -#if QT_CONFIG(qt3d_profile_jobs) - Debug::AspectCommandDebugger *m_commandDebugger; -#endif - void initialize(); void shutdown(); 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 diff --git a/src/core/aspects/qaspectmanager_p.h b/src/core/aspects/qaspectmanager_p.h index d9a6c41ec..ed04b314f 100644 --- a/src/core/aspects/qaspectmanager_p.h +++ b/src/core/aspects/qaspectmanager_p.h @@ -73,6 +73,7 @@ class QScheduler; class QChangeArbiter; class QAbstractAspect; class QAbstractAspectJobManager; +class QAspectEngine; class QServiceLocator; class NodePostConstructorInit; struct NodeTreeChange; @@ -81,7 +82,7 @@ class Q_3DCORE_PRIVATE_EXPORT QAspectManager : public QObject { Q_OBJECT public: - explicit QAspectManager(QObject *parent = nullptr); + explicit QAspectManager(QAspectEngine *parent = nullptr); ~QAspectManager(); void setRunMode(QAspectEngine::RunMode mode); @@ -111,10 +112,13 @@ public: QNode *lookupNode(QNodeId id) const; QVector<QNode *> lookupNodes(const QVector<QNodeId> &ids) const; + int jobsInLastFrame() const { return m_jobsInLastFrame; } + private: bool event(QEvent *event) override; void requestNextFrame(); + QAspectEngine *m_engine; QVector<QAbstractAspect *> m_aspects; QEntity *m_root; QVariantMap m_data; @@ -122,12 +126,11 @@ private: QAbstractAspectJobManager *m_jobManager; QChangeArbiter *m_changeArbiter; QScopedPointer<QServiceLocator> m_serviceLocator; - bool m_mainLoopRunning; bool m_simulationLoopRunning; QAspectEngine::RunMode m_driveMode; QVector<NodeTreeChange> m_nodeTreeChanges; NodePostConstructorInit* m_postConstructorInit; - + int m_jobsInLastFrame; }; } // namespace Qt3DCore diff --git a/src/core/changes/qcomponentaddedchange.h b/src/core/changes/qcomponentaddedchange.h index ef2f6a227..9e1522024 100644 --- a/src/core/changes/qcomponentaddedchange.h +++ b/src/core/changes/qcomponentaddedchange.h @@ -53,10 +53,10 @@ class QComponentAddedChangePrivate; class Q_3DCORESHARED_EXPORT QComponentAddedChange : public QSceneChange { public: - explicit QComponentAddedChange(const QEntity *entity, - const QComponent *component); - explicit QComponentAddedChange(const QComponent *component, - const QEntity *entity); + Q3D_DECL_DEPRECATED explicit QComponentAddedChange(const QEntity *entity, + const QComponent *component); + Q3D_DECL_DEPRECATED explicit QComponentAddedChange(const QComponent *component, + const QEntity *entity); ~QComponentAddedChange(); QNodeId entityId() const Q_DECL_NOTHROW; @@ -67,7 +67,7 @@ private: Q_DECLARE_PRIVATE(QComponentAddedChange) }; -typedef QSharedPointer<QComponentAddedChange> QComponentAddedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QComponentAddedChange> QComponentAddedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qcomponentremovedchange.h b/src/core/changes/qcomponentremovedchange.h index 8108b33d5..e0b039780 100644 --- a/src/core/changes/qcomponentremovedchange.h +++ b/src/core/changes/qcomponentremovedchange.h @@ -53,10 +53,10 @@ class QComponentRemovedChangePrivate; class Q_3DCORESHARED_EXPORT QComponentRemovedChange : public QSceneChange { public: - explicit QComponentRemovedChange(const QEntity *entity, - const QComponent *component); - explicit QComponentRemovedChange(const QComponent *component, - const QEntity *entity); + Q3D_DECL_DEPRECATED explicit QComponentRemovedChange(const QEntity *entity, + const QComponent *component); + Q3D_DECL_DEPRECATED explicit QComponentRemovedChange(const QComponent *component, + const QEntity *entity); ~QComponentRemovedChange(); QNodeId entityId() const Q_DECL_NOTHROW; @@ -67,7 +67,7 @@ private: Q_DECLARE_PRIVATE(QComponentRemovedChange) }; -typedef QSharedPointer<QComponentRemovedChange> QComponentRemovedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QComponentRemovedChange> QComponentRemovedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qdynamicpropertyupdatedchange.h b/src/core/changes/qdynamicpropertyupdatedchange.h index 0509582b0..7009e1fe7 100644 --- a/src/core/changes/qdynamicpropertyupdatedchange.h +++ b/src/core/changes/qdynamicpropertyupdatedchange.h @@ -51,7 +51,7 @@ class QDynamicPropertyUpdatedChangePrivate; class Q_3DCORESHARED_EXPORT QDynamicPropertyUpdatedChange : public QPropertyUpdatedChangeBase { public: - explicit QDynamicPropertyUpdatedChange(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QDynamicPropertyUpdatedChange(QNodeId subjectId); ~QDynamicPropertyUpdatedChange(); QByteArray propertyName() const; @@ -65,7 +65,7 @@ protected: QDynamicPropertyUpdatedChange(QDynamicPropertyUpdatedChangePrivate &dd, QNodeId subjectId); }; -typedef QSharedPointer<QDynamicPropertyUpdatedChange> QDynamicPropertyUpdatedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QDynamicPropertyUpdatedChange> QDynamicPropertyUpdatedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qnodecommand.h b/src/core/changes/qnodecommand.h index 3622f7421..83d7caf4f 100644 --- a/src/core/changes/qnodecommand.h +++ b/src/core/changes/qnodecommand.h @@ -57,7 +57,7 @@ public: typedef quint32 CommandId; #endif - explicit QNodeCommand(QNodeId id); + Q3D_DECL_DEPRECATED explicit QNodeCommand(QNodeId id); ~QNodeCommand(); CommandId commandId() const; @@ -76,7 +76,7 @@ private: Q_DECLARE_PRIVATE(QNodeCommand) }; -typedef QSharedPointer<QNodeCommand> QNodeCommandPtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QNodeCommand> QNodeCommandPtr; } // namespace Qt3DCore diff --git a/src/core/changes/qnodecreatedchange.h b/src/core/changes/qnodecreatedchange.h index f46e8abee..359cdb917 100644 --- a/src/core/changes/qnodecreatedchange.h +++ b/src/core/changes/qnodecreatedchange.h @@ -51,7 +51,7 @@ class QNodeCreatedChangeBasePrivate; class Q_3DCORESHARED_EXPORT QNodeCreatedChangeBase : public QSceneChange { public: - explicit QNodeCreatedChangeBase(const QNode *node); + Q3D_DECL_DEPRECATED explicit QNodeCreatedChangeBase(const QNode *node); ~QNodeCreatedChangeBase(); QNodeId parentId() const Q_DECL_NOTHROW; @@ -65,7 +65,7 @@ private: Q_DECLARE_PRIVATE(QNodeCreatedChangeBase) }; -typedef QSharedPointer<QNodeCreatedChangeBase> QNodeCreatedChangeBasePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QNodeCreatedChangeBase> QNodeCreatedChangeBasePtr; template<typename T> class QNodeCreatedChange : public QNodeCreatedChangeBase @@ -81,7 +81,7 @@ public: }; template<typename T> -using QNodeCreatedChangePtr = QSharedPointer<QNodeCreatedChange<T>>; +using QNodeCreatedChangePtr Q3D_DECL_DEPRECATED = QSharedPointer<QNodeCreatedChange<T>>; } // namespace Qt3DCore diff --git a/src/core/changes/qnodedestroyedchange.h b/src/core/changes/qnodedestroyedchange.h index c072dd412..dce6da59e 100644 --- a/src/core/changes/qnodedestroyedchange.h +++ b/src/core/changes/qnodedestroyedchange.h @@ -50,7 +50,7 @@ class QNodeDestroyedChangePrivate; class Q_3DCORESHARED_EXPORT QNodeDestroyedChange : public QSceneChange { public: - explicit QNodeDestroyedChange(const QNode *node, const QVector<QNodeIdTypePair> &subtreeIdsAndTypes); + Q3D_DECL_DEPRECATED explicit QNodeDestroyedChange(const QNode *node, const QVector<QNodeIdTypePair> &subtreeIdsAndTypes); ~QNodeDestroyedChange(); QVector<QNodeIdTypePair> subtreeIdsAndTypes() const; @@ -59,7 +59,7 @@ private: Q_DECLARE_PRIVATE(QNodeDestroyedChange) }; -typedef QSharedPointer<QNodeDestroyedChange> QNodeDestroyedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QNodeDestroyedChange> QNodeDestroyedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertynodeaddedchange.h b/src/core/changes/qpropertynodeaddedchange.h index ce3288a65..062244f88 100644 --- a/src/core/changes/qpropertynodeaddedchange.h +++ b/src/core/changes/qpropertynodeaddedchange.h @@ -53,7 +53,7 @@ class QPropertyNodeAddedChangePrivate; class Q_3DCORESHARED_EXPORT QPropertyNodeAddedChange : public QStaticPropertyValueAddedChangeBase { public: - explicit QPropertyNodeAddedChange(QNodeId subjectId, QNode *node); + Q3D_DECL_DEPRECATED explicit QPropertyNodeAddedChange(QNodeId subjectId, QNode *node); ~QPropertyNodeAddedChange(); QNodeId addedNodeId() const; @@ -63,7 +63,7 @@ private: Q_DECLARE_PRIVATE(QPropertyNodeAddedChange) }; -typedef QSharedPointer<QPropertyNodeAddedChange> QPropertyNodeAddedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyNodeAddedChange> QPropertyNodeAddedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertynoderemovedchange.h b/src/core/changes/qpropertynoderemovedchange.h index 1a4db8f1c..a8ea9d6c4 100644 --- a/src/core/changes/qpropertynoderemovedchange.h +++ b/src/core/changes/qpropertynoderemovedchange.h @@ -53,7 +53,7 @@ class QPropertyNodeRemovedChangePrivate; class Q_3DCORESHARED_EXPORT QPropertyNodeRemovedChange : public QStaticPropertyValueRemovedChangeBase { public: - explicit QPropertyNodeRemovedChange(QNodeId subjectId, QNode *node); + Q3D_DECL_DEPRECATED explicit QPropertyNodeRemovedChange(QNodeId subjectId, QNode *node); ~QPropertyNodeRemovedChange(); QNodeId removedNodeId() const; @@ -63,7 +63,7 @@ private: Q_DECLARE_PRIVATE(QPropertyNodeRemovedChange) }; -typedef QSharedPointer<QPropertyNodeRemovedChange> QPropertyNodeRemovedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyNodeRemovedChange> QPropertyNodeRemovedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertyupdatedchange.h b/src/core/changes/qpropertyupdatedchange.h index e0c12f13d..aa0dd9364 100644 --- a/src/core/changes/qpropertyupdatedchange.h +++ b/src/core/changes/qpropertyupdatedchange.h @@ -51,7 +51,7 @@ class QPropertyUpdatedChangePrivate; class Q_3DCORESHARED_EXPORT QPropertyUpdatedChange : public QStaticPropertyUpdatedChangeBase { public: - explicit QPropertyUpdatedChange(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyUpdatedChange(QNodeId subjectId); virtual ~QPropertyUpdatedChange(); QVariant value() const; @@ -62,7 +62,7 @@ protected: QPropertyUpdatedChange(QPropertyUpdatedChangePrivate &dd, QNodeId subjectId); }; -typedef QSharedPointer<QPropertyUpdatedChange> QPropertyUpdatedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyUpdatedChange> QPropertyUpdatedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertyupdatedchangebase.h b/src/core/changes/qpropertyupdatedchangebase.h index 800abb477..5a0f6c87f 100644 --- a/src/core/changes/qpropertyupdatedchangebase.h +++ b/src/core/changes/qpropertyupdatedchangebase.h @@ -56,12 +56,12 @@ public: ~QPropertyUpdatedChangeBase(); protected: - explicit QPropertyUpdatedChangeBase(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyUpdatedChangeBase(QNodeId subjectId); QPropertyUpdatedChangeBase(QPropertyUpdatedChangeBasePrivate &dd, QNodeId subjectId); Q_DECLARE_PRIVATE(QPropertyUpdatedChangeBase) }; -typedef QSharedPointer<QPropertyUpdatedChangeBase> QPropertyUpdatedChangeBasePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyUpdatedChangeBase> QPropertyUpdatedChangeBasePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertyvalueaddedchange.h b/src/core/changes/qpropertyvalueaddedchange.h index d85720246..e70d78b7e 100644 --- a/src/core/changes/qpropertyvalueaddedchange.h +++ b/src/core/changes/qpropertyvalueaddedchange.h @@ -53,7 +53,7 @@ class QPropertyValueAddedChangePrivate; class Q_3DCORESHARED_EXPORT QPropertyValueAddedChange : public QStaticPropertyValueAddedChangeBase { public: - explicit QPropertyValueAddedChange(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyValueAddedChange(QNodeId subjectId); ~QPropertyValueAddedChange(); void setAddedValue(const QVariant &value); @@ -63,7 +63,7 @@ private: Q_DECLARE_PRIVATE(QPropertyValueAddedChange) }; -typedef QSharedPointer<QPropertyValueAddedChange> QPropertyValueAddedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueAddedChange> QPropertyValueAddedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertyvalueaddedchangebase.h b/src/core/changes/qpropertyvalueaddedchangebase.h index 2be39ad47..148411de8 100644 --- a/src/core/changes/qpropertyvalueaddedchangebase.h +++ b/src/core/changes/qpropertyvalueaddedchangebase.h @@ -56,12 +56,12 @@ public: ~QPropertyValueAddedChangeBase(); protected: - explicit QPropertyValueAddedChangeBase(QNodeId subjectId); - explicit QPropertyValueAddedChangeBase(QPropertyValueAddedChangeBasePrivate &dd, QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyValueAddedChangeBase(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyValueAddedChangeBase(QPropertyValueAddedChangeBasePrivate &dd, QNodeId subjectId); Q_DECLARE_PRIVATE(QPropertyValueAddedChangeBase) }; -typedef QSharedPointer<QPropertyValueAddedChangeBase> QPropertyValueAddedChangeBasePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueAddedChangeBase> QPropertyValueAddedChangeBasePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertyvalueremovedchange.h b/src/core/changes/qpropertyvalueremovedchange.h index 2bd781ed5..70eb42db4 100644 --- a/src/core/changes/qpropertyvalueremovedchange.h +++ b/src/core/changes/qpropertyvalueremovedchange.h @@ -53,7 +53,7 @@ class QPropertyValueRemovedChangePrivate; class Q_3DCORESHARED_EXPORT QPropertyValueRemovedChange : public QStaticPropertyValueRemovedChangeBase { public: - explicit QPropertyValueRemovedChange(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyValueRemovedChange(QNodeId subjectId); ~QPropertyValueRemovedChange(); void setRemovedValue(const QVariant &value); @@ -63,7 +63,7 @@ private: Q_DECLARE_PRIVATE(QPropertyValueRemovedChange) }; -typedef QSharedPointer<QPropertyValueRemovedChange> QPropertyValueRemovedChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueRemovedChange> QPropertyValueRemovedChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qpropertyvalueremovedchangebase.h b/src/core/changes/qpropertyvalueremovedchangebase.h index 233354078..b5ead7d22 100644 --- a/src/core/changes/qpropertyvalueremovedchangebase.h +++ b/src/core/changes/qpropertyvalueremovedchangebase.h @@ -57,11 +57,11 @@ public: protected: Q_DECLARE_PRIVATE(QPropertyValueRemovedChangeBase) - explicit QPropertyValueRemovedChangeBase(QNodeId subjectId); - explicit QPropertyValueRemovedChangeBase(QPropertyValueRemovedChangeBasePrivate &dd, QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyValueRemovedChangeBase(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QPropertyValueRemovedChangeBase(QPropertyValueRemovedChangeBasePrivate &dd, QNodeId subjectId); }; -typedef QSharedPointer<QPropertyValueRemovedChangeBase> QPropertyValueRemovedChangeBasePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QPropertyValueRemovedChangeBase> QPropertyValueRemovedChangeBasePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qscenechange.cpp b/src/core/changes/qscenechange.cpp index 87bf06ea0..822451b5f 100644 --- a/src/core/changes/qscenechange.cpp +++ b/src/core/changes/qscenechange.cpp @@ -48,6 +48,7 @@ namespace Qt3DCore { /*! * \enum Qt3DCore::ChangeFlag * \relates Qt3DCore::QSceneChange + * \obsolete * * The types of change that can be sent and received by Qt3D's change notification system. * diff --git a/src/core/changes/qscenechange.h b/src/core/changes/qscenechange.h index e8c0ea748..792c00d0a 100644 --- a/src/core/changes/qscenechange.h +++ b/src/core/changes/qscenechange.h @@ -48,7 +48,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { -enum ChangeFlag { +enum Q3D_DECL_DEPRECATED ChangeFlag { NodeCreated = 1 << 0, NodeDeleted = 1 << 1, PropertyUpdated = 1 << 2, @@ -64,14 +64,6 @@ Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag) Q_DECLARE_OPERATORS_FOR_FLAGS(ChangeFlags) class QNode; -//! internal -struct NodeRelationshipChange { - QNode *node; - QNode *subNode; - ChangeFlag change; - const char *property; -}; - class QSceneChangePrivate; class Q_3DCORESHARED_EXPORT QSceneChange @@ -95,9 +87,9 @@ public: protected: Q_DECLARE_PRIVATE(QSceneChange) - explicit QSceneChange(ChangeFlag type, QNodeId subjectId); - explicit QSceneChange(QSceneChangePrivate &dd, - ChangeFlag type, QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QSceneChange(ChangeFlag type, QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QSceneChange(QSceneChangePrivate &dd, + ChangeFlag type, QNodeId subjectId); QSceneChangePrivate *d_ptr; private: @@ -106,7 +98,7 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QSceneChange::DeliveryFlags) -typedef QSharedPointer<QSceneChange> QSceneChangePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QSceneChange> QSceneChangePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qscenechange_p.h b/src/core/changes/qscenechange_p.h index d32f6eec3..32006807c 100644 --- a/src/core/changes/qscenechange_p.h +++ b/src/core/changes/qscenechange_p.h @@ -63,6 +63,13 @@ namespace Qt3DCore { class QSceneChange; class QNodeId; +struct NodeRelationshipChange { + QNode *node; + QNode *subNode; + ChangeFlag change; + const char *property; +}; + class Q_3DCORE_PRIVATE_EXPORT QSceneChangePrivate { public : diff --git a/src/core/changes/qskeletoncreatedchange_p.h b/src/core/changes/qskeletoncreatedchange_p.h index 09b37d545..c20bcae85 100644 --- a/src/core/changes/qskeletoncreatedchange_p.h +++ b/src/core/changes/qskeletoncreatedchange_p.h @@ -60,7 +60,7 @@ class QSkeletonCreatedChangeBasePrivate; class Q_3DCORESHARED_EXPORT QSkeletonCreatedChangeBase : public QNodeCreatedChangeBase { public: - explicit QSkeletonCreatedChangeBase(const QAbstractSkeleton *skeleton); + Q3D_DECL_DEPRECATED explicit QSkeletonCreatedChangeBase(const QAbstractSkeleton *skeleton); ~QSkeletonCreatedChangeBase(); enum SkeletonType { @@ -74,7 +74,7 @@ private: Q_DECLARE_PRIVATE(QSkeletonCreatedChangeBase) }; -typedef QSharedPointer<QSkeletonCreatedChangeBase> QSkeletonCreatedChangeBasePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QSkeletonCreatedChangeBase> QSkeletonCreatedChangeBasePtr; template<typename T> class QSkeletonCreatedChange : public QSkeletonCreatedChangeBase @@ -90,7 +90,7 @@ public: }; template<typename T> -using QSkeletonCreatedChangePtr = QSharedPointer<QSkeletonCreatedChange<T>>; +using QSkeletonCreatedChangePtr Q3D_DECL_DEPRECATED = QSharedPointer<QSkeletonCreatedChange<T>>; } // namespace Qt3DCore diff --git a/src/core/changes/qstaticpropertyupdatedchangebase.h b/src/core/changes/qstaticpropertyupdatedchangebase.h index b698d1f06..c59a87a20 100644 --- a/src/core/changes/qstaticpropertyupdatedchangebase.h +++ b/src/core/changes/qstaticpropertyupdatedchangebase.h @@ -57,12 +57,12 @@ public: void setPropertyName(const char *name); protected: - explicit QStaticPropertyUpdatedChangeBase(QNodeId subjectId); - explicit QStaticPropertyUpdatedChangeBase(QStaticPropertyUpdatedChangeBasePrivate &dd, QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QStaticPropertyUpdatedChangeBase(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QStaticPropertyUpdatedChangeBase(QStaticPropertyUpdatedChangeBasePrivate &dd, QNodeId subjectId); Q_DECLARE_PRIVATE(QStaticPropertyUpdatedChangeBase) }; -typedef QSharedPointer<QStaticPropertyUpdatedChangeBase> QStaticPropertyUpdatedChangeBasePtr; +Q3D_DECL_DEPRECATED typedef QSharedPointer<QStaticPropertyUpdatedChangeBase> QStaticPropertyUpdatedChangeBasePtr; } // namespace Qt3DCore diff --git a/src/core/changes/qstaticpropertyvalueaddedchangebase.h b/src/core/changes/qstaticpropertyvalueaddedchangebase.h index e56e8f18a..7e6807764 100644 --- a/src/core/changes/qstaticpropertyvalueaddedchangebase.h +++ b/src/core/changes/qstaticpropertyvalueaddedchangebase.h @@ -59,7 +59,7 @@ public: protected: Q_DECLARE_PRIVATE(QStaticPropertyValueAddedChangeBase) - explicit QStaticPropertyValueAddedChangeBase(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QStaticPropertyValueAddedChangeBase(QNodeId subjectId); QStaticPropertyValueAddedChangeBase(QStaticPropertyValueAddedChangeBasePrivate &dd, QNodeId subjectId); }; diff --git a/src/core/changes/qstaticpropertyvalueremovedchangebase.h b/src/core/changes/qstaticpropertyvalueremovedchangebase.h index e9f53fb12..d1b96f83e 100644 --- a/src/core/changes/qstaticpropertyvalueremovedchangebase.h +++ b/src/core/changes/qstaticpropertyvalueremovedchangebase.h @@ -59,7 +59,7 @@ public: protected: Q_DECLARE_PRIVATE(QStaticPropertyValueRemovedChangeBase) - explicit QStaticPropertyValueRemovedChangeBase(QNodeId subjectId); + Q3D_DECL_DEPRECATED explicit QStaticPropertyValueRemovedChangeBase(QNodeId subjectId); QStaticPropertyValueRemovedChangeBase(QStaticPropertyValueRemovedChangeBasePrivate &dd, QNodeId subjectId); }; diff --git a/src/core/configure.json b/src/core/configure.json index 2ba205530..2e13d9027 100644 --- a/src/core/configure.json +++ b/src/core/configure.json @@ -44,7 +44,7 @@ "output": [ "privateFeature" ] }, "qt3d-profile-jobs": { - "label": "Output Qt3D Job traces", + "label": "Output Qt3D Job traces (deprecated)", "autoDetect": false, "output": [ "privateFeature" ] }, @@ -112,7 +112,6 @@ "entries": [ "assimp", "system-assimp", - "qt3d-profile-jobs", "qt3d-profile-gl", "qt3d-simd-sse2", "qt3d-simd-avx2", diff --git a/src/core/jobs/qaspectjob_p.h b/src/core/jobs/qaspectjob_p.h index b16c3cad2..ddad09c86 100644 --- a/src/core/jobs/qaspectjob_p.h +++ b/src/core/jobs/qaspectjob_p.h @@ -54,6 +54,7 @@ #include <QtCore/QWeakPointer> #include <Qt3DCore/private/qt3dcore_global_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p_p.h> #include <Qt3DCore/qt3dcore-config.h> QT_BEGIN_NAMESPACE @@ -63,47 +64,6 @@ namespace Qt3DCore { class QAspectJob; class QAspectManager; -#if QT_CONFIG(qt3d_profile_jobs) -struct FrameHeader -{ - FrameHeader() - : frameId(0) - , jobCount(0) - , frameType(WorkerJob) - { - } - - enum FrameType { - WorkerJob = 0, - Submission - }; - - quint32 frameId; - quint16 jobCount; - quint16 frameType; // Submission or worker job -}; - -union JobId -{ - quint32 typeAndInstance[2]; - quint64 id; -}; - -struct JobRunStats -{ - JobRunStats() - { - jobId.id = 0; - } - - qint64 startTime; - qint64 endTime; - JobId jobId; - // QAspectJob subclasses should properly populate the jobId - quint64 threadId; -}; -#endif - class Q_3DCORE_PRIVATE_EXPORT QAspectJobPrivate { public: @@ -115,29 +75,16 @@ public: virtual void postFrame(QAspectManager *aspectManager); QVector<QWeakPointer<QAspectJob> > m_dependencies; -#if QT_CONFIG(qt3d_profile_jobs) - JobRunStats m_stats; -#endif + JobId m_jobId; }; - } // Qt3D -#if QT_CONFIG(qt3d_profile_jobs) - -#include <Qt3DCore/private/qaspectjob_p.h> - #define SET_JOB_RUN_STAT_TYPE(job, type, instance) \ - Qt3DCore::QAspectJobPrivate::get(job)->m_stats.jobId.typeAndInstance[0] = type; \ - Qt3DCore::QAspectJobPrivate::get(job)->m_stats.jobId.typeAndInstance[1] = instance; - -#else - -#define SET_JOB_RUN_STAT_TYPE(job, type, instance) \ - Q_UNUSED(job) \ - Q_UNUSED(type) \ - Q_UNUSED(instance) - -#endif + { \ + auto &jobId = Qt3DCore::QAspectJobPrivate::get(job)->m_jobId; \ + jobId.typeAndInstance[0] = type; \ + jobId.typeAndInstance[1] = instance; \ + } QT_END_NAMESPACE diff --git a/src/core/jobs/qaspectjobmanager.cpp b/src/core/jobs/qaspectjobmanager.cpp index 91394924f..be7942359 100644 --- a/src/core/jobs/qaspectjobmanager.cpp +++ b/src/core/jobs/qaspectjobmanager.cpp @@ -44,7 +44,7 @@ #include <QtCore/QDebug> #include <QtCore/QThread> #include <QtCore/QFuture> - +#include <Qt3DCore/private/qaspectmanager_p.h> #include <Qt3DCore/private/qthreadpooler_p.h> #include <Qt3DCore/private/task_p.h> @@ -52,9 +52,10 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { -QAspectJobManager::QAspectJobManager(QObject *parent) +QAspectJobManager::QAspectJobManager(QAspectManager *parent) : QAbstractAspectJobManager(parent) , m_threadPooler(new QThreadPooler(this)) + , m_aspectManager(parent) { } @@ -69,12 +70,16 @@ void QAspectJobManager::initialize() // Adds all Aspect Jobs to be processed for a frame void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue) { + auto systemService = m_aspectManager ? m_aspectManager->serviceLocator()->systemInformation() : nullptr; + if (systemService) + systemService->writePreviousFrameTraces(); + // Convert QJobs to Tasks QHash<QAspectJob *, AspectTaskRunnable *> tasksMap; QVector<RunnableInterface *> taskList; taskList.reserve(jobQueue.size()); for (const QAspectJobPtr &job : jobQueue) { - AspectTaskRunnable *task = new AspectTaskRunnable(); + AspectTaskRunnable *task = new AspectTaskRunnable(systemService); task->m_job = job; tasksMap.insert(job.data(), task); @@ -99,9 +104,6 @@ void QAspectJobManager::enqueueJobs(const QVector<QAspectJobPtr> &jobQueue) taskDepender->m_dependerCount += dependerCount; } -#if QT_CONFIG(qt3d_profile_jobs) - QThreadPooler::writeFrameJobLogStats(); -#endif m_threadPooler->mapDependables(taskList); } diff --git a/src/core/jobs/qaspectjobmanager_p.h b/src/core/jobs/qaspectjobmanager_p.h index 77e535491..acbd0263e 100644 --- a/src/core/jobs/qaspectjobmanager_p.h +++ b/src/core/jobs/qaspectjobmanager_p.h @@ -63,12 +63,13 @@ namespace Qt3DCore { class QThreadPooler; class DependencyHandler; +class QAspectManager; class Q_3DCORE_PRIVATE_EXPORT QAspectJobManager : public QAbstractAspectJobManager { Q_OBJECT public: - explicit QAspectJobManager(QObject *parent = 0); + explicit QAspectJobManager(QAspectManager *parent = nullptr); ~QAspectJobManager(); void initialize() override; @@ -81,6 +82,7 @@ public: private: QThreadPooler *m_threadPooler; + QAspectManager *m_aspectManager; }; } // namespace Qt3DCore diff --git a/src/core/jobs/qaspectjobproviderinterface_p.h b/src/core/jobs/qaspectjobproviderinterface_p.h index 29b44b3c1..b521fea68 100644 --- a/src/core/jobs/qaspectjobproviderinterface_p.h +++ b/src/core/jobs/qaspectjobproviderinterface_p.h @@ -61,6 +61,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { class QScheduler; +class QAspectManager; class QAspectJobProviderInterface { @@ -69,6 +70,7 @@ public: private: virtual QVector<QAspectJobPtr> jobsToExecute(qint64 time) = 0; + virtual void jobsDone(QAspectManager *manager) = 0; friend class QScheduler; }; diff --git a/src/core/jobs/qthreadpooler.cpp b/src/core/jobs/qthreadpooler.cpp index a9f4e7a31..f5c50062a 100644 --- a/src/core/jobs/qthreadpooler.cpp +++ b/src/core/jobs/qthreadpooler.cpp @@ -40,45 +40,27 @@ #include "qthreadpooler_p.h" #include <QtCore/QDebug> -#if QT_CONFIG(qt3d_profile_jobs) - -#ifdef Q_OS_ANDROID -#include <QtCore/QStandardPaths> -#endif - -#include <QtCore/QCoreApplication> -#include <QtCore/QFile> -#include <QtCore/QThreadStorage> -#include <QtCore/QDateTime> -#include <QtCore/QCoreApplication> -#endif - QT_BEGIN_NAMESPACE namespace Qt3DCore { -#if QT_CONFIG(qt3d_profile_jobs) -QElapsedTimer QThreadPooler::m_jobsStatTimer; -#endif - QThreadPooler::QThreadPooler(QObject *parent) : QObject(parent) , m_futureInterface(nullptr) , m_mutex() , m_taskCount(0) + , m_threadPool(QThreadPool::globalInstance()) { const QByteArray maxThreadCount = qgetenv("QT3D_MAX_THREAD_COUNT"); if (!maxThreadCount.isEmpty()) { bool conversionOK = false; const int maxThreadCountValue = maxThreadCount.toInt(&conversionOK); if (conversionOK) - m_threadPool.setMaxThreadCount(maxThreadCountValue); + m_threadPool->setMaxThreadCount(maxThreadCountValue); } + // Ensures that threads will never be recycled - m_threadPool.setExpiryTimeout(-1); -#if QT_CONFIG(qt3d_profile_jobs) - QThreadPooler::m_jobsStatTimer.start(); -#endif + m_threadPool->setExpiryTimeout(-1); } QThreadPooler::~QThreadPooler() @@ -105,7 +87,7 @@ void QThreadPooler::enqueueTasks(const QVector<RunnableInterface *> &tasks) if (!hasDependencies(*it) && !(*it)->reserved()) { (*it)->setReserved(true); (*it)->setPooler(this); - m_threadPool.start((*it)); + m_threadPool->start((*it)); } } } @@ -125,7 +107,7 @@ void QThreadPooler::taskFinished(RunnableInterface *task) if (!aspectTask->reserved()) { aspectTask->setReserved(true); aspectTask->setPooler(this); - m_threadPool.start(aspectTask); + m_threadPool->start(aspectTask); } } } @@ -188,105 +170,9 @@ int QThreadPooler::currentCount() const int QThreadPooler::maxThreadCount() const { - return m_threadPool.maxThreadCount(); -} - -#if QT_CONFIG(qt3d_profile_jobs) - -QThreadStorage<QVector<JobRunStats> *> jobStatsCached; - -QVector<QVector<JobRunStats> *> localStorages; -QVector<JobRunStats> *submissionStorage = nullptr; - -QMutex localStoragesMutex; - -// Called by the jobs -void QThreadPooler::addJobLogStatsEntry(JobRunStats &stats) -{ - if (!jobStatsCached.hasLocalData()) { - auto jobVector = new QVector<JobRunStats>; - jobStatsCached.setLocalData(jobVector); - QMutexLocker lock(&localStoragesMutex); - localStorages.push_back(jobVector); - } - jobStatsCached.localData()->push_back(stats); -} - -// Called after jobs have been executed (MainThread QAspectJobManager::enqueueJobs) -void QThreadPooler::writeFrameJobLogStats() -{ - static QScopedPointer<QFile> traceFile; - static quint32 frameId = 0; - if (!traceFile) { - const QString fileName = QStringLiteral("trace_") + QCoreApplication::applicationName() + QDateTime::currentDateTime().toString(QStringLiteral("_ddd_dd_MM_yy-hh_mm_ss_"))+ QSysInfo::productType() + QStringLiteral("_") + QSysInfo::buildAbi() + QStringLiteral(".qt3d"); -#ifdef Q_OS_ANDROID - traceFile.reset(new QFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/") + fileName)); -#else - traceFile.reset(new QFile(fileName)); -#endif - if (!traceFile->open(QFile::WriteOnly|QFile::Truncate)) - qCritical("Failed to open trace file"); - } - - // Write Aspect + Job threads - { - FrameHeader header; - header.frameId = frameId; - header.jobCount = 0; - - for (const QVector<JobRunStats> *storage : qAsConst(localStorages)) - header.jobCount += storage->size(); - - traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader)); - - for (QVector<JobRunStats> *storage : qAsConst(localStorages)) { - for (const JobRunStats &stat : *storage) - traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats)); - storage->clear(); - } - } - - // Write submission thread - { - QMutexLocker lock(&localStoragesMutex); - const int submissionJobSize = submissionStorage != nullptr ? submissionStorage->size() : 0; - if (submissionJobSize > 0) { - FrameHeader header; - header.frameId = frameId; - header.jobCount = submissionJobSize; - header.frameType = FrameHeader::Submission; - - traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader)); - - for (const JobRunStats &stat : *submissionStorage) - traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats)); - submissionStorage->clear(); - } - } - - traceFile->flush(); - ++frameId; -} - -// Called from Submission thread (which can be main thread in Manual drive mode) -void QThreadPooler::addSubmissionLogStatsEntry(JobRunStats &stats) -{ - QMutexLocker lock(&localStoragesMutex); - if (!jobStatsCached.hasLocalData()) { - submissionStorage = new QVector<JobRunStats>; - jobStatsCached.setLocalData(submissionStorage); - } - - // Handle the case where submission thread is also the main thread (Scene/Manual drive modes with no RenderThread) - if (submissionStorage == nullptr && jobStatsCached.hasLocalData()) - submissionStorage = new QVector<JobRunStats>; - - // When having no submission thread this can be null - submissionStorage->push_back(stats); + return m_threadPool->maxThreadCount(); } -#endif - } // namespace Qt3DCore QT_END_NAMESPACE diff --git a/src/core/jobs/qthreadpooler_p.h b/src/core/jobs/qthreadpooler_p.h index 65459efba..1970641b8 100644 --- a/src/core/jobs/qthreadpooler_p.h +++ b/src/core/jobs/qthreadpooler_p.h @@ -60,10 +60,6 @@ #include <Qt3DCore/private/qaspectjob_p.h> #include <Qt3DCore/private/task_p.h> -#if QT_CONFIG(qt3d_profile_jobs) -#include <QtCore/QElapsedTimer> -#endif - QT_BEGIN_NAMESPACE namespace Qt3DCore { @@ -81,17 +77,6 @@ public: QFuture<void> future(); int maxThreadCount() const; -#if QT_CONFIG(qt3d_profile_jobs) - static QElapsedTimer m_jobsStatTimer; - - // Aspects + Job threads - static void addJobLogStatsEntry(JobRunStats &stats); - static void writeFrameJobLogStats(); - - // Submission thread - static void addSubmissionLogStatsEntry(JobRunStats &stats); - -#endif private: void enqueueTasks(const QVector<RunnableInterface *> &tasks); @@ -103,7 +88,7 @@ private: QFutureInterface<void> *m_futureInterface; QMutex m_mutex; QAtomicInt m_taskCount; - QThreadPool m_threadPool; + QThreadPool *m_threadPool; }; } // namespace Qt3DCore diff --git a/src/core/jobs/task.cpp b/src/core/jobs/task.cpp index 091aabfd6..1dd5712c9 100644 --- a/src/core/jobs/task.cpp +++ b/src/core/jobs/task.cpp @@ -44,6 +44,7 @@ #include <QtCore/QMutexLocker> #include <Qt3DCore/private/qthreadpooler_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p_p.h> QT_BEGIN_NAMESPACE @@ -55,8 +56,10 @@ RunnableInterface::~RunnableInterface() // Aspect task -AspectTaskRunnable::AspectTaskRunnable() - : m_pooler(nullptr) +AspectTaskRunnable::AspectTaskRunnable(QSystemInformationService *service) + : m_service(service) + , m_pooler(nullptr) + , m_id(0) , m_reserved(false) { } @@ -68,21 +71,9 @@ AspectTaskRunnable::~AspectTaskRunnable() void AspectTaskRunnable::run() { if (m_job) { -#if QT_CONFIG(qt3d_profile_jobs) QAspectJobPrivate *jobD = QAspectJobPrivate::get(m_job.data()); - if (m_pooler) { - jobD->m_stats.startTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed(); - jobD->m_stats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId()); - } -#endif + QTaskLogger logger(m_pooler ? m_service : nullptr, jobD->m_jobId, QTaskLogger::AspectJob); m_job->run(); -#if QT_CONFIG(qt3d_profile_jobs) - if (m_pooler) { - jobD->m_stats.endTime = QThreadPooler::m_jobsStatTimer.nsecsElapsed(); - // Add current job's stats to log output - QThreadPooler::addJobLogStatsEntry(jobD->m_stats); - } -#endif } // We could have an append sub task or something in here diff --git a/src/core/jobs/task_p.h b/src/core/jobs/task_p.h index c81882719..ff411539f 100644 --- a/src/core/jobs/task_p.h +++ b/src/core/jobs/task_p.h @@ -65,6 +65,7 @@ namespace Qt3DCore { class JobRunner; class DependencyHandler; class QThreadPooler; +class QSystemInformationService; class RunnableInterface : public QRunnable { @@ -92,7 +93,7 @@ public: class AspectTaskRunnable : public RunnableInterface { public: - AspectTaskRunnable(); + AspectTaskRunnable(QSystemInformationService *service); ~AspectTaskRunnable(); void run() override; @@ -113,6 +114,7 @@ public: int m_dependerCount = 0; private: + QSystemInformationService *m_service; QThreadPooler *m_pooler; int m_id; // For testing purposes for now bool m_reserved; diff --git a/src/core/nodes/qbackendnode.cpp b/src/core/nodes/qbackendnode.cpp index e5f93e96f..4138ea060 100644 --- a/src/core/nodes/qbackendnode.cpp +++ b/src/core/nodes/qbackendnode.cpp @@ -220,6 +220,7 @@ QBackendNode::QBackendNode(QBackendNodePrivate &dd) /*! * Notifies observers of scene change \a e. + * \obsolete */ void QBackendNode::notifyObservers(const QSceneChangePtr &e) { @@ -228,6 +229,8 @@ void QBackendNode::notifyObservers(const QSceneChangePtr &e) } /*! + \obsolete + Send the command named \a name with contents \a data, and specify \a replyTo as the command id to which the reply needs to be sent. @@ -247,6 +250,7 @@ QNodeCommand::CommandId QBackendNode::sendCommand(const QString &name, /*! Send the reply to \a command. + \obsolete */ void QBackendNode::sendReply(const QNodeCommandPtr &command) { @@ -254,9 +258,12 @@ void QBackendNode::sendReply(const QNodeCommandPtr &command) notifyObservers(command); } +/*! + * \obsolete + */ void QBackendNode::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) { - Q_UNUSED(change); + Q_UNUSED(change) qCDebug(Nodes) << Q_FUNC_INFO << change->metaObject()->className() << "does not override"; } @@ -270,8 +277,7 @@ void QBackendNode::setEnabled(bool enabled) Q_DECL_NOTHROW } /*! - * TODO - * \a e + * \obsolete */ void QBackendNode::sceneChangeEvent(const QSceneChangePtr &e) { diff --git a/src/core/nodes/qbackendnode.h b/src/core/nodes/qbackendnode.h index 550ced04f..691375999 100644 --- a/src/core/nodes/qbackendnode.h +++ b/src/core/nodes/qbackendnode.h @@ -90,18 +90,18 @@ public: protected: Q_DECLARE_PRIVATE(QBackendNode) explicit QBackendNode(QBackendNodePrivate &dd); - void notifyObservers(const QSceneChangePtr &e); - QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data, - QNodeCommand::CommandId replyTo = QNodeCommand::CommandId()); - void sendReply(const QNodeCommandPtr &command); - virtual void sceneChangeEvent(const QSceneChangePtr &e); + Q3D_DECL_DEPRECATED void notifyObservers(const QSceneChangePtr &e); + Q3D_DECL_DEPRECATED QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data, + QNodeCommand::CommandId replyTo = QNodeCommand::CommandId()); + Q3D_DECL_DEPRECATED void sendReply(const QNodeCommandPtr &command); + Q3D_DECL_DEPRECATED virtual void sceneChangeEvent(const QSceneChangePtr &e); QBackendNodePrivate *d_ptr; private: Q_DISABLE_COPY(QBackendNode) void setPeerId(QNodeId id) Q_DECL_NOEXCEPT; - virtual void initializeFromPeer(const QNodeCreatedChangeBasePtr &change); + Q3D_DECL_DEPRECATED virtual void initializeFromPeer(const QNodeCreatedChangeBasePtr &change); friend class QBackendNodePropertyChange; friend class QAbstractAspectPrivate; diff --git a/src/core/nodes/qentity.cpp b/src/core/nodes/qentity.cpp index 024991387..93601901f 100644 --- a/src/core/nodes/qentity.cpp +++ b/src/core/nodes/qentity.cpp @@ -75,7 +75,7 @@ namespace Qt3DCore { */ /*! - \fn template<typename T> QVector<T *> QEntity::componentsOfType() const + \fn template<typename T> QVector<T *> Qt3DCore::QEntity::componentsOfType() const Returns all the components added to this entity that can be cast to type T or an empty vector if there are no such components. diff --git a/src/core/nodes/qnode.cpp b/src/core/nodes/qnode.cpp index cfe83f4db..ad084242f 100644 --- a/src/core/nodes/qnode.cpp +++ b/src/core/nodes/qnode.cpp @@ -382,7 +382,7 @@ void QNodePrivate::unregisterNotifiedProperties() void QNodePrivate::propertyChanged(int propertyIndex) { - Q_UNUSED(propertyIndex); + Q_UNUSED(propertyIndex) // Bail out early if we can to avoid the cost below if (m_blockNotifications) @@ -539,6 +539,8 @@ void QNode::notifyObservers(const QSceneChangePtr &change) } /*! + \obsolete + Called when one or more backend aspects sends a notification \a change to the current Qt3DCore::QNode instance. @@ -547,7 +549,7 @@ void QNode::notifyObservers(const QSceneChangePtr &change) */ void QNode::sceneChangeEvent(const QSceneChangePtr &change) { - Q_UNUSED(change); + Q_UNUSED(change) if (change->type() == Qt3DCore::PropertyUpdated) { // TODO: Do this more efficiently. We could pass the metaobject and property // index to the animation aspect via the QChannelMapping. This would @@ -594,8 +596,8 @@ QScene *QNodePrivate::scene() const */ void QNodePrivate::notifyPropertyChange(const char *name, const QVariant &value) { - Q_UNUSED(name); - Q_UNUSED(value); + Q_UNUSED(name) + Q_UNUSED(value) // Bail out early if we can to avoid operator new if (m_blockNotifications) @@ -606,8 +608,8 @@ void QNodePrivate::notifyPropertyChange(const char *name, const QVariant &value) void QNodePrivate::notifyDynamicPropertyChange(const QByteArray &name, const QVariant &value) { - Q_UNUSED(name); - Q_UNUSED(value); + Q_UNUSED(name) + Q_UNUSED(value) // Bail out early if we can to avoid operator new if (m_blockNotifications) @@ -683,6 +685,11 @@ void QNodePrivate::update() void QNodePrivate::updateNode(QNode *node, const char *property, ChangeFlag change) { if (m_changeArbiter) { + // Ensure node has its postConstructorInit called if we reach this + // point, we could otherwise endup referencing a node that has yet + // to be created in the backend + QNodePrivate::get(node)->_q_ensureBackendNodeCreated(); + Q_Q(QNode); m_changeArbiter->addDirtyFrontEndNode(q, node, property, change); } @@ -787,10 +794,9 @@ QNode::~QNode() { Q_D(QNode); // Disconnect each connection that was stored - for (auto it = d->m_destructionConnections.begin(), end = d->m_destructionConnections.end(); it != end; ++it) - QObject::disconnect(it.value()); + for (const auto &nodeConnectionPair : qAsConst(d->m_destructionConnections)) + QObject::disconnect(nodeConnectionPair.second); d->m_destructionConnections.clear(); - Q_EMIT nodeDestroyed(); // Notify the backend that the parent lost this node as a child and @@ -993,6 +999,9 @@ void QNode::clearPropertyTrackings() d->updatePropertyTrackMode(); } +/*! + * \obsolete + */ QNodeCreatedChangeBasePtr QNode::createNodeCreationChange() const { // Uncomment this when implementing new frontend and backend types. @@ -1045,6 +1054,7 @@ QNodeCreatedChangeBasePtr QNode::createNodeCreationChange() const */ /*! * \brief Sends a command message to the backend node + * \obsolete * * Creates a QNodeCommand message and dispatches it to the backend node. The * command is given and a \a name and some \a data which can be used in the @@ -1075,6 +1085,7 @@ QNodeCommand::CommandId QNode::sendCommand(const QString &name, /*! * \brief Send a \a command back to the backend node. + * \obsolete * * Assumes the command is to be to sent back in reply to itself to the backend node. * diff --git a/src/core/nodes/qnode.h b/src/core/nodes/qnode.h index 9ca817fb6..efdec8da5 100644 --- a/src/core/nodes/qnode.h +++ b/src/core/nodes/qnode.h @@ -99,9 +99,9 @@ public: void clearPropertyTracking(const QString &propertyName); void clearPropertyTrackings(); - QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data = QVariant(), - QNodeCommand::CommandId replyTo = QNodeCommand::CommandId()); - void sendReply(const QNodeCommandPtr &command); + Q3D_DECL_DEPRECATED QNodeCommand::CommandId sendCommand(const QString &name, const QVariant &data = QVariant(), + QNodeCommand::CommandId replyTo = QNodeCommand::CommandId()); + Q3D_DECL_DEPRECATED void sendReply(const QNodeCommandPtr &command); public Q_SLOTS: void setParent(QNode *parent); @@ -116,12 +116,12 @@ Q_SIGNALS: protected: explicit QNode(QNodePrivate &dd, QNode *parent = nullptr); - void notifyObservers(const QSceneChangePtr &change); - virtual void sceneChangeEvent(const QSceneChangePtr &change); + Q3D_DECL_DEPRECATED void notifyObservers(const QSceneChangePtr &change); + Q3D_DECL_DEPRECATED virtual void sceneChangeEvent(const QSceneChangePtr &change); private: Q_DECLARE_PRIVATE(QNode) - virtual QNodeCreatedChangeBasePtr createNodeCreationChange() const; + Q3D_DECL_DEPRECATED virtual QNodeCreatedChangeBasePtr createNodeCreationChange() const; // We only want setParent(QNode *) to be callable // when dealing with QNode objects diff --git a/src/core/nodes/qnode_p.h b/src/core/nodes/qnode_p.h index a7a300a5e..61aa81c81 100644 --- a/src/core/nodes/qnode_p.h +++ b/src/core/nodes/qnode_p.h @@ -124,7 +124,7 @@ public: // If the node is destoyed, we make sure not to keep a dangling pointer to it Q_Q(QNode); auto f = [q, func]() { (static_cast<Caller *>(q)->*func)(nullptr); }; - m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f)); + m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)}); } template<typename Caller, typename NodeType> @@ -133,7 +133,7 @@ public: // If the node is destoyed, we make sure not to keep a dangling pointer to it Q_Q(QNode); auto f = [q, func, node]() { (static_cast<Caller *>(q)->*func)(node); }; - m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f)); + m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)}); } template<typename Caller, typename ValueType> @@ -146,7 +146,7 @@ public: // If the node is destoyed, we make sure not to keep a dangling pointer to it Q_Q(QNode); auto f = [q, func, resetValue]() { (static_cast<Caller *>(q)->*func)(resetValue); }; - m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f)); + m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)}); } template<typename Caller, typename NodeType> @@ -154,12 +154,21 @@ public: { // If the node is destoyed, we make sure not to keep a dangling pointer to it auto f = [this, func, node]() { (static_cast<Caller *>(this)->*func)(node); }; - m_destructionConnections.insert(node, QObject::connect(node, &QNode::nodeDestroyed, f)); + m_destructionConnections.push_back({node, QObject::connect(node, &QNode::nodeDestroyed, f)}); } void unregisterDestructionHelper(QNode *node) { - QObject::disconnect(m_destructionConnections.take(node)); + m_destructionConnections.erase(std::remove_if(m_destructionConnections.begin(), + m_destructionConnections.end(), + [node] (const QPair<QNode *, QMetaObject::Connection> &nodeConnectionPair) { + if (nodeConnectionPair.first == node) { + QObject::disconnect(nodeConnectionPair.second); + return true; + } + return false; + }), + m_destructionConnections.end()); } static const QMetaObject *findStaticMetaObject(const QMetaObject *metaObject); @@ -184,7 +193,7 @@ private: friend class PropertyChangeHandler<QNodePrivate>; bool m_propertyChangesSetup; PropertyChangeHandler<QNodePrivate> m_signals; - QHash<QNode *, QMetaObject::Connection> m_destructionConnections; + QVector<QPair<QNode *, QMetaObject::Connection>> m_destructionConnections; }; class NodePostConstructorInit : public QObject diff --git a/src/core/qchangearbiter_p.h b/src/core/qchangearbiter_p.h index f31480685..7d48c390a 100644 --- a/src/core/qchangearbiter_p.h +++ b/src/core/qchangearbiter_p.h @@ -64,6 +64,7 @@ #include <Qt3DCore/private/qlockableobserverinterface_p.h> #include <Qt3DCore/private/qt3dcore_global_p.h> +#include <Qt3DCore/private/qscenechange_p.h> QT_BEGIN_NAMESPACE diff --git a/src/core/qpostman_p.h b/src/core/qpostman_p.h index 23c638239..3e5f91742 100644 --- a/src/core/qpostman_p.h +++ b/src/core/qpostman_p.h @@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QPostman final { Q_OBJECT public: - explicit QPostman(QObject *parent = 0); + explicit QPostman(QObject *parent = nullptr); ~QPostman(); void setScene(QScene *sceneLookup) final; diff --git a/src/core/qscheduler.cpp b/src/core/qscheduler.cpp index edfbb391c..2294976ca 100644 --- a/src/core/qscheduler.cpp +++ b/src/core/qscheduler.cpp @@ -43,6 +43,7 @@ #include <Qt3DCore/private/qabstractaspect_p.h> #include <Qt3DCore/private/qaspectmanager_p.h> +#include <Qt3DCore/private/qaspectjob_p.h> #include <Qt3DCore/private/qabstractaspectjobmanager_p.h> QT_BEGIN_NAMESPACE @@ -69,7 +70,7 @@ QAspectManager *QScheduler::aspectManager() const return m_aspectManager; } -void QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time) +int QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time) { QVector<QAspectJobPtr> jobQueue; @@ -92,8 +93,17 @@ void QScheduler::scheduleAndWaitForFrameAspectJobs(qint64 time) m_aspectManager->jobManager()->waitForAllJobs(); - for (auto &job : qAsConst(jobQueue)) - job->postFrame(m_aspectManager); + { + QTaskLogger logger(m_aspectManager->serviceLocator()->systemInformation(), 4097, 0); + + for (auto &job : qAsConst(jobQueue)) + QAspectJobPrivate::get(job.data())->postFrame(m_aspectManager); + + for (QAbstractAspect *aspect : aspects) + QAbstractAspectPrivate::get(aspect)->jobsDone(m_aspectManager); + } + + return jobQueue.size(); } } // namespace Qt3DCore diff --git a/src/core/qscheduler_p.h b/src/core/qscheduler_p.h index 9b1685e54..dd4101ef2 100644 --- a/src/core/qscheduler_p.h +++ b/src/core/qscheduler_p.h @@ -64,13 +64,13 @@ class QScheduler : public QObject { Q_OBJECT public: - explicit QScheduler(QObject *parent = 0); + explicit QScheduler(QObject *parent = nullptr); ~QScheduler(); void setAspectManager(QAspectManager *aspectManager); QAspectManager *aspectManager() const; - virtual void scheduleAndWaitForFrameAspectJobs(qint64 time); + virtual int scheduleAndWaitForFrameAspectJobs(qint64 time); private: QAspectManager *m_aspectManager; diff --git a/src/core/qt3dcore_global.h b/src/core/qt3dcore_global.h index b2ad787c0..e932b02ba 100644 --- a/src/core/qt3dcore_global.h +++ b/src/core/qt3dcore_global.h @@ -55,6 +55,12 @@ QT_BEGIN_NAMESPACE # define Q_3DCORESHARED_EXPORT #endif +#ifdef BUILD_QT3D_MODULE +#define Q3D_DECL_DEPRECATED +#else +#define Q3D_DECL_DEPRECATED Q_DECL_DEPRECATED +#endif + #define QT3D_DECLARE_TYPEINFO(NS, Class, Flags) \ } /* NS */ \ Q_DECLARE_TYPEINFO(NS :: Class, Flags); \ diff --git a/src/core/resources/qframeallocator.cpp b/src/core/resources/qframeallocator.cpp index 61a82a2b4..e85ae4057 100644 --- a/src/core/resources/qframeallocator.cpp +++ b/src/core/resources/qframeallocator.cpp @@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { QFrameAllocatorPrivate::QFrameAllocatorPrivate() + : m_maxObjectSize(0U) + , m_alignment(0U) { } diff --git a/src/core/resources/qloadgltf_p.h b/src/core/resources/qloadgltf_p.h new file mode 100644 index 000000000..be7ee0d5f --- /dev/null +++ b/src/core/resources/qloadgltf_p.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** 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_QLOADGLTF_P_H +#define QT3DCORE_QLOADGLTF_P_H + +#include <QtCore/qcborarray.h> +#include <QtCore/qcbormap.h> +#include <QtCore/qcborvalue.h> +#include <QtCore/qjsonarray.h> +#include <QtCore/qjsondocument.h> +#include <QtCore/qjsonobject.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. +// + +inline QJsonDocument qLoadGLTF(const QByteArray &gltfData) +{ +#if QT_CONFIG(binaryjson) + { + QJsonDocument sceneDocument = QJsonDocument::fromBinaryData(gltfData); + if (!sceneDocument.isNull()) + return sceneDocument; + } +#endif + { + const QCborValue cbor = QCborValue::fromCbor(gltfData); + if (cbor.isMap()) + return QJsonDocument(cbor.toMap().toJsonObject()); + if (cbor.isArray()) + return QJsonDocument(cbor.toArray().toJsonArray()); + } + return QJsonDocument::fromJson(gltfData); +} + +#endif // QT3DCORE_QLOADGLTF_P_H diff --git a/src/core/resources/resources.pri b/src/core/resources/resources.pri index 7f3ce4bdc..89540a36d 100644 --- a/src/core/resources/resources.pri +++ b/src/core/resources/resources.pri @@ -1,4 +1,5 @@ HEADERS += \ + $$PWD/qloadgltf_p.h \ $$PWD/qresourcemanager_p.h \ $$PWD/qcircularbuffer_p.h \ $$PWD/qboundedcircularbuffer_p.h \ diff --git a/src/core/services/nullservices_p.h b/src/core/services/nullservices_p.h index 30dc2d543..6b2d1b029 100644 --- a/src/core/services/nullservices_p.h +++ b/src/core/services/nullservices_p.h @@ -54,25 +54,11 @@ #include <Qt3DCore/qt3dcore_global.h> #include <Qt3DCore/private/qopenglinformationservice_p.h> -#include <Qt3DCore/private/qsysteminformationservice_p.h> QT_BEGIN_NAMESPACE namespace Qt3DCore { -class NullSystemInformationService : public QSystemInformationService -{ -public: - NullSystemInformationService() - : QSystemInformationService(QStringLiteral("Null System Information Service")) - {} - ~NullSystemInformationService() {} - - QStringList aspectNames() const final { return QStringList(); } - int threadPoolThreadCount() const final { return 0; } -}; - - class NullOpenGLInformationService : public QOpenGLInformationService { public: diff --git a/src/core/services/qservicelocator.cpp b/src/core/services/qservicelocator.cpp index bdcb4a521..73a40c2e4 100644 --- a/src/core/services/qservicelocator.cpp +++ b/src/core/services/qservicelocator.cpp @@ -46,6 +46,7 @@ #include <Qt3DCore/private/qdownloadhelperservice_p.h> #include <Qt3DCore/private/qeventfilterservice_p.h> #include <Qt3DCore/private/qtickclockservice_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p.h> QT_BEGIN_NAMESPACE @@ -85,16 +86,19 @@ QString QAbstractServiceProvider::description() const } +class QAspectEngine; + class QServiceLocatorPrivate { public: - QServiceLocatorPrivate() - : m_nonNullDefaultServices(0) + QServiceLocatorPrivate(QAspectEngine *aspectEngine) + : m_systemInfo(aspectEngine) + , m_nonNullDefaultServices(0) {} QHash<int, QAbstractServiceProvider *> m_services; - NullSystemInformationService m_nullSystemInfo; + QSystemInformationService m_systemInfo; NullOpenGLInformationService m_nullOpenGLInfo; QTickClockService m_defaultFrameAdvanceService; QEventFilterService m_eventFilterService; @@ -128,8 +132,8 @@ public: /* Creates an instance of QServiceLocator. */ -QServiceLocator::QServiceLocator() - : d_ptr(new QServiceLocatorPrivate) +QServiceLocator::QServiceLocator(QAspectEngine *aspectEngine) + : d_ptr(new QServiceLocatorPrivate(aspectEngine)) { } @@ -196,7 +200,7 @@ int QServiceLocator::serviceCount() const QSystemInformationService *QServiceLocator::systemInformation() { Q_D(QServiceLocator); - return static_cast<QSystemInformationService *>(d->m_services.value(SystemInformation, &d->m_nullSystemInfo)); + return static_cast<QSystemInformationService *>(d->m_services.value(SystemInformation, &d->m_systemInfo)); } /* diff --git a/src/core/services/qservicelocator_p.h b/src/core/services/qservicelocator_p.h index 9111a14ab..5bf71a996 100644 --- a/src/core/services/qservicelocator_p.h +++ b/src/core/services/qservicelocator_p.h @@ -85,11 +85,12 @@ class QSystemInformationService; class QServiceLocatorPrivate; class QEventFilterService; class QDownloadHelperService; +class QAspectEngine; class Q_3DCORESHARED_EXPORT QServiceLocator { public: - QServiceLocator(); + QServiceLocator(QAspectEngine *aspectEngine = nullptr); ~QServiceLocator(); enum ServiceType { diff --git a/src/core/services/qsysteminformationservice.cpp b/src/core/services/qsysteminformationservice.cpp index f11e0c3d1..40f3594fb 100644 --- a/src/core/services/qsysteminformationservice.cpp +++ b/src/core/services/qsysteminformationservice.cpp @@ -40,10 +40,220 @@ #include "qsysteminformationservice_p.h" #include "qsysteminformationservice_p_p.h" +#ifdef Q_OS_ANDROID +#include <QtCore/QStandardPaths> +#endif + +#include <QtCore/QThreadPool> +#include <QtCore/QCoreApplication> +#include <QtCore/QFile> +#include <QtCore/QDateTime> +#include <QtCore/QCoreApplication> + +#include <Qt3DCore/QAspectEngine> +#include <Qt3DCore/QAbstractAspect> +#include <Qt3DCore/private/qaspectengine_p.h> +#include <Qt3DCore/private/aspectcommanddebugger_p.h> + QT_BEGIN_NAMESPACE +namespace { + +struct FrameHeader +{ + FrameHeader() + : frameId(0) + , jobCount(0) + , frameType(WorkerJob) + { + } + + enum FrameType { + WorkerJob = 0, + Submission + }; + + quint32 frameId; + quint16 jobCount; + quint16 frameType; // Submission or worker job +}; + +} namespace Qt3DCore { +QSystemInformationServicePrivate::QSystemInformationServicePrivate(QAspectEngine *aspectEngine, + const QString &description) + : QAbstractServiceProviderPrivate(QServiceLocator::SystemInformation, description) + , m_aspectEngine(aspectEngine) + , m_submissionStorage(nullptr) + , m_frameId(0) + , m_commandDebugger(nullptr) +{ + m_traceEnabled = qEnvironmentVariableIsSet("QT3D_TRACE_ENABLED"); + if (m_traceEnabled) + m_jobsStatTimer.start(); + + const bool commandServerEnabled = qEnvironmentVariableIsSet("QT3D_COMMAND_SERVER_ENABLED"); + if (commandServerEnabled) { + m_commandDebugger = new Debug::AspectCommandDebugger(q_func()); + m_commandDebugger->initialize(); + } +} + +QSystemInformationServicePrivate::~QSystemInformationServicePrivate() = default; + +QSystemInformationServicePrivate *QSystemInformationServicePrivate::get(QSystemInformationService *q) +{ + return q->d_func(); +} + +// Called by the jobs +void QSystemInformationServicePrivate::addJobLogStatsEntry(QSystemInformationServicePrivate::JobRunStats &stats) +{ + if (!m_traceEnabled) + return; + + if (!m_jobStatsCached.hasLocalData()) { + auto jobVector = new QVector<JobRunStats>; + m_jobStatsCached.setLocalData(jobVector); + QMutexLocker lock(&m_localStoragesMutex); + m_localStorages.push_back(jobVector); + } + m_jobStatsCached.localData()->push_back(stats); +} + +// Called from Submission thread (which can be main thread in Manual drive mode) +void QSystemInformationServicePrivate::addSubmissionLogStatsEntry(QSystemInformationServicePrivate::JobRunStats &stats) +{ + if (!m_traceEnabled) + return; + + QMutexLocker lock(&m_localStoragesMutex); + if (!m_jobStatsCached.hasLocalData()) { + m_submissionStorage = new QVector<JobRunStats>; + m_jobStatsCached.setLocalData(m_submissionStorage); + } + + // Handle the case where submission thread is also the main thread (Scene/Manual drive modes with no RenderThread) + if (m_submissionStorage == nullptr && m_jobStatsCached.hasLocalData()) + m_submissionStorage = new QVector<JobRunStats>; + + // When having no submission thread this can be null + m_submissionStorage->push_back(stats); +} + +// Called after jobs have been executed (MainThread QAspectJobManager::enqueueJobs) +void QSystemInformationServicePrivate::writeFrameJobLogStats() +{ + if (!m_traceEnabled) + return; + + using JobRunStats = QSystemInformationServicePrivate::JobRunStats; + + if (!m_traceFile) { + const QString fileName = QStringLiteral("trace_") + QCoreApplication::applicationName() + QDateTime::currentDateTime().toString(QStringLiteral("_ddd_dd_MM_yy-hh_mm_ss_"))+ QSysInfo::productType() + QStringLiteral("_") + QSysInfo::buildAbi() + QStringLiteral(".qt3d"); +#ifdef Q_OS_ANDROID + m_traceFile.reset(new QFile(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/") + fileName)); +#else + // TODO fix for iOS + m_traceFile.reset(new QFile(fileName)); +#endif + if (!m_traceFile->open(QFile::WriteOnly|QFile::Truncate)) + qCritical("Failed to open trace file"); + } + + // Write Aspect + Job threads + { + FrameHeader header; + header.frameId = m_frameId; + header.jobCount = 0; + + for (const QVector<JobRunStats> *storage : qAsConst(m_localStorages)) + header.jobCount += storage->size(); + + m_traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader)); + + for (QVector<JobRunStats> *storage : qAsConst(m_localStorages)) { + for (const JobRunStats &stat : *storage) + m_traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats)); + storage->clear(); + } + } + + // Write submission thread + { + QMutexLocker lock(&m_localStoragesMutex); + const int submissionJobSize = m_submissionStorage != nullptr ? m_submissionStorage->size() : 0; + if (submissionJobSize > 0) { + FrameHeader header; + header.frameId = m_frameId; + header.jobCount = submissionJobSize; + header.frameType = FrameHeader::Submission; + + m_traceFile->write(reinterpret_cast<char *>(&header), sizeof(FrameHeader)); + + for (const JobRunStats &stat : *m_submissionStorage) + m_traceFile->write(reinterpret_cast<const char *>(&stat), sizeof(JobRunStats)); + m_submissionStorage->clear(); + } + } + + m_traceFile->flush(); + ++m_frameId; +} + + +QTaskLogger::QTaskLogger(QSystemInformationService *service, const JobId &jobId, Type type) + : m_service(service && service->isTraceEnabled() ? service : nullptr) + , m_type(type) +{ + m_stats.jobId = jobId; + if (m_service) { + m_stats.startTime = QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed(); + m_stats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId()); + } +} + +QTaskLogger::QTaskLogger(QSystemInformationService *service, + const quint32 jobType, + const quint32 instance, + QTaskLogger::Type type) + : m_service(service && service->isTraceEnabled() ? service : nullptr) + , m_type(type) +{ + m_stats.jobId.typeAndInstance[0] = jobType; + m_stats.jobId.typeAndInstance[1] = instance; + if (m_service) { + m_stats.startTime = QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed(); + m_stats.threadId = reinterpret_cast<quint64>(QThread::currentThreadId()); + } +} + +QTaskLogger::~QTaskLogger() { + if (m_service) { + auto dservice = QSystemInformationServicePrivate::get(m_service); + if (m_stats.endTime == 0L) + m_stats.endTime = dservice->m_jobsStatTimer.nsecsElapsed(); + switch (m_type) { + case AspectJob: dservice->addJobLogStatsEntry(m_stats); break; + case Submission: dservice->addSubmissionLogStatsEntry(m_stats); break; + } + } +} + +void QTaskLogger::end(qint64 t) +{ + m_stats.endTime = t > 0 || !m_service ? t : QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed(); +} + +qint64 QTaskLogger::restart() +{ + if (m_service) + m_stats.startTime = QSystemInformationServicePrivate::get(m_service)->m_jobsStatTimer.nsecsElapsed(); + return m_stats.startTime; +} + + /* !\internal \class Qt3DCore::QSystemInformationService \inmodule Qt3DCore @@ -58,8 +268,14 @@ namespace Qt3DCore { the new service. This constructor is protected so only subclasses can instantiate a QSystemInformationService object. */ -QSystemInformationService::QSystemInformationService(const QString &description) - : QAbstractServiceProvider(*new QSystemInformationServicePrivate(description)) + +QSystemInformationService::QSystemInformationService(QAspectEngine *aspectEngine) + : QAbstractServiceProvider(*new QSystemInformationServicePrivate(aspectEngine, QLatin1String("Default System Information Service"))) +{ +} + +QSystemInformationService::QSystemInformationService(QAspectEngine *aspectEngine, const QString &description) + : QAbstractServiceProvider(*new QSystemInformationServicePrivate(aspectEngine, description)) { } @@ -71,19 +287,93 @@ QSystemInformationService::QSystemInformationService(QSystemInformationServicePr { } +bool QSystemInformationService::isTraceEnabled() const +{ + Q_D(const QSystemInformationService); + return d->m_traceEnabled; +} + +bool QSystemInformationService::isCommandServerEnabled() const +{ + Q_D(const QSystemInformationService); + return d->m_commandDebugger != nullptr; +} + +void QSystemInformationService::setTraceEnabled(bool traceEnabled) +{ + Q_D(QSystemInformationService); + if (d->m_traceEnabled != traceEnabled) { + d->m_traceEnabled = traceEnabled; + emit traceEnabledChanged(d->m_traceEnabled); + if (d->m_traceEnabled) { + if (!d->m_jobsStatTimer.isValid()) + d->m_jobsStatTimer.start(); + } else { + d->m_traceFile.reset(); + } + } +} + /* \fn QStringList Qt3DCore::QSystemInformationService::aspectNames() const - Subclasses should override this function and return a string list containing the - names of all registered aspects. + Returns a string list containing the names of all registered aspects. */ +QStringList QSystemInformationService::aspectNames() const +{ + Q_D(const QSystemInformationService); + if (!d->m_aspectEngine) + return {}; + + QStringList res; + const auto aspects = d->m_aspectEngine->aspects(); + if (aspects.isEmpty()) + return { QLatin1String("No loaded aspects") }; + + QAspectEnginePrivate *dengine = QAspectEnginePrivate::get(d->m_aspectEngine); + for (auto aspect: aspects) { + const QString name = dengine->m_factory.aspectName(aspect); + if (!name.isEmpty()) + res << name; + else + res << QLatin1String("<unnamed>"); + } + + return res; +} /* \fn int Qt3DCore::QSystemInformationService::threadPoolThreadCount() const - Subclasses should override this function and return the number of threads in the - Qt3D task manager's threadpool. + Returns the maximum number of threads in the Qt3D task manager's threadpool. */ +int QSystemInformationService::threadPoolThreadCount() const +{ + return QThreadPool::globalInstance()->maxThreadCount(); +} + +void QSystemInformationService::writePreviousFrameTraces() +{ + Q_D(QSystemInformationService); + d->writeFrameJobLogStats(); +} + +QVariant QSystemInformationService::executeCommand(const QString &command) +{ + Q_D(QSystemInformationService); + + if (command == QLatin1String("tracing on")) { + setTraceEnabled(true); + return {isTraceEnabled()}; + } + + if (command == QLatin1String("tracing off")) { + setTraceEnabled(false); + return {isTraceEnabled()}; + } + + return d->m_aspectEngine->executeCommand(command); +} } diff --git a/src/core/services/qsysteminformationservice_p.h b/src/core/services/qsysteminformationservice_p.h index a8a83701b..64e6c779e 100644 --- a/src/core/services/qsysteminformationservice_p.h +++ b/src/core/services/qsysteminformationservice_p.h @@ -61,16 +61,34 @@ QT_BEGIN_NAMESPACE namespace Qt3DCore { class QSystemInformationServicePrivate; +struct JobRunStats; class Q_3DCORESHARED_EXPORT QSystemInformationService : public QAbstractServiceProvider { Q_OBJECT + Q_PROPERTY(bool traceEnabled READ isTraceEnabled WRITE setTraceEnabled NOTIFY traceEnabledChanged) + Q_PROPERTY(bool commandServerEnabled READ isCommandServerEnabled CONSTANT) public: - virtual QStringList aspectNames() const = 0; - virtual int threadPoolThreadCount() const = 0; + QSystemInformationService(QAspectEngine *aspectEngine); + + bool isTraceEnabled() const; + bool isCommandServerEnabled() const; + + void setTraceEnabled(bool traceEnabled); + + QStringList aspectNames() const; + int threadPoolThreadCount() const; + + void writePreviousFrameTraces(); + + QVariant executeCommand(const QString &command); + +signals: + void traceEnabledChanged(bool traceEnabled); protected: - QSystemInformationService(const QString &description = QString()); + Q_DECLARE_PRIVATE(QSystemInformationService) + QSystemInformationService(QAspectEngine *aspectEngine, const QString &description); QSystemInformationService(QSystemInformationServicePrivate &dd); }; diff --git a/src/core/services/qsysteminformationservice_p_p.h b/src/core/services/qsysteminformationservice_p_p.h index e3ce9fe49..222f4e1af 100644 --- a/src/core/services/qsysteminformationservice_p_p.h +++ b/src/core/services/qsysteminformationservice_p_p.h @@ -51,21 +51,98 @@ // We mean it. // -#include <Qt3DCore/qt3dcore_global.h> +#include <QtCore/QThreadStorage> +#include <QtCore/QElapsedTimer> +#include <QtCore/QFile> +#include <QtCore/QMutex> +#include <Qt3DCore/qt3dcore_global.h> +#include <Qt3DCore/private/qt3dcore_global_p.h> #include <Qt3DCore/private/qabstractserviceprovider_p.h> #include <Qt3DCore/private/qservicelocator_p.h> +#include <Qt3DCore/private/qsysteminformationservice_p.h> QT_BEGIN_NAMESPACE namespace Qt3DCore { -class QSystemInformationServicePrivate : public QAbstractServiceProviderPrivate +namespace Debug { +class AspectCommandDebugger; +} // Debug + +union Q_3DCORE_PRIVATE_EXPORT JobId +{ + JobId() : id(0L) { } + JobId(quint32 t, quint32 i) { typeAndInstance[0] = t; typeAndInstance[1] = i; } + + quint32 typeAndInstance[2]; + quint64 id; +}; + +class Q_3DCORE_PRIVATE_EXPORT QSystemInformationServicePrivate : public QAbstractServiceProviderPrivate { public: - QSystemInformationServicePrivate(const QString &description) - : QAbstractServiceProviderPrivate(QServiceLocator::SystemInformation, description) - {} + struct JobRunStats + { + JobRunStats() { jobId.id = 0; startTime = 0L; endTime = 0L; } + + qint64 startTime; + qint64 endTime; + JobId jobId; // QAspectJob subclasses should properly populate the jobId + quint64 threadId; + }; + + QSystemInformationServicePrivate(QAspectEngine *aspectEngine, const QString &description); + ~QSystemInformationServicePrivate(); + + static QSystemInformationServicePrivate *get(QSystemInformationService *q); + + // Aspects + Job threads + void addJobLogStatsEntry(JobRunStats &stats); + + // Submission thread + void addSubmissionLogStatsEntry(JobRunStats &stats); + + void writeFrameJobLogStats(); + + QAspectEngine *m_aspectEngine; + bool m_traceEnabled; + + QElapsedTimer m_jobsStatTimer; + QThreadStorage<QVector<JobRunStats> *> m_jobStatsCached; + + QVector<QVector<JobRunStats> *> m_localStorages; + QVector<JobRunStats> *m_submissionStorage; + + QMutex m_localStoragesMutex; + + QScopedPointer<QFile> m_traceFile; + quint32 m_frameId; + + Debug::AspectCommandDebugger *m_commandDebugger; + + Q_DECLARE_PUBLIC(QSystemInformationService) +}; + +class Q_3DCORE_PRIVATE_EXPORT QTaskLogger { +public: + enum Type { + AspectJob, + Submission + }; + + QTaskLogger(QSystemInformationService *service, const JobId &jobId, Type type); + QTaskLogger(QSystemInformationService *service, const quint32 jobType, const quint32 instance, Type type = Submission); + + ~QTaskLogger(); + + void end(qint64 t = 0L); + qint64 restart(); + +private: + QSystemInformationService *m_service; + QSystemInformationServicePrivate::JobRunStats m_stats; + Type m_type; }; } diff --git a/src/core/transforms/qabstractskeleton.cpp b/src/core/transforms/qabstractskeleton.cpp index 5f3b05eb8..4a30d0710 100644 --- a/src/core/transforms/qabstractskeleton.cpp +++ b/src/core/transforms/qabstractskeleton.cpp @@ -39,7 +39,6 @@ #include "qabstractskeleton.h" #include "qabstractskeleton_p.h" -#include <Qt3DCore/qpropertyupdatedchange.h> QT_BEGIN_NAMESPACE @@ -47,6 +46,7 @@ namespace Qt3DCore { QAbstractSkeletonPrivate::QAbstractSkeletonPrivate() : Qt3DCore::QNodePrivate() + , m_type(QSkeletonCreatedChangeBase::Skeleton) , m_jointCount(0) { } @@ -105,6 +105,13 @@ QAbstractSkeleton::~QAbstractSkeleton() { } +/*! \internal */ +void QAbstractSkeleton::sceneChangeEvent(const QSceneChangePtr &change) +{ + // TODO Unused remove in Qt6 + Q_UNUSED(change) +} + /*! \property Qt3DCore::QAbstractSkeleton::jointCount @@ -127,16 +134,6 @@ void QAbstractSkeletonPrivate::setJointCount(int jointCount) q->blockNotifications(block); } -void QAbstractSkeleton::sceneChangeEvent(const QSceneChangePtr &change) -{ - Q_D(QAbstractSkeleton); - if (change->type() == Qt3DCore::PropertyUpdated) { - const Qt3DCore::QPropertyUpdatedChangePtr e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); - if (e->propertyName() == QByteArrayLiteral("jointCount")) - d->setJointCount(e->value().toInt()); - } -} - } // namespace Qt3DCore QT_END_NAMESPACE diff --git a/src/core/transforms/qabstractskeleton.h b/src/core/transforms/qabstractskeleton.h index 902def9f8..1c2eba08f 100644 --- a/src/core/transforms/qabstractskeleton.h +++ b/src/core/transforms/qabstractskeleton.h @@ -64,7 +64,8 @@ Q_SIGNALS: protected: QAbstractSkeleton(QAbstractSkeletonPrivate &dd, Qt3DCore::QNode *parent = nullptr); - void sceneChangeEvent(const QSceneChangePtr &change) override; + // TODO Unused remove in Qt6 + void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: Q_DECLARE_PRIVATE(QAbstractSkeleton) diff --git a/src/core/transforms/qskeletonloader.cpp b/src/core/transforms/qskeletonloader.cpp index d5296ecc9..b1a311a0c 100644 --- a/src/core/transforms/qskeletonloader.cpp +++ b/src/core/transforms/qskeletonloader.cpp @@ -68,6 +68,27 @@ void QSkeletonLoaderPrivate::setStatus(QSkeletonLoader::Status status) } } +void QSkeletonLoaderPrivate::setRootJoint(QJoint *rootJoint) +{ + Q_Q(QSkeletonLoader); + if (rootJoint == m_rootJoint) + return; + + if (m_rootJoint) + unregisterDestructionHelper(m_rootJoint); + + if (rootJoint && !rootJoint->parent()) + rootJoint->setParent(q); + + m_rootJoint = rootJoint; + + // Ensures proper bookkeeping + if (m_rootJoint) + registerPrivateDestructionHelper(m_rootJoint, &QSkeletonLoaderPrivate::setRootJoint); + + emit q->rootJointChanged(m_rootJoint); +} + /*! \qmltype SkeletonLoader \inqmlmodule Qt3D.Core @@ -217,39 +238,12 @@ void QSkeletonLoader::setCreateJointsEnabled(bool createJoints) void QSkeletonLoader::setRootJoint(QJoint *rootJoint) { Q_D(QSkeletonLoader); - if (rootJoint == d->m_rootJoint) - return; - - if (d->m_rootJoint) - d->unregisterDestructionHelper(d->m_rootJoint); - - if (rootJoint && !rootJoint->parent()) - rootJoint->setParent(this); - - d->m_rootJoint = rootJoint; - - // Ensures proper bookkeeping - if (d->m_rootJoint) - d->registerDestructionHelper(d->m_rootJoint, &QSkeletonLoader::setRootJoint, d->m_rootJoint); - - emit rootJointChanged(d->m_rootJoint); + d->setRootJoint(rootJoint); } /*! \internal */ void QSkeletonLoader::sceneChangeEvent(const QSceneChangePtr &change) { - Q_D(QSkeletonLoader); - if (change->type() == Qt3DCore::PropertyUpdated) { - auto propertyChange = qSharedPointerCast<QStaticPropertyUpdatedChangeBase>(change); - if (propertyChange->propertyName() == QByteArrayLiteral("status")) { - const auto e = qSharedPointerCast<Qt3DCore::QPropertyUpdatedChange>(change); - d->setStatus(static_cast<QSkeletonLoader::Status>(e->value().toInt())); - } else if (propertyChange->propertyName() == QByteArrayLiteral("rootJoint")) { - auto typedChange = qSharedPointerCast<QJointChange>(propertyChange); - auto rootJoint = std::move(typedChange->data); - setRootJoint(rootJoint.release()); - } - } QAbstractSkeleton::sceneChangeEvent(change); } diff --git a/src/core/transforms/qskeletonloader_p.h b/src/core/transforms/qskeletonloader_p.h index 5c415745b..6bd4e1eef 100644 --- a/src/core/transforms/qskeletonloader_p.h +++ b/src/core/transforms/qskeletonloader_p.h @@ -70,6 +70,7 @@ public: QSkeletonLoaderPrivate(); void setStatus(QSkeletonLoader::Status status); + void setRootJoint(QJoint *rootJoint); Q_DECLARE_PUBLIC(QSkeletonLoader) diff --git a/src/core/transforms/qtransform.cpp b/src/core/transforms/qtransform.cpp index e5902f11f..d41b87f79 100644 --- a/src/core/transforms/qtransform.cpp +++ b/src/core/transforms/qtransform.cpp @@ -237,6 +237,7 @@ QTransform::QTransform(QTransformPrivate &dd, QNode *parent) /*! \internal */ +// TODO Unused remove in Qt6 void QTransform::sceneChangeEvent(const QSceneChangePtr &change) { Q_D(QTransform); diff --git a/src/core/transforms/qtransform.h b/src/core/transforms/qtransform.h index 503ea4d4a..ce6bf42fa 100644 --- a/src/core/transforms/qtransform.h +++ b/src/core/transforms/qtransform.h @@ -119,6 +119,7 @@ Q_SIGNALS: protected: explicit QTransform(QTransformPrivate &dd, QNode *parent = nullptr); + // TODO Unused remove in Qt6 void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; private: diff --git a/src/core/transforms/sqt_p.h b/src/core/transforms/sqt_p.h index 5fdefccc8..e602cc71e 100644 --- a/src/core/transforms/sqt_p.h +++ b/src/core/transforms/sqt_p.h @@ -71,7 +71,9 @@ struct Sqt Sqt() : rotation() , scale(1.0f, 1.0f, 1.0f) + , pad1(0.f) , translation() + , pad2(0.f) {} inline QMatrix4x4 toMatrix() const |