diff --git a/src/plugins/qmlprofiler/quick3dmodel.cpp b/src/plugins/qmlprofiler/quick3dmodel.cpp index fd2b5959dfe..ac8f42d5338 100644 --- a/src/plugins/qmlprofiler/quick3dmodel.cpp +++ b/src/plugins/qmlprofiler/quick3dmodel.cpp @@ -38,11 +38,6 @@ Quick3DModel::Quick3DModel(QmlProfilerModelManager *manager, { } -int Quick3DModel::typeId(int index) const -{ - return m_data[index].typeId; -} - QRgb Quick3DModel::color(int index) const { return colorBySelectionId(index); @@ -58,6 +53,15 @@ static const char *messageTypes[] = { QT_TRANSLATE_NOOP("Quick3DModel", "Generate Shader"), QT_TRANSLATE_NOOP("Quick3DModel", "Load Shader"), QT_TRANSLATE_NOOP("Quick3DModel", "Particle Update"), + + QT_TRANSLATE_NOOP("Quick3DModel", "Mesh Memory consumption"), + QT_TRANSLATE_NOOP("Quick3DModel", "Texture Memory consumption"), +}; + +static const char *unloadMessageTypes[] = { + QT_TRANSLATE_NOOP("Quick3DModel", "Mesh Unload"), + QT_TRANSLATE_NOOP("Quick3DModel", "Custom Mesh Unload"), + QT_TRANSLATE_NOOP("Quick3DModel", "Texture Unload"), }; QString Quick3DModel::messageType(uint i) @@ -66,12 +70,26 @@ QString Quick3DModel::messageType(uint i) tr("Unknown Message %1").arg(i); } +QString Quick3DModel::unloadMessageType(uint i) +{ + switch (i) { + case MeshLoad: + return tr(unloadMessageTypes[0]); + case CustomMeshLoad: + return tr(unloadMessageTypes[1]); + case TextureLoad: + return tr(unloadMessageTypes[2]); + } + return tr("Unknown Unload 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("displayName"), + i != ParticleUpdate ? tr("Render Thread") : tr("GUI Thread")); element.insert(QLatin1String("description"), messageType(i)); element.insert(QLatin1String("id"), i); result << element; @@ -79,17 +97,49 @@ QVariantList Quick3DModel::labels() const return result; } +float Quick3DModel::relativeHeight(int index) const +{ + auto detailType = m_data[index].additionalType; + if (detailType == TextureMemoryConsumption) + return qMin(1.0f, (float)m_data[index].data / (float)m_maxTextureSize); + if (detailType == MeshMemoryConsumption) + return qMin(1.0f, (float)m_data[index].data / (float)m_maxMeshSize); + return 1.0f; +} + +qint64 Quick3DModel::rowMaxValue(int rowNumber) const +{ + int index = rowNumber - 1; + if (index == TextureMemoryConsumption) + return m_maxTextureSize; + if (index == MeshMemoryConsumption) + return m_maxMeshSize; + return 0; +} + QVariantMap Quick3DModel::details(int index) const { - const QmlProfilerModelManager *manager = modelManager(); - const QmlEventType &type = manager->eventType(m_data[index].typeId); - + auto detailType = m_data[index].additionalType; + bool unload = m_data[index].unload; 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(QLatin1String("displayName"), + detailType != ParticleUpdate ? tr("Render Thread") : tr("GUI Thread")); + result.insert(tr("Description"), + !unload ? messageType(detailType) : unloadMessageType(detailType)); + if (detailType < MeshMemoryConsumption) + result.insert(tr("Duration"), Timeline::formatTime(duration(index))); + if (detailType == ParticleUpdate) result.insert(tr("Count"), m_data[index].data); + if (detailType == RenderFrame) { + quint32 calls = m_data[index].data & 0xffffffff; + quint32 passes = m_data[index].data >> 32; + result.insert(tr("Draw Calls"), calls); + result.insert(tr("Render Passes"), passes); + } + if ((detailType >= MeshLoad && detailType <= TextureLoad) + || (detailType >= MeshMemoryConsumption && detailType <= TextureMemoryConsumption)) { + result.insert(tr("Total Memory Usage"), m_data[index].data); + } return result; } @@ -106,23 +156,80 @@ int Quick3DModel::collapsedRow(int index) const void Quick3DModel::loadEvent(const QmlEvent &event, const QmlEventType &type) { + auto detailType = type.detailType(); 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)); - } + qint64 eventTime = event.timestamp() - eventDuration; + QVector numbers = event.numbers>(); + quint64 data = numbers.size() > 1 ? event.number(1) : 0; - if (type.detailType() > m_maximumMsgType) - m_maximumMsgType = type.detailType(); + int typeCount = detailType; + if (detailType == MeshLoad || detailType == CustomMeshLoad) { + bool updatePrevValues = true; + if (m_prevMeshStartTime != -1) { + bool unload = m_prevMeshData > data; + m_data.insert(insert(eventTime, eventDuration, detailType), + Item(detailType, data, unload)); + if (m_prevMeshData != data) { + m_data.insert(insert(m_prevMeshStartTime, + eventTime - m_prevMeshStartTime, MeshMemoryConsumption), + Item(MeshMemoryConsumption, m_prevMeshData)); + } else { + updatePrevValues = false; + } + } else { + m_data.insert(insert(eventTime, eventDuration, detailType), + Item(detailType, data)); + } + m_maxMeshSize = qMax(m_maxMeshSize, data); + if (updatePrevValues) { + m_prevMeshStartTime = eventTime; + m_prevMeshData = data; + } + typeCount = MeshMemoryConsumption; + } else if (detailType == TextureLoad) { + bool updatePrevValues = true; + if (m_prevTexStartTime != -1) { + bool unload = m_prevTexData > data; + m_data.insert(insert(eventTime, eventDuration, detailType), + Item(detailType, data, unload)); + if (m_prevTexData != data) { + m_data.insert(insert(m_prevTexStartTime, + eventTime - m_prevTexStartTime, TextureMemoryConsumption), + Item(TextureMemoryConsumption, m_prevTexData)); + } else { + updatePrevValues = false; + } + } else { + m_data.insert(insert(eventTime, eventDuration, detailType), + Item(detailType, data)); + } + m_maxTextureSize = qMax(m_maxTextureSize, data); + if (updatePrevValues) { + m_prevTexData = data; + m_prevTexStartTime = eventTime; + } + typeCount = TextureMemoryConsumption; + } else { + m_data.insert(insert(eventTime, eventDuration, detailType), + Item(detailType, data)); + } + if (typeCount > m_maximumMsgType) + m_maximumMsgType = typeCount; } void Quick3DModel::finalize() { + if (m_prevMeshStartTime != -1) { + m_data.insert(insert(m_prevMeshStartTime, modelManager()->traceEnd() - m_prevMeshStartTime, + MeshMemoryConsumption), + Item(MeshMemoryConsumption, m_prevMeshData)); + } + if (m_prevTexStartTime != -1) { + m_data.insert(insert(m_prevTexStartTime, modelManager()->traceEnd() - m_prevTexStartTime, + TextureMemoryConsumption), + Item(TextureMemoryConsumption, m_prevTexData)); + } + computeNesting(); setCollapsedRowCount(Constants::QML_MIN_LEVEL + 1); setExpandedRowCount(m_maximumMsgType + 2); QmlProfilerTimelineModel::finalize(); @@ -132,6 +239,10 @@ void Quick3DModel::clear() { m_data.clear(); m_maximumMsgType = -1; + m_prevTexStartTime = -1; + m_prevMeshStartTime = -1; + m_maxMeshSize = 0; + m_maxTextureSize = 0; QmlProfilerTimelineModel::clear(); } diff --git a/src/plugins/qmlprofiler/quick3dmodel.h b/src/plugins/qmlprofiler/quick3dmodel.h index 50bcebcb732..c82a2056ae3 100644 --- a/src/plugins/qmlprofiler/quick3dmodel.h +++ b/src/plugins/qmlprofiler/quick3dmodel.h @@ -36,10 +36,11 @@ class Quick3DModel : public QmlProfilerTimelineModel public: struct Item { - Item(int typeId, int data) : - typeId(typeId), data(data) {} - int typeId; - int data; + Item(int additionalType, quint64 data, bool unload = false) : + additionalType(additionalType), data(data), unload(unload) {} + int additionalType = 0; + quint64 data = 0; + bool unload = false; }; enum MessageType @@ -53,16 +54,21 @@ public: GenerateShader, LoadShader, ParticleUpdate, + + // additional types + MeshMemoryConsumption, + TextureMemoryConsumption }; 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; + qint64 rowMaxValue(int rowNumber) const override; + float relativeHeight(int index) const override; void loadEvent(const QmlEvent &event, const QmlEventType &type) override; void finalize() override; void clear() override; @@ -70,8 +76,15 @@ public: private: static QString messageType(uint i); + static QString unloadMessageType(uint i); - int m_maximumMsgType; + int m_maximumMsgType = 0; + qint64 m_prevTexStartTime = -1; + qint64 m_prevMeshStartTime = -1; + quint64 m_prevMeshData = 0; + quint64 m_prevTexData = 0; + quint64 m_maxMeshSize = 0; + quint64 m_maxTextureSize = 0; QVector m_data; };