diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2017-08-11 11:12:49 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2017-08-14 09:39:59 +0000 |
commit | 63551d7711170e2f0c96922d465dcea89f2963f7 (patch) | |
tree | 0c994d2e4c5cd46e996e825db012563342835581 | |
parent | e7c950eb11c393a2b999e2a175f71b72716b6168 (diff) | |
download | qt-creator-63551d7711170e2f0c96922d465dcea89f2963f7.tar.gz |
QmlProfiler: Rebuild the flamegraph model when visible features change
This is more expensive than just setting the filtered items' height to
0. However, this way we implicitly also change the size of the root
element, group equal items that end up on the same level by filtering,
recalculate the cutoff for too small items and resort all items by
width.
Change-Id: Ida2c5acd9848c5644ecff052d78e9fe5ad962606
Task-number: QTCREATORBUG-18713
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r-- | src/plugins/qmlprofiler/flamegraphmodel.cpp | 36 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/flamegraphmodel.h | 2 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/flamegraphview.cpp | 8 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml | 7 |
4 files changed, 39 insertions, 14 deletions
diff --git a/src/plugins/qmlprofiler/flamegraphmodel.cpp b/src/plugins/qmlprofiler/flamegraphmodel.cpp index 843c771c74..ca7e690aee 100644 --- a/src/plugins/qmlprofiler/flamegraphmodel.cpp +++ b/src/plugins/qmlprofiler/flamegraphmodel.cpp @@ -38,6 +38,11 @@ namespace QmlProfiler { namespace Internal { +static inline quint64 supportedFeatures() +{ + return Constants::QML_JS_RANGE_FEATURES | (1ULL << ProfileMemory); +} + FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager, QObject *parent) : QAbstractItemModel(parent) { @@ -51,8 +56,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager, connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed, this, [this](int typeId, int, int){loadNotes(typeId, true);}); m_modelId = modelManager->registerModelProxy(); + m_acceptedFeatures = supportedFeatures(); - modelManager->announceFeatures(Constants::QML_JS_RANGE_FEATURES | 1 << ProfileMemory, + modelManager->announceFeatures(m_acceptedFeatures, [this](const QmlEvent &event, const QmlEventType &type) { loadEvent(event, type); }, [this](){ @@ -98,7 +104,8 @@ void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal) void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type) { - Q_UNUSED(type); + if (!(m_acceptedFeatures & (1ULL << type.feature()))) + return; if (m_stackBottom.children.isEmpty()) beginResetModel(); @@ -150,6 +157,31 @@ void FlameGraphModel::onModelManagerStateChanged() clear(); } +void FlameGraphModel::restrictToFeatures(quint64 visibleFeatures) +{ + visibleFeatures = visibleFeatures & supportedFeatures(); + if (visibleFeatures == m_acceptedFeatures) + return; + + m_acceptedFeatures = visibleFeatures; + if (m_modelManager->state() != QmlProfilerModelManager::Done) + return; + + clear(); + beginResetModel(); + if (!m_modelManager->replayEvents(m_modelManager->traceTime()->startTime(), + m_modelManager->traceTime()->endTime(), + std::bind(&FlameGraphModel::loadEvent, + this, std::placeholders::_1, + std::placeholders::_2))) { + emit m_modelManager->error(tr("Could not re-read events from temporary trace file.")); + endResetModel(); + clear(); + } else { + finalize(); + } +} + static QString nameForType(RangeType typeNumber) { switch (typeNumber) { diff --git a/src/plugins/qmlprofiler/flamegraphmodel.h b/src/plugins/qmlprofiler/flamegraphmodel.h index 9fcc6e674c..587de41cf7 100644 --- a/src/plugins/qmlprofiler/flamegraphmodel.h +++ b/src/plugins/qmlprofiler/flamegraphmodel.h @@ -91,6 +91,7 @@ public slots: void loadEvent(const QmlEvent &event, const QmlEventType &type); void finalize(); void onModelManagerStateChanged(); + void restrictToFeatures(quint64 visibleFeatures); void loadNotes(int typeId, bool emitSignal); void clear(); @@ -105,6 +106,7 @@ private: FlameGraphData *m_callStackTop; FlameGraphData *m_compileStackTop; + quint64 m_acceptedFeatures; int m_modelId; QmlProfilerModelManager *m_modelManager; diff --git a/src/plugins/qmlprofiler/flamegraphview.cpp b/src/plugins/qmlprofiler/flamegraphview.cpp index 12cffd84d3..d26d4747a3 100644 --- a/src/plugins/qmlprofiler/flamegraphview.cpp +++ b/src/plugins/qmlprofiler/flamegraphview.cpp @@ -80,13 +80,7 @@ void FlameGraphView::selectByTypeId(int typeIndex) void FlameGraphView::onVisibleFeaturesChanged(quint64 features) { - int rangeTypeMask = 0; - for (int rangeType = 0; rangeType < MaximumRangeType; ++rangeType) { - if (features & (1ULL << featureFromRangeType(RangeType(rangeType)))) - rangeTypeMask |= (1 << rangeType); - } - if (m_content->rootObject()) - m_content->rootObject()->setProperty("visibleRangeTypes", rangeTypeMask); + m_model->restrictToFeatures(features); } void FlameGraphView::contextMenuEvent(QContextMenuEvent *ev) diff --git a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml index 2de3ec9422..34bca26cfa 100644 --- a/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml +++ b/src/plugins/qmlprofiler/qml/QmlProfilerFlameGraphView.qml @@ -36,7 +36,6 @@ ScrollView { signal gotoSourceLocation(string filename, int line, int column) property int selectedTypeId: -1 - property int visibleRangeTypes: -1 property int sizeRole: QmlProfilerFlameGraphModel.DurationRole readonly property var trRoleNames: [ @@ -86,11 +85,9 @@ ScrollView { property int typeId: FlameGraph.data(QmlProfilerFlameGraphModel.TypeIdRole) || -1 property bool isBindingLoop: parent.checkBindingLoop(typeId) - property bool rangeTypeVisible: - root.visibleRangeTypes & (1 << FlameGraph.data(QmlProfilerFlameGraphModel.RangeTypeRole)) - itemHeight: rangeTypeVisible ? flamegraph.delegateHeight : 0 - isSelected: typeId !== -1 && typeId === root.selectedTypeId && rangeTypeVisible + itemHeight: flamegraph.delegateHeight + isSelected: typeId !== -1 && typeId === root.selectedTypeId borderColor: { if (isSelected) |