Commit 63551d77 authored by Ulf Hermann's avatar Ulf Hermann

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: Riitta-Leena Miettinen's avatarLeena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Christian Kandeler's avatarChristian Kandeler <christian.kandeler@qt.io>
parent e7c950eb
...@@ -38,6 +38,11 @@ ...@@ -38,6 +38,11 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
static inline quint64 supportedFeatures()
{
return Constants::QML_JS_RANGE_FEATURES | (1ULL << ProfileMemory);
}
FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager, FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
QObject *parent) : QAbstractItemModel(parent) QObject *parent) : QAbstractItemModel(parent)
{ {
...@@ -51,8 +56,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager, ...@@ -51,8 +56,9 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed, connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
this, [this](int typeId, int, int){loadNotes(typeId, true);}); this, [this](int typeId, int, int){loadNotes(typeId, true);});
m_modelId = modelManager->registerModelProxy(); 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) { [this](const QmlEvent &event, const QmlEventType &type) {
loadEvent(event, type); loadEvent(event, type);
}, [this](){ }, [this](){
...@@ -98,7 +104,8 @@ void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal) ...@@ -98,7 +104,8 @@ void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal)
void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type) void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{ {
Q_UNUSED(type); if (!(m_acceptedFeatures & (1ULL << type.feature())))
return;
if (m_stackBottom.children.isEmpty()) if (m_stackBottom.children.isEmpty())
beginResetModel(); beginResetModel();
...@@ -150,6 +157,31 @@ void FlameGraphModel::onModelManagerStateChanged() ...@@ -150,6 +157,31 @@ void FlameGraphModel::onModelManagerStateChanged()
clear(); 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) static QString nameForType(RangeType typeNumber)
{ {
switch (typeNumber) { switch (typeNumber) {
......
...@@ -91,6 +91,7 @@ public slots: ...@@ -91,6 +91,7 @@ public slots:
void loadEvent(const QmlEvent &event, const QmlEventType &type); void loadEvent(const QmlEvent &event, const QmlEventType &type);
void finalize(); void finalize();
void onModelManagerStateChanged(); void onModelManagerStateChanged();
void restrictToFeatures(quint64 visibleFeatures);
void loadNotes(int typeId, bool emitSignal); void loadNotes(int typeId, bool emitSignal);
void clear(); void clear();
...@@ -105,6 +106,7 @@ private: ...@@ -105,6 +106,7 @@ private:
FlameGraphData *m_callStackTop; FlameGraphData *m_callStackTop;
FlameGraphData *m_compileStackTop; FlameGraphData *m_compileStackTop;
quint64 m_acceptedFeatures;
int m_modelId; int m_modelId;
QmlProfilerModelManager *m_modelManager; QmlProfilerModelManager *m_modelManager;
......
...@@ -80,13 +80,7 @@ void FlameGraphView::selectByTypeId(int typeIndex) ...@@ -80,13 +80,7 @@ void FlameGraphView::selectByTypeId(int typeIndex)
void FlameGraphView::onVisibleFeaturesChanged(quint64 features) void FlameGraphView::onVisibleFeaturesChanged(quint64 features)
{ {
int rangeTypeMask = 0; m_model->restrictToFeatures(features);
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);
} }
void FlameGraphView::contextMenuEvent(QContextMenuEvent *ev) void FlameGraphView::contextMenuEvent(QContextMenuEvent *ev)
......
...@@ -36,7 +36,6 @@ ScrollView { ...@@ -36,7 +36,6 @@ ScrollView {
signal gotoSourceLocation(string filename, int line, int column) signal gotoSourceLocation(string filename, int line, int column)
property int selectedTypeId: -1 property int selectedTypeId: -1
property int visibleRangeTypes: -1
property int sizeRole: QmlProfilerFlameGraphModel.DurationRole property int sizeRole: QmlProfilerFlameGraphModel.DurationRole
readonly property var trRoleNames: [ readonly property var trRoleNames: [
...@@ -86,11 +85,9 @@ ScrollView { ...@@ -86,11 +85,9 @@ ScrollView {
property int typeId: FlameGraph.data(QmlProfilerFlameGraphModel.TypeIdRole) || -1 property int typeId: FlameGraph.data(QmlProfilerFlameGraphModel.TypeIdRole) || -1
property bool isBindingLoop: parent.checkBindingLoop(typeId) property bool isBindingLoop: parent.checkBindingLoop(typeId)
property bool rangeTypeVisible:
root.visibleRangeTypes & (1 << FlameGraph.data(QmlProfilerFlameGraphModel.RangeTypeRole))
itemHeight: rangeTypeVisible ? flamegraph.delegateHeight : 0 itemHeight: flamegraph.delegateHeight
isSelected: typeId !== -1 && typeId === root.selectedTypeId && rangeTypeVisible isSelected: typeId !== -1 && typeId === root.selectedTypeId
borderColor: { borderColor: {
if (isSelected) if (isSelected)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment