diff options
author | Ulf Hermann <ulf.hermann@digia.com> | 2014-05-27 16:30:48 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@digia.com> | 2014-06-17 17:53:19 +0300 |
commit | 8e4445302ade7e1327b21f92db1dde1b81b26724 (patch) | |
tree | a0e2033048544b490ea16b0020d9fcfb9fe344af | |
parent | c83e2cb3eb009a88d65ba990e5ddf53d26afd228 (diff) |
Memory usage model
An additional model to represent memory usage of the application being
profiled.
Change-Id: I5f1e1e06a31adf2e4ba0bb63147492b6b5f50a3e
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
4 files changed, 306 insertions, 2 deletions
diff --git a/plugins/qmlprofilerextension/memoryusagemodel.cpp b/plugins/qmlprofilerextension/memoryusagemodel.cpp new file mode 100644 index 0000000000..409b48953a --- /dev/null +++ b/plugins/qmlprofilerextension/memoryusagemodel.cpp @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com <http://qt.digia.com/> +** +** This file is part of the Qt Enterprise Qt Quick Profiler Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com <http://qt.digia.com/> +** +****************************************************************************/ + +#include "memoryusagemodel.h" +#include "qmldebug/qmlprofilereventtypes.h" +#include "qmlprofiler/qmlprofilermodelmanager.h" +#include "qmlprofiler/sortedtimelinemodel.h" +#include "qmlprofiler/singlecategorytimelinemodel_p.h" + +#include <QDebug> + +namespace QmlProfilerExtension { +namespace Internal { + +using namespace QmlProfiler; + +class MemoryUsageModel::MemoryUsageModelPrivate : + public SortedTimelineModel<MemoryAllocation, + SingleCategoryTimelineModel::SingleCategoryTimelineModelPrivate> +{ +public: + static QString memoryTypeName(int type); + + qint64 maxSize; +private: + Q_DECLARE_PUBLIC(MemoryUsageModel) +}; + +MemoryUsageModel::MemoryUsageModel(QObject *parent) + : SingleCategoryTimelineModel(new MemoryUsageModelPrivate(), + QLatin1String("MemoryUsageTimelineModel"), + QLatin1String("Memory Usage"), QmlDebug::MemoryAllocation, + QmlDebug::MaximumRangeType, parent) +{ +} + +int MemoryUsageModel::rowCount() const +{ + return isEmpty() ? 1 : 3; +} + +int MemoryUsageModel::getEventRow(int index) const +{ + Q_D(const MemoryUsageModel); + QmlDebug::MemoryType type = d->range(index).type; + if (type == QmlDebug::HeapPage || type == QmlDebug::LargeItem) + return 1; + else + return 2; +} + +int MemoryUsageModel::getEventId(int index) const +{ + Q_D(const MemoryUsageModel); + return d->range(index).type; +} + +QColor MemoryUsageModel::getColor(int index) const +{ + return getEventColor(index); +} + +float MemoryUsageModel::getHeight(int index) const +{ + Q_D(const MemoryUsageModel); + return qMin(1.0f, (float)d->range(index).size / (float)d->maxSize * 0.85f + 0.15f); +} + +const QVariantList MemoryUsageModel::getLabels() const +{ + Q_D(const MemoryUsageModel); + QVariantList result; + + if (d->expanded && !isEmpty()) { + { + QVariantMap element; + element.insert(QLatin1String("displayName"), QVariant(tr("Memory Allocation"))); + element.insert(QLatin1String("description"), QVariant(tr("Memory Allocation"))); + + element.insert(QLatin1String("id"), QVariant(QmlDebug::HeapPage)); + result << element; + } + + { + QVariantMap element; + element.insert(QLatin1String("displayName"), QVariant(tr("Memory Usage"))); + element.insert(QLatin1String("description"), QVariant(tr("Memory Usage"))); + + element.insert(QLatin1String("id"), QVariant(QmlDebug::SmallItem)); + result << element; + } + } + + return result; +} + +const QVariantList MemoryUsageModel::getEventDetails(int index) const +{ + Q_D(const MemoryUsageModel); + QVariantList result; + const MemoryUsageModelPrivate::Range *ev = &d->range(index); + + { + QVariantMap res; + if (ev->size > 0) + res.insert(QLatin1String("title"), QVariant(QLatin1String("Memory Allocated"))); + else + res.insert(QLatin1String("title"), QVariant(QLatin1String("Memory Freed"))); + + result << res; + } + + { + QVariantMap res; + res.insert(tr("Total"), QVariant(QString::fromLatin1("%1 bytes").arg(ev->size))); + result << res; + } + + { + QVariantMap res; + res.insert(tr("Allocation"), QVariant(QString::fromLatin1("%1 bytes").arg(ev->delta))); + result << res; + } + + + { + QVariantMap res; + res.insert(tr("Type"), QVariant(MemoryUsageModelPrivate::memoryTypeName(ev->type))); + result << res; + } + + return result; +} + +void MemoryUsageModel::loadData() +{ + Q_D(MemoryUsageModel); + clear(); + QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel(); + if (simpleModel->isEmpty()) + return; + + qint64 currentSize = 0; + qint64 currentUsage = 0; + int currentUsageIndex = -1; + int currentJSHeapIndex = -1; + foreach (const QmlProfilerDataModel::QmlEventData &event, simpleModel->getEvents()) { + if (!eventAccepted(event)) + continue; + + if (event.detailType == QmlDebug::SmallItem || event.detailType == QmlDebug::LargeItem) { + currentUsage += event.numericData1; + MemoryAllocation allocation = { + QmlDebug::SmallItem, + currentUsage, + event.numericData1 + }; + if (currentUsageIndex != -1) { + d->insertEnd(currentUsageIndex, + event.startTime - d->range(currentUsageIndex).start - 1); + } + currentUsageIndex = d->insertStart(event.startTime, allocation); + } + + if (event.detailType == QmlDebug::HeapPage || event.detailType == QmlDebug::LargeItem) { + currentSize += event.numericData1; + MemoryAllocation allocation = { + (QmlDebug::MemoryType)event.detailType, + currentSize, + event.numericData1 + }; + + if (currentSize > d->maxSize) + d->maxSize = currentSize; + if (currentJSHeapIndex != -1) + d->insertEnd(currentJSHeapIndex, + event.startTime - d->range(currentJSHeapIndex).start - 1); + currentJSHeapIndex = d->insertStart(event.startTime, allocation); + } + + d->modelManager->modelProxyCountUpdated(d->modelId, d->count(), simpleModel->getEvents().count()); + } + + if (currentJSHeapIndex != -1) + d->insertEnd(currentJSHeapIndex, simpleModel->lastTimeMark() - + d->range(currentJSHeapIndex).start - 1); + if (currentUsageIndex != -1) + d->insertEnd(currentUsageIndex, simpleModel->lastTimeMark() - + d->range(currentUsageIndex).start - 1); + + + d->computeNesting(); + d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); +} + +void MemoryUsageModel::clear() +{ + Q_D(MemoryUsageModel); + d->SortedTimelineModel::clear(); + d->expanded = false; + d->maxSize = 1; + + d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); +} + +QString MemoryUsageModel::MemoryUsageModelPrivate::memoryTypeName(int type) +{ + switch (type) { + case QmlDebug::HeapPage: return tr("Heap Allocation"); + case QmlDebug::LargeItem: return tr("Large Item Allocation"); + case QmlDebug::SmallItem: return tr("Heap Usage"); + case QmlDebug::MaximumMemoryType: return tr("Total"); + default: return tr("Unknown"); + } +} + + +} // namespace Internal +} // namespace QmlProfilerExtension diff --git a/plugins/qmlprofilerextension/memoryusagemodel.h b/plugins/qmlprofilerextension/memoryusagemodel.h new file mode 100644 index 0000000000..a4250d767a --- /dev/null +++ b/plugins/qmlprofilerextension/memoryusagemodel.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc +** All rights reserved. +** For any questions to Digia, please use contact form at http://qt.digia.com <http://qt.digia.com/> +** +** This file is part of the Qt Enterprise Qt Quick Profiler Add-on. +** +** Licensees holding valid Qt Enterprise licenses may use this file in +** accordance with the Qt Enterprise License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. +** +** If you have questions regarding the use of this file, please use +** contact form at http://qt.digia.com <http://qt.digia.com/> +** +****************************************************************************/ + +#ifndef MEMORYUSAGEMODEL_H +#define MEMORYUSAGEMODEL_H + +#include "qmlprofiler/qmlprofilertimelinemodelproxy.h" +#include "qmlprofiler/singlecategorytimelinemodel.h" +#include "qmlprofiler/qmlprofilerdatamodel.h" + +#include <QStringList> +#include <QColor> + +namespace QmlProfilerExtension { +namespace Internal { + +class MemoryUsageModel : public QmlProfiler::SingleCategoryTimelineModel +{ + Q_OBJECT +public: + + struct MemoryAllocation { + QmlDebug::MemoryType type; + qint64 size; + qint64 delta; + }; + + MemoryUsageModel(QObject *parent = 0); + + int rowCount() const; + + int getEventRow(int index) const; + int getEventId(int index) const; + QColor getColor(int index) const; + float getHeight(int index) const; + + const QVariantList getLabels() const; + const QVariantList getEventDetails(int index) const; + + void loadData(); + void clear(); + +private: + class MemoryUsageModelPrivate; + Q_DECLARE_PRIVATE(MemoryUsageModel) +}; + +} // namespace Internal +} // namespace QmlProfilerExtension + +#endif // MEMORYUSAGEMODEL_H diff --git a/plugins/qmlprofilerextension/qmlprofilerextension.pro b/plugins/qmlprofilerextension/qmlprofilerextension.pro index e1282d0ace..b0e4e2ad0b 100644 --- a/plugins/qmlprofilerextension/qmlprofilerextension.pro +++ b/plugins/qmlprofilerextension/qmlprofilerextension.pro @@ -11,13 +11,15 @@ DEFINES += QMLPROFILEREXTENSION_LIBRARY SOURCES += qmlprofilerextensionplugin.cpp \ scenegraphtimelinemodel.cpp \ - pixmapcachemodel.cpp + pixmapcachemodel.cpp \ + memoryusagemodel.cpp HEADERS += qmlprofilerextensionplugin.h \ qmlprofilerextension_global.h \ qmlprofilerextensionconstants.h \ scenegraphtimelinemodel.h \ - pixmapcachemodel.h + pixmapcachemodel.h \ + memoryusagemodel.h OTHER_FILES += \ QmlProfilerExtension.json diff --git a/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp b/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp index c609ec0256..2a1f493075 100644 --- a/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp +++ b/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp @@ -40,6 +40,7 @@ #include "scenegraphtimelinemodel.h" #include "pixmapcachemodel.h" +#include "memoryusagemodel.h" using namespace QmlProfilerExtension::Internal; @@ -72,6 +73,7 @@ bool QmlProfilerExtensionPlugin::initialize(const QStringList &arguments, QStrin if (licenseChecker && licenseChecker->hasValidLicense()) { addAutoReleasedObject(new PixmapCacheModel); addAutoReleasedObject(new SceneGraphTimelineModel); + addAutoReleasedObject(new MemoryUsageModel); } else { qWarning() << "Invalid license, disabling QML Profiler Enterprise features"; } |