/**************************************************************************** ** ** Copyright (C) 2017 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of Qt 3D Studio. ** ** $QT_BEGIN_LICENSE:GPL$ ** 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 General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) 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.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-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef Q3DSPROFILER_P_H #define Q3DSPROFILER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists for the convenience // of a number of Qt sources files. This header file may change from // version to version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include #if defined(Q_OS_MACOS) #include "q3dsprofilerhelper_mac_p.h" #endif QT_BEGIN_NAMESPACE class Q3DSSceneManager; class Q3DSUipPresentation; class Q3DSMesh; struct Q3DSRenderLoopStats; namespace Qt3DCore { class QEntity; } namespace Qt3DRender { class QFrameGraphNode; } class Q3DSProfiler { public: Q3DSProfiler(); ~Q3DSProfiler(); void resetForNewScene(Q3DSSceneManager *sceneManager); bool isEnabled() const { return m_enabled; } void setEnabled(bool enabled); void reportNewFrame(float deltaMs, const Q3DSRenderLoopStats *rlStats = nullptr); void updateFrameStats(qint64 globalFrameCounter); enum ObjectType { UnknownObject, RenderTargetObject, Texture2DObject, TextureCubeObject, MeshObject, ShaderProgramObject }; void trackNewObject(QObject *obj, ObjectType type, const QByteArray &id, const char *info, ...); void vtrackNewObject(QObject *obj, ObjectType type, const QByteArray &id, const char *info, va_list args); void updateObjectInfo(QObject *obj, ObjectType type, const QByteArray &id, const char *info, ...); struct FrameData { float deltaMs = 0; float quickDeltaMs = 0; bool usedDedicatedQuickRenderThread = false; bool usedDefaultQt3DRenderAspectWithOwnRenderThread = false; qint64 globalFrameCounter = 0; bool wasDirty = false; }; const QVector *frameData() const { return &m_frameData; } struct ObjectData { ObjectData() { } ObjectData(QObject *obj_, ObjectType type_, const QByteArray &id_) : obj(obj_), type(type_), id(id_) { } QObject *obj = nullptr; ObjectType type = UnknownObject; QByteArray id; QString info; }; const QMultiMap *objectData() const { return &m_objectData; } void reportTotalParseBuildTime(qint64 ms); qint64 totalParseBuildTime() const { return m_totalParseBuildTime; } void reportBehaviorStats(qint64 loadTimeMs, int loadCount); qint64 behaviorLoadTime() const { return m_behaviorLoadTime; } int behaviorActiveCount() const { return m_behaviorActiveCount; } void reportTimeAfterBuildUntilFirstFrameAction(qint64 ms); qint64 timeAfterBuildUntilFirstFrameAction() const { return m_firstFrameActionTime; } struct SubMeshData { bool needsBlending = false; }; void reportSubMeshData(Q3DSMesh *mesh, const SubMeshData &data); SubMeshData subMeshData(Q3DSMesh *mesh) const { return m_subMeshData.value(mesh); } void registerSubPresentationProfiler(Q3DSProfiler *p); const QVector *subPresentationProfilers() const { return &m_subPresProfilers; } Q3DSProfiler *mainPresentationProfiler(); void reportQt3DSceneGraphRoot(Qt3DCore::QEntity *rootEntity); // there can be multiple ones QVector qt3dSceneGraphRoots() const { return m_qt3dSceneGraphRoots; } void reportFrameGraphRoot(Qt3DRender::QFrameGraphNode *fgNode); void reportFrameGraphStopNode(Qt3DRender::QFrameGraphNode *fgNode); Qt3DRender::QFrameGraphNode *frameGraphRoot() const { return m_frameGraphRoot; } QSet frameGraphStopNodes() const { return m_fgStopNodes; } const Q3DSUipPresentation *presentation() const { return m_presentation; } Q3DSUipPresentation *presentation() { return m_presentation; } QString presentationName() const { return m_presentationName; } // note that we do not expose the scene manager to the profile ui. instead, // such data is expected to be mediated through the profiler object. QStringList log() const { return m_log; } bool hasLogChanged(); void clearLog(); void addLog(const QString &msg); void sendDataInputValueChange(const QString &dataInputName, const QVariant &value); void setLayerCaching(bool enabled); float cpuLoadForCurrentProcess(); QPair memUsageForCurrentProcess(); private: #if defined(Q_OS_MACOS) qint64 timeValToMicroseconds(const struct timeval& timeVal); #endif bool m_enabled = false; // disabled by default, profiling is opt-in QVector m_frameData; QMultiMap m_objectData; QVector m_objectDestroyConnections; Q3DSSceneManager *m_sceneManager = nullptr; Q3DSUipPresentation *m_presentation = nullptr; QString m_presentationName; qint64 m_totalParseBuildTime = 0; qint64 m_behaviorLoadTime = 0; int m_behaviorActiveCount = 0; qint64 m_firstFrameActionTime = 0; QHash m_subMeshData; QVector m_subPresProfilers; QStringList m_log; bool m_logChanged = false; Q3DSProfiler *m_mainProfiler = nullptr; QVector m_qt3dSceneGraphRoots; Qt3DRender::QFrameGraphNode *m_frameGraphRoot = nullptr; QSet m_fgStopNodes; QElapsedTimer m_cpuLoadTimer; float m_lastCpuLoad = 0; QElapsedTimer m_memUsageTimer; QPair m_lastMemUsage; #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) quint64 m_lastKernelTimeSys = 0; quint64 m_lastUserTimeSys = 0; quint64 m_lastKernelTimeProc = 0; quint64 m_lastUserTimeProc = 0; #elif defined(Q_OS_LINUX) int m_numCpus = 0; qint64 m_lastTimestamp = 0; qint64 m_lastKernel = 0; qint64 m_lastUser = 0; #elif defined(Q_OS_MACOS) qint64 m_lastTimestamp = 0; qint64 m_lastTaskTime = 0; Q3DSProfilerHelperMacOS m_macOSProfiler; #endif }; Q_DECLARE_TYPEINFO(Q3DSProfiler::FrameData, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(Q3DSProfiler::ObjectData, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(Q3DSProfiler::SubMeshData, Q_MOVABLE_TYPE); inline bool operator==(const Q3DSProfiler::ObjectData &lhs, const Q3DSProfiler::ObjectData &rhs) Q_DECL_NOTHROW { return lhs.type == rhs.type && lhs.obj == rhs.obj; } inline bool operator!=(const Q3DSProfiler::ObjectData &lhs, const Q3DSProfiler::ObjectData &rhs) Q_DECL_NOTHROW { return !(lhs == rhs); } QT_END_NAMESPACE #endif // Q3DSPROFILER_P_H