From e37f1d3d6b40155733c0661a73dea98f063545bc Mon Sep 17 00:00:00 2001 From: Janne Koskinen Date: Thu, 9 Dec 2021 21:12:00 +0200 Subject: [PATCH] Add Quick3d profiler support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for quick3d profiling Task-number: QTBUG-98146 Change-Id: Ida84537df685e8bddc536158519600d722a23d2e Reviewed-by: Reviewed-by: Miikka Heikkinen Reviewed-by: Tomi Korpipää Reviewed-by: Alessandro Portale Reviewed-by: Qt CI Bot --- src/plugins/qmlprofiler/CMakeLists.txt | 1 + src/plugins/qmlprofiler/qmleventtype.cpp | 2 + .../qmlprofiler/qmlprofilereventtypes.h | 17 +++ .../qmlprofiler/qmlprofilermodelmanager.cpp | 3 +- .../qmlprofiler/qmlprofilertracefile.cpp | 3 +- .../qmlprofiler/qmlprofilertraceview.cpp | 2 + src/plugins/qmlprofiler/qmltypedevent.cpp | 13 ++ src/plugins/qmlprofiler/quick3dmodel.cpp | 144 ++++++++++++++++++ src/plugins/qmlprofiler/quick3dmodel.h | 79 ++++++++++ .../qmlprofiler/tests/qmleventtype_test.cpp | 5 +- 10 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 src/plugins/qmlprofiler/quick3dmodel.cpp create mode 100644 src/plugins/qmlprofiler/quick3dmodel.h diff --git a/src/plugins/qmlprofiler/CMakeLists.txt b/src/plugins/qmlprofiler/CMakeLists.txt index f1b5979670b..2646774bae1 100644 --- a/src/plugins/qmlprofiler/CMakeLists.txt +++ b/src/plugins/qmlprofiler/CMakeLists.txt @@ -67,6 +67,7 @@ set(QMLPROFILER_CPP_SOURCES qmlprofilerviewmanager.cpp qmlprofilerviewmanager.h qmltypedevent.cpp qmltypedevent.h scenegraphtimelinemodel.cpp scenegraphtimelinemodel.h + quick3dmodel.cpp quick3dmodel.h ) if(${Qt5_VERSION} VERSION_LESS "6.2.0") diff --git a/src/plugins/qmlprofiler/qmleventtype.cpp b/src/plugins/qmlprofiler/qmleventtype.cpp index 67daa5a47a1..4963b684959 100644 --- a/src/plugins/qmlprofiler/qmleventtype.cpp +++ b/src/plugins/qmlprofiler/qmleventtype.cpp @@ -50,6 +50,8 @@ static ProfileFeature qmlFeatureFromType(Message message, RangeType rangeType, i return ProfileMemory; case DebugMessage: return ProfileDebugMessages; + case Quick3DEvent: + return ProfileQuick3D; default: return featureFromRangeType(rangeType); } diff --git a/src/plugins/qmlprofiler/qmlprofilereventtypes.h b/src/plugins/qmlprofiler/qmlprofilereventtypes.h index 1ca5ccc3d9c..0c4d92c07ab 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventtypes.h +++ b/src/plugins/qmlprofiler/qmlprofilereventtypes.h @@ -40,6 +40,7 @@ enum Message { SceneGraphFrame, MemoryAllocation, DebugMessage, + Quick3DEvent, MaximumMessage }; @@ -55,6 +56,21 @@ enum EventType { MaximumEventType }; +enum Quick3DEventType { + Quick3DRenderFrame, + Quick3DSynchronizeFrame, + Quick3DPrepareFrame, + Quick3DMeshLoad, + Quick3DCustomMeshLoad, + Quick3DTextureLoad, + Quick3DParticleUpdate, + Quick3DGenerateShader, + Quick3DLoadShader, + MaximumQuick3DFrameType, + NumQuick3DRenderThreadFrameTypes = Quick3DParticleUpdate, + NumQuick3DGUIThreadFrameTypes = MaximumQuick3DFrameType - NumQuick3DRenderThreadFrameTypes, +}; + enum RangeType { Painting, // old Qt4 paint events Compiling, @@ -144,6 +160,7 @@ enum ProfileFeature { ProfileHandlingSignal, ProfileInputEvents, ProfileDebugMessages, + ProfileQuick3D, MaximumProfileFeature }; diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index bfb5f1f0cf7..a17de09d2dc 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -56,7 +56,8 @@ static const char *ProfileFeatureNames[] = { QT_TRANSLATE_NOOP("MainView", "Binding"), QT_TRANSLATE_NOOP("MainView", "Handling Signal"), QT_TRANSLATE_NOOP("MainView", "Input Events"), - QT_TRANSLATE_NOOP("MainView", "Debug Messages") + QT_TRANSLATE_NOOP("MainView", "Debug Messages"), + QT_TRANSLATE_NOOP("MainView", "Quick3D") }; Q_STATIC_ASSERT(sizeof(ProfileFeatureNames) == sizeof(char *) * MaximumProfileFeature); diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp index e2531e9fe81..7d5ecfaa25f 100644 --- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp @@ -66,7 +66,8 @@ static const char *MESSAGE_STRINGS[] = { "PixmapCache", "SceneGraph", "MemoryAllocation", - "DebugMessage" + "DebugMessage", + "Quick3D" }; Q_STATIC_ASSERT(sizeof(MESSAGE_STRINGS) == MaximumMessage * sizeof(const char *)); diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index 4e40644c6f2..939254620ad 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp @@ -32,6 +32,7 @@ #include "qmlprofilerrangemodel.h" #include "qmlprofilerplugin.h" +#include "quick3dmodel.h" #include "inputeventsmodel.h" #include "pixmapcachemodel.h" #include "debugmessagesmodel.h" @@ -155,6 +156,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag models.append(QVariant::fromValue(new MemoryUsageModel(modelManager, d->m_modelProxy))); models.append(QVariant::fromValue(new InputEventsModel(modelManager, d->m_modelProxy))); models.append(QVariant::fromValue(new DebugMessagesModel(modelManager, d->m_modelProxy))); + models.append(QVariant::fromValue(new Quick3DModel(modelManager, d->m_modelProxy))); models.append(QVariant::fromValue(new QmlProfilerAnimationsModel(modelManager, d->m_modelProxy))); for (int i = 0; i < MaximumRangeType; ++i) { diff --git a/src/plugins/qmlprofiler/qmltypedevent.cpp b/src/plugins/qmlprofiler/qmltypedevent.cpp index 5eec5d082b6..dade47c6dbd 100644 --- a/src/plugins/qmlprofiler/qmltypedevent.cpp +++ b/src/plugins/qmlprofiler/qmltypedevent.cpp @@ -183,6 +183,19 @@ QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event) event.event.setRangeStage(RangeEnd); break; } + case Quick3DEvent: { + + QVarLengthArray params; + qint64 param; + + while (!stream.atEnd()) { + stream >> param; + params.push_back(param); + } + event.type = QmlEventType(static_cast(messageType), MaximumRangeType, subtype); + event.event.setNumbers, qint64>(params); + break; + } default: event.event.setNumbers({}); event.type = QmlEventType(static_cast(messageType), MaximumRangeType, subtype); diff --git a/src/plugins/qmlprofiler/quick3dmodel.cpp b/src/plugins/qmlprofiler/quick3dmodel.cpp new file mode 100644 index 00000000000..fd2b5959dfe --- /dev/null +++ b/src/plugins/qmlprofiler/quick3dmodel.cpp @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** 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 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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. +** +****************************************************************************/ + +#include "quick3dmodel.h" +#include "qmlprofilerconstants.h" +#include + + +namespace QmlProfiler { +namespace Internal { + +Quick3DModel::Quick3DModel(QmlProfilerModelManager *manager, + Timeline::TimelineModelAggregator *parent) : + QmlProfilerTimelineModel(manager, Quick3DEvent, MaximumRangeType, ProfileQuick3D, parent), + m_maximumMsgType(-1) +{ +} + +int Quick3DModel::typeId(int index) const +{ + return m_data[index].typeId; +} + +QRgb Quick3DModel::color(int index) const +{ + return colorBySelectionId(index); +} + +static const char *messageTypes[] = { + QT_TRANSLATE_NOOP("Quick3DModel", "Render Frame"), + QT_TRANSLATE_NOOP("Quick3DModel", "Synchronize Frame"), + QT_TRANSLATE_NOOP("Quick3DModel", "Prepare Frame"), + QT_TRANSLATE_NOOP("Quick3DModel", "Mesh Load"), + QT_TRANSLATE_NOOP("Quick3DModel", "Custom Mesh Load"), + QT_TRANSLATE_NOOP("Quick3DModel", "Texture Load"), + QT_TRANSLATE_NOOP("Quick3DModel", "Generate Shader"), + QT_TRANSLATE_NOOP("Quick3DModel", "Load Shader"), + QT_TRANSLATE_NOOP("Quick3DModel", "Particle Update"), +}; + +QString Quick3DModel::messageType(uint i) +{ + return i < sizeof(messageTypes) / sizeof(char *) ? tr(messageTypes[i]) : + tr("Unknown Message %1").arg(i); +} + +QVariantList Quick3DModel::labels() const +{ + QVariantList result; + for (int i = 0; i <= m_maximumMsgType; ++i) { + QVariantMap element; + element.insert(QLatin1String("displayName"), i < ParticleUpdate ? tr("Render Thread") : tr("GUI Thread")); + element.insert(QLatin1String("description"), messageType(i)); + element.insert(QLatin1String("id"), i); + result << element; + } + return result; +} + +QVariantMap Quick3DModel::details(int index) const +{ + const QmlProfilerModelManager *manager = modelManager(); + const QmlEventType &type = manager->eventType(m_data[index].typeId); + + QVariantMap result; + result.insert(QLatin1String("displayName"), type.detailType() < ParticleUpdate ? tr("Render Thread") : tr("GUI Thread")); + result.insert(tr("Description"), messageType(type.detailType())); + result.insert(tr("Duration"), Timeline::formatTime(duration(index))); + if (type.detailType() == ParticleUpdate) + result.insert(tr("Count"), m_data[index].data); + return result; +} + +int Quick3DModel::expandedRow(int index) const +{ + return selectionId(index) + 1; +} + +int Quick3DModel::collapsedRow(int index) const +{ + Q_UNUSED(index) + return Constants::QML_MIN_LEVEL; +} + +void Quick3DModel::loadEvent(const QmlEvent &event, const QmlEventType &type) +{ + qint64 eventDuration = event.number(0); + qint64 startTime = event.timestamp() - eventDuration; + if (type.detailType() == MessageType::ParticleUpdate) { + quint64 particleCount = event.number(1); + m_data.insert(insert(startTime, eventDuration, type.detailType()), + Item(event.typeIndex(), particleCount)); + } else { + m_data.insert(insert(startTime, eventDuration, type.detailType()), + Item(event.typeIndex(), 0)); + } + + if (type.detailType() > m_maximumMsgType) + m_maximumMsgType = type.detailType(); +} + +void Quick3DModel::finalize() +{ + setCollapsedRowCount(Constants::QML_MIN_LEVEL + 1); + setExpandedRowCount(m_maximumMsgType + 2); + QmlProfilerTimelineModel::finalize(); +} + +void Quick3DModel::clear() +{ + m_data.clear(); + m_maximumMsgType = -1; + QmlProfilerTimelineModel::clear(); +} + +QVariantMap Quick3DModel::location(int index) const +{ + return locationFromTypeId(index); +} + +} // namespace Internal +} // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/quick3dmodel.h b/src/plugins/qmlprofiler/quick3dmodel.h new file mode 100644 index 00000000000..50bcebcb732 --- /dev/null +++ b/src/plugins/qmlprofiler/quick3dmodel.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2022 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** 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 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** 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. +** +****************************************************************************/ + +#pragma once + +#include "qmlprofilertimelinemodel.h" + +namespace QmlProfiler { +namespace Internal { + +class Quick3DModel : public QmlProfilerTimelineModel +{ + Q_OBJECT + +public: + struct Item { + Item(int typeId, int data) : + typeId(typeId), data(data) {} + int typeId; + int data; + }; + + enum MessageType + { + RenderFrame, + SynchronizeFrame, + PrepareFrame, + MeshLoad, + CustomMeshLoad, + TextureLoad, + GenerateShader, + LoadShader, + ParticleUpdate, + }; + + Quick3DModel(QmlProfilerModelManager *manager, Timeline::TimelineModelAggregator *parent); + + int typeId(int index) const override; + QRgb color(int index) const override; + QVariantList labels() const override; + QVariantMap details(int index) const override; + int expandedRow(int index) const override; + int collapsedRow(int index) const override; + void loadEvent(const QmlEvent &event, const QmlEventType &type) override; + void finalize() override; + void clear() override; + QVariantMap location(int index) const override; + +private: + static QString messageType(uint i); + + int m_maximumMsgType; + QVector m_data; +}; + +} // namespace Internal +} // namespace Qmlprofiler diff --git a/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp b/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp index 366298c6f4d..30157c7c7fd 100644 --- a/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp +++ b/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp @@ -99,7 +99,10 @@ void QmlEventTypeTest::testFeature() ProfileMemory, ProfileMemory, ProfileMemory}, // DebugMessage {ProfileDebugMessages, ProfileDebugMessages, ProfileDebugMessages, - ProfileDebugMessages, ProfileDebugMessages, ProfileDebugMessages} + ProfileDebugMessages, ProfileDebugMessages, ProfileDebugMessages}, + // ProfileQuick3D + {ProfileQuick3D, ProfileQuick3D, ProfileQuick3D, + ProfileQuick3D, ProfileQuick3D, ProfileQuick3D} }; for (int i = 0; i < MaximumMessage; ++i) {