forked from qt-creator/qt-creator
QmlProfiler: Load data event by event in aggregated models
This paves the way for driving the event loading from the model manager. Also, unify the loading and eliminate the two different classes for the children models. Change-Id: Ic89e757963292d75b3b6fd7d6012f09194dff5a9 Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
@@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStack>
|
|
||||||
#include <QQueue>
|
#include <QQueue>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
|
||||||
@@ -44,8 +43,10 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
|
|||||||
QObject *parent) : QAbstractItemModel(parent)
|
QObject *parent) : QAbstractItemModel(parent)
|
||||||
{
|
{
|
||||||
m_modelManager = modelManager;
|
m_modelManager = modelManager;
|
||||||
connect(modelManager->qmlModel(), &QmlProfilerDataModel::changed,
|
m_callStack.append(QmlEvent());
|
||||||
this, [this](){loadData();});
|
m_stackTop = &m_stackBottom;
|
||||||
|
connect(modelManager, &QmlProfilerModelManager::stateChanged,
|
||||||
|
this, &FlameGraphModel::onModelManagerStateChanged);
|
||||||
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();
|
||||||
@@ -61,8 +62,13 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
|
|||||||
|
|
||||||
void FlameGraphModel::clear()
|
void FlameGraphModel::clear()
|
||||||
{
|
{
|
||||||
|
beginResetModel();
|
||||||
m_stackBottom = FlameGraphData();
|
m_stackBottom = FlameGraphData();
|
||||||
|
m_callStack.clear();
|
||||||
|
m_callStack.append(QmlEvent());
|
||||||
|
m_stackTop = &m_stackBottom;
|
||||||
m_typeIdsWithNotes.clear();
|
m_typeIdsWithNotes.clear();
|
||||||
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal)
|
void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal)
|
||||||
@@ -87,64 +93,66 @@ void FlameGraphModel::loadNotes(int typeIndex, bool emitSignal)
|
|||||||
emit dataChanged(QModelIndex(), QModelIndex(), QVector<int>() << NoteRole);
|
emit dataChanged(QModelIndex(), QModelIndex(), QVector<int>() << NoteRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlameGraphModel::loadData(qint64 rangeStart, qint64 rangeEnd)
|
void FlameGraphModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||||
{
|
{
|
||||||
const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);
|
if (!m_acceptedTypes.contains(type.rangeType))
|
||||||
if (m_modelManager->state() == QmlProfilerModelManager::ClearingData) {
|
|
||||||
beginResetModel();
|
|
||||||
clear();
|
|
||||||
endResetModel();
|
|
||||||
return;
|
return;
|
||||||
} else if (m_modelManager->state() != QmlProfilerModelManager::ProcessingData &&
|
|
||||||
m_modelManager->state() != QmlProfilerModelManager::Done) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (m_stackBottom.children.isEmpty())
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
clear();
|
|
||||||
|
|
||||||
const QVector<QmlEvent> &eventList = m_modelManager->qmlModel()->events();
|
const QmlEvent *potentialParent = &(m_callStack.top());
|
||||||
const QVector<QmlEventType> &typesList = m_modelManager->qmlModel()->eventTypes();
|
while (potentialParent->isValid() &&
|
||||||
|
potentialParent->timestamp() + potentialParent->duration() <= event.timestamp()) {
|
||||||
// used by binding loop detection
|
m_callStack.pop();
|
||||||
QStack<const QmlEvent *> callStack;
|
m_stackTop = m_stackTop->parent;
|
||||||
callStack.append(0);
|
potentialParent = &(m_callStack.top());
|
||||||
FlameGraphData *stackTop = &m_stackBottom;
|
|
||||||
|
|
||||||
for (int i = 0; i < eventList.size(); ++i) {
|
|
||||||
const QmlEvent *event = &eventList[i];
|
|
||||||
int typeIndex = event->typeIndex();
|
|
||||||
const QmlEventType *type = &typesList[typeIndex];
|
|
||||||
|
|
||||||
if (!m_acceptedTypes.contains(type->rangeType))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (checkRanges) {
|
|
||||||
if ((event->timestamp() + event->duration() < rangeStart)
|
|
||||||
|| (event->timestamp() > rangeEnd))
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QmlEvent *potentialParent = callStack.top();
|
m_callStack.push(event);
|
||||||
while (potentialParent &&
|
m_stackTop = pushChild(m_stackTop, event);
|
||||||
potentialParent->timestamp() + potentialParent->duration() <= event->timestamp()) {
|
|
||||||
callStack.pop();
|
|
||||||
stackTop = stackTop->parent;
|
|
||||||
potentialParent = callStack.top();
|
|
||||||
}
|
|
||||||
|
|
||||||
callStack.push(event);
|
|
||||||
stackTop = pushChild(stackTop, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlameGraphModel::finalize()
|
||||||
|
{
|
||||||
foreach (FlameGraphData *child, m_stackBottom.children)
|
foreach (FlameGraphData *child, m_stackBottom.children)
|
||||||
m_stackBottom.duration += child->duration;
|
m_stackBottom.duration += child->duration;
|
||||||
|
|
||||||
loadNotes(-1, false);
|
loadNotes(-1, false);
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlameGraphModel::onModelManagerStateChanged()
|
||||||
|
{
|
||||||
|
if (m_modelManager->state() == QmlProfilerModelManager::ClearingData)
|
||||||
|
clear();
|
||||||
|
else if (m_modelManager->state() == QmlProfilerModelManager::ProcessingData)
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlameGraphModel::loadData(qint64 rangeStart, qint64 rangeEnd)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);
|
||||||
|
|
||||||
|
const QVector<QmlEvent> &eventList = m_modelManager->qmlModel()->events();
|
||||||
|
const QVector<QmlEventType> &typesList = m_modelManager->qmlModel()->eventTypes();
|
||||||
|
|
||||||
|
for (int i = 0; i < eventList.size(); ++i) {
|
||||||
|
const QmlEvent &event = eventList[i];
|
||||||
|
|
||||||
|
if (checkRanges) {
|
||||||
|
if ((event.timestamp() + event.duration() < rangeStart)
|
||||||
|
|| (event.timestamp() > rangeEnd))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadEvent(event, typesList[event.typeIndex()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize();
|
||||||
|
}
|
||||||
|
|
||||||
static QString nameForType(RangeType typeNumber)
|
static QString nameForType(RangeType typeNumber)
|
||||||
{
|
{
|
||||||
switch (typeNumber) {
|
switch (typeNumber) {
|
||||||
@@ -210,18 +218,17 @@ FlameGraphData::~FlameGraphData()
|
|||||||
qDeleteAll(children);
|
qDeleteAll(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlameGraphData *FlameGraphModel::pushChild(
|
FlameGraphData *FlameGraphModel::pushChild(FlameGraphData *parent, const QmlEvent &data)
|
||||||
FlameGraphData *parent, const QmlEvent *data)
|
|
||||||
{
|
{
|
||||||
foreach (FlameGraphData *child, parent->children) {
|
foreach (FlameGraphData *child, parent->children) {
|
||||||
if (child->typeIndex == data->typeIndex()) {
|
if (child->typeIndex == data.typeIndex()) {
|
||||||
++child->calls;
|
++child->calls;
|
||||||
child->duration += data->duration();
|
child->duration += data.duration();
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlameGraphData *child = new FlameGraphData(parent, data->typeIndex(), data->duration());
|
FlameGraphData *child = new FlameGraphData(parent, data.typeIndex(), data.duration());
|
||||||
parent->children.append(child);
|
parent->children.append(child);
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
#include <QStack>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
@@ -81,8 +82,12 @@ public:
|
|||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void loadEvent(const QmlEvent &event, const QmlEventType &type);
|
||||||
|
void finalize();
|
||||||
|
void onModelManagerStateChanged();
|
||||||
void loadData(qint64 rangeStart = -1, qint64 rangeEnd = -1);
|
void loadData(qint64 rangeStart = -1, qint64 rangeEnd = -1);
|
||||||
void loadNotes(int typeId, bool emitSignal);
|
void loadNotes(int typeId, bool emitSignal);
|
||||||
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class FlameGraphRelativesModel;
|
friend class FlameGraphRelativesModel;
|
||||||
@@ -90,11 +95,14 @@ private:
|
|||||||
friend class FlameGraphChildrenModel;
|
friend class FlameGraphChildrenModel;
|
||||||
|
|
||||||
QVariant lookup(const FlameGraphData &data, int role) const;
|
QVariant lookup(const FlameGraphData &data, int role) const;
|
||||||
void clear();
|
FlameGraphData *pushChild(FlameGraphData *parent, const QmlEvent &data);
|
||||||
FlameGraphData *pushChild(FlameGraphData *parent, const QmlEvent *data);
|
|
||||||
|
|
||||||
int m_selectedTypeIndex;
|
int m_selectedTypeIndex;
|
||||||
|
|
||||||
|
// used by binding loop detection
|
||||||
|
QStack<QmlEvent> m_callStack;
|
||||||
FlameGraphData m_stackBottom;
|
FlameGraphData m_stackBottom;
|
||||||
|
FlameGraphData *m_stackTop;
|
||||||
|
|
||||||
int m_modelId;
|
int m_modelId;
|
||||||
QmlProfilerModelManager *m_modelManager;
|
QmlProfilerModelManager *m_modelManager;
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStack>
|
#include <QStack>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ class QmlProfilerStatisticsModel::QmlProfilerStatisticsModelPrivate
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QHash<int, QmlProfilerStatisticsModel::QmlEventStats> data;
|
QHash<int, QmlProfilerStatisticsModel::QmlEventStats> data;
|
||||||
|
QPointer<QmlProfilerStatisticsRelativesModel> childrenModel;
|
||||||
|
QPointer<QmlProfilerStatisticsRelativesModel> parentsModel;
|
||||||
|
|
||||||
QmlProfilerModelManager *modelManager;
|
QmlProfilerModelManager *modelManager;
|
||||||
|
|
||||||
@@ -50,6 +53,11 @@ public:
|
|||||||
QList<RangeType> acceptedTypes;
|
QList<RangeType> acceptedTypes;
|
||||||
QSet<int> eventsInBindingLoop;
|
QSet<int> eventsInBindingLoop;
|
||||||
QHash<int, QString> notes;
|
QHash<int, QString> notes;
|
||||||
|
|
||||||
|
QStack<QmlEvent> callStack;
|
||||||
|
qint64 qmlTime = 0;
|
||||||
|
qint64 lastEndTime = 0;
|
||||||
|
QHash <int, QVector<qint64> > durations;
|
||||||
};
|
};
|
||||||
|
|
||||||
QmlProfilerStatisticsModel::QmlProfilerStatisticsModel(QmlProfilerModelManager *modelManager,
|
QmlProfilerStatisticsModel::QmlProfilerStatisticsModel(QmlProfilerModelManager *modelManager,
|
||||||
@@ -57,7 +65,8 @@ QmlProfilerStatisticsModel::QmlProfilerStatisticsModel(QmlProfilerModelManager *
|
|||||||
QObject(parent), d(new QmlProfilerStatisticsModelPrivate)
|
QObject(parent), d(new QmlProfilerStatisticsModelPrivate)
|
||||||
{
|
{
|
||||||
d->modelManager = modelManager;
|
d->modelManager = modelManager;
|
||||||
connect(modelManager->qmlModel(), &QmlProfilerDataModel::changed,
|
d->callStack.push(QmlEvent());
|
||||||
|
connect(modelManager, &QmlProfilerModelManager::stateChanged,
|
||||||
this, &QmlProfilerStatisticsModel::dataChanged);
|
this, &QmlProfilerStatisticsModel::dataChanged);
|
||||||
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
|
connect(modelManager->notesModel(), &Timeline::TimelineNotesModel::changed,
|
||||||
this, &QmlProfilerStatisticsModel::notesChanged);
|
this, &QmlProfilerStatisticsModel::notesChanged);
|
||||||
@@ -86,11 +95,6 @@ void QmlProfilerStatisticsModel::setEventTypeAccepted(RangeType type, bool accep
|
|||||||
d->acceptedTypes.removeOne(type);
|
d->acceptedTypes.removeOne(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QmlProfilerStatisticsModel::eventTypeAccepted(RangeType type) const
|
|
||||||
{
|
|
||||||
return d->acceptedTypes.contains(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QHash<int, QmlProfilerStatisticsModel::QmlEventStats> &QmlProfilerStatisticsModel::getData() const
|
const QHash<int, QmlProfilerStatisticsModel::QmlEventStats> &QmlProfilerStatisticsModel::getData() const
|
||||||
{
|
{
|
||||||
return d->data;
|
return d->data;
|
||||||
@@ -111,6 +115,15 @@ void QmlProfilerStatisticsModel::clear()
|
|||||||
d->data.clear();
|
d->data.clear();
|
||||||
d->eventsInBindingLoop.clear();
|
d->eventsInBindingLoop.clear();
|
||||||
d->notes.clear();
|
d->notes.clear();
|
||||||
|
d->callStack.clear();
|
||||||
|
d->callStack.push(QmlEvent());
|
||||||
|
d->qmlTime = 0;
|
||||||
|
d->lastEndTime = 0;
|
||||||
|
d->durations.clear();
|
||||||
|
if (!d->childrenModel.isNull())
|
||||||
|
d->childrenModel->clear();
|
||||||
|
if (!d->parentsModel.isNull())
|
||||||
|
d->parentsModel->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlProfilerStatisticsModel::limitToRange(qint64 rangeStart, qint64 rangeEnd)
|
void QmlProfilerStatisticsModel::limitToRange(qint64 rangeStart, qint64 rangeEnd)
|
||||||
@@ -119,6 +132,15 @@ void QmlProfilerStatisticsModel::limitToRange(qint64 rangeStart, qint64 rangeEnd
|
|||||||
loadData(rangeStart, rangeEnd);
|
loadData(rangeStart, rangeEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlProfilerStatisticsModel::setRelativesModel(QmlProfilerStatisticsRelativesModel *relative,
|
||||||
|
QmlProfilerStatisticsRelation relation)
|
||||||
|
{
|
||||||
|
if (relation == QmlProfilerStatisticsParents)
|
||||||
|
d->parentsModel = relative;
|
||||||
|
else
|
||||||
|
d->childrenModel = relative;
|
||||||
|
}
|
||||||
|
|
||||||
void QmlProfilerStatisticsModel::dataChanged()
|
void QmlProfilerStatisticsModel::dataChanged()
|
||||||
{
|
{
|
||||||
if (d->modelManager->state() == QmlProfilerModelManager::ProcessingData)
|
if (d->modelManager->state() == QmlProfilerModelManager::ProcessingData)
|
||||||
@@ -159,98 +181,103 @@ void QmlProfilerStatisticsModel::notesChanged(int typeIndex)
|
|||||||
emit notesAvailable(typeIndex);
|
emit notesAvailable(typeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QSet<int> &QmlProfilerStatisticsModel::eventsInBindingLoop() const
|
|
||||||
{
|
|
||||||
return d->eventsInBindingLoop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QmlProfilerStatisticsModel::loadData(qint64 rangeStart, qint64 rangeEnd)
|
void QmlProfilerStatisticsModel::loadData(qint64 rangeStart, qint64 rangeEnd)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
qint64 qmlTime = 0;
|
|
||||||
qint64 lastEndTime = 0;
|
|
||||||
QHash <int, QVector<qint64> > durations;
|
|
||||||
|
|
||||||
const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);
|
const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);
|
||||||
|
|
||||||
const QVector<QmlEvent> &eventList = d->modelManager->qmlModel()->events();
|
const QVector<QmlEvent> &eventList = d->modelManager->qmlModel()->events();
|
||||||
const QVector<QmlEventType> &typesList = d->modelManager->qmlModel()->eventTypes();
|
const QVector<QmlEventType> &typesList = d->modelManager->qmlModel()->eventTypes();
|
||||||
|
|
||||||
// used by binding loop detection
|
|
||||||
QStack<const QmlEvent*> callStack;
|
|
||||||
callStack.push(0); // artificial root
|
|
||||||
|
|
||||||
for (int i = 0; i < eventList.size(); ++i) {
|
for (int i = 0; i < eventList.size(); ++i) {
|
||||||
const QmlEvent *event = &eventList[i];
|
const QmlEvent &event = eventList[i];
|
||||||
const QmlEventType *type = &typesList[event->typeIndex()];
|
const QmlEventType &type = typesList[event.typeIndex()];
|
||||||
|
|
||||||
if (!d->acceptedTypes.contains(type->rangeType))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (checkRanges) {
|
if (checkRanges) {
|
||||||
if ((event->timestamp() + event->duration() < rangeStart)
|
if ((event.timestamp() + event.duration() < rangeStart)
|
||||||
|| (event->timestamp() > rangeEnd))
|
|| (event.timestamp() > rangeEnd))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update stats
|
loadEvent(event, type);
|
||||||
QmlEventStats *stats = &d->data[event->typeIndex()];
|
}
|
||||||
|
|
||||||
stats->duration += event->duration();
|
finalize();
|
||||||
stats->durationSelf += event->duration();
|
if (checkRanges)
|
||||||
if (event->duration() < stats->minTime)
|
notesChanged(-1); // Reload notes
|
||||||
stats->minTime = event->duration();
|
}
|
||||||
if (event->duration() > stats->maxTime)
|
|
||||||
stats->maxTime = event->duration();
|
void QmlProfilerStatisticsModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
|
||||||
|
{
|
||||||
|
if (!d->acceptedTypes.contains(type.rangeType))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// update stats
|
||||||
|
QmlEventStats *stats = &d->data[event.typeIndex()];
|
||||||
|
|
||||||
|
stats->duration += event.duration();
|
||||||
|
stats->durationSelf += event.duration();
|
||||||
|
if (event.duration() < stats->minTime)
|
||||||
|
stats->minTime = event.duration();
|
||||||
|
if (event.duration() > stats->maxTime)
|
||||||
|
stats->maxTime = event.duration();
|
||||||
stats->calls++;
|
stats->calls++;
|
||||||
|
|
||||||
// for median computing
|
// for median computing
|
||||||
durations[event->typeIndex()].append(event->duration());
|
d->durations[event.typeIndex()].append(event.duration());
|
||||||
|
|
||||||
// qml time computation
|
// qml time computation
|
||||||
if (event->timestamp() > lastEndTime) { // assume parent event if starts before last end
|
if (event.timestamp() > d->lastEndTime) { // assume parent event if starts before last end
|
||||||
qmlTime += event->duration();
|
d->qmlTime += event.duration();
|
||||||
lastEndTime = event->timestamp() + event->duration();
|
d->lastEndTime = event.timestamp() + event.duration();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// binding loop detection
|
// binding loop detection
|
||||||
//
|
//
|
||||||
const QmlEvent *potentialParent = callStack.top();
|
const QmlEvent *potentialParent = &(d->callStack.top());
|
||||||
while (potentialParent && !(potentialParent->timestamp() + potentialParent->duration() >
|
while (potentialParent->isValid() &&
|
||||||
event->timestamp())) {
|
!(potentialParent->timestamp() + potentialParent->duration() > event.timestamp())) {
|
||||||
callStack.pop();
|
d->callStack.pop();
|
||||||
potentialParent = callStack.top();
|
potentialParent = &(d->callStack.top());
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether event is already in stack
|
// check whether event is already in stack
|
||||||
for (int ii = 1; ii < callStack.size(); ++ii) {
|
for (int ii = 1; ii < d->callStack.size(); ++ii) {
|
||||||
if (callStack.at(ii)->typeIndex() == event->typeIndex()) {
|
if (d->callStack.at(ii).typeIndex() == event.typeIndex()) {
|
||||||
d->eventsInBindingLoop.insert(event->typeIndex());
|
d->eventsInBindingLoop.insert(event.typeIndex());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callStack.count() > 1)
|
if (d->callStack.count() > 1)
|
||||||
d->data[callStack.top()->typeIndex()].durationSelf -= event->duration();
|
d->data[d->callStack.top().typeIndex()].durationSelf -= event.duration();
|
||||||
callStack.push(event);
|
d->callStack.push(event);
|
||||||
|
|
||||||
|
if (!d->childrenModel.isNull())
|
||||||
|
d->childrenModel->loadEvent(event);
|
||||||
|
if (!d->parentsModel.isNull())
|
||||||
|
d->parentsModel->loadEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QmlProfilerStatisticsModel::finalize()
|
||||||
|
{
|
||||||
// post-process: calc mean time, median time, percentoftime
|
// post-process: calc mean time, median time, percentoftime
|
||||||
for (QHash<int, QmlEventStats>::iterator it = d->data.begin(); it != d->data.end(); ++it) {
|
for (QHash<int, QmlEventStats>::iterator it = d->data.begin(); it != d->data.end(); ++it) {
|
||||||
QmlEventStats* stats = &it.value();
|
QmlEventStats* stats = &it.value();
|
||||||
if (stats->calls > 0)
|
if (stats->calls > 0)
|
||||||
stats->timePerCall = stats->duration / (double)stats->calls;
|
stats->timePerCall = stats->duration / (double)stats->calls;
|
||||||
|
|
||||||
QVector<qint64> eventDurations = durations[it.key()];
|
QVector<qint64> eventDurations = d->durations[it.key()];
|
||||||
if (!eventDurations.isEmpty()) {
|
if (!eventDurations.isEmpty()) {
|
||||||
Utils::sort(eventDurations);
|
Utils::sort(eventDurations);
|
||||||
stats->medianTime = eventDurations.at(eventDurations.count()/2);
|
stats->medianTime = eventDurations.at(eventDurations.count()/2);
|
||||||
}
|
}
|
||||||
|
|
||||||
stats->percentOfTime = stats->duration * 100.0 / qmlTime;
|
stats->percentOfTime = stats->duration * 100.0 / d->qmlTime;
|
||||||
stats->percentSelf = stats->durationSelf * 100.0 / qmlTime;
|
stats->percentSelf = stats->durationSelf * 100.0 / d->qmlTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set binding loop flag
|
// set binding loop flag
|
||||||
@@ -260,13 +287,17 @@ void QmlProfilerStatisticsModel::loadData(qint64 rangeStart, qint64 rangeEnd)
|
|||||||
// insert root event
|
// insert root event
|
||||||
QmlEventStats rootEvent;
|
QmlEventStats rootEvent;
|
||||||
rootEvent.duration = rootEvent.minTime = rootEvent.maxTime = rootEvent.timePerCall
|
rootEvent.duration = rootEvent.minTime = rootEvent.maxTime = rootEvent.timePerCall
|
||||||
= rootEvent.medianTime = qmlTime + 1;
|
= rootEvent.medianTime = d->qmlTime + 1;
|
||||||
rootEvent.durationSelf = 1;
|
rootEvent.durationSelf = 1;
|
||||||
rootEvent.calls = 1;
|
rootEvent.calls = 1;
|
||||||
rootEvent.percentOfTime = 100.0;
|
rootEvent.percentOfTime = 100.0;
|
||||||
rootEvent.percentSelf = 1.0 / rootEvent.duration;
|
rootEvent.percentSelf = 1.0 / rootEvent.duration;
|
||||||
|
|
||||||
d->data.insert(-1, rootEvent);
|
d->data.insert(-1, rootEvent);
|
||||||
|
if (!d->childrenModel.isNull())
|
||||||
|
d->childrenModel->finalize(d->eventsInBindingLoop);
|
||||||
|
if (!d->parentsModel.isNull())
|
||||||
|
d->parentsModel->finalize(d->eventsInBindingLoop);
|
||||||
|
|
||||||
emit dataAvailable();
|
emit dataAvailable();
|
||||||
}
|
}
|
||||||
@@ -278,18 +309,21 @@ int QmlProfilerStatisticsModel::count() const
|
|||||||
|
|
||||||
QmlProfilerStatisticsRelativesModel::QmlProfilerStatisticsRelativesModel(
|
QmlProfilerStatisticsRelativesModel::QmlProfilerStatisticsRelativesModel(
|
||||||
QmlProfilerModelManager *modelManager, QmlProfilerStatisticsModel *statisticsModel,
|
QmlProfilerModelManager *modelManager, QmlProfilerStatisticsModel *statisticsModel,
|
||||||
QObject *parent) : QObject(parent)
|
QmlProfilerStatisticsRelation relation, QObject *parent) :
|
||||||
|
QObject(parent), m_relation(relation)
|
||||||
{
|
{
|
||||||
|
m_endtimesPerLevel[0] = 0;
|
||||||
|
|
||||||
QTC_CHECK(modelManager);
|
QTC_CHECK(modelManager);
|
||||||
m_modelManager = modelManager;
|
m_modelManager = modelManager;
|
||||||
|
|
||||||
QTC_CHECK(statisticsModel);
|
QTC_CHECK(statisticsModel);
|
||||||
m_statisticsModel = statisticsModel;
|
statisticsModel->setRelativesModel(this, relation);
|
||||||
|
|
||||||
// Load the child models whenever the parent model is done to get the filtering for JS/QML
|
// Load the child models whenever the parent model is done to get the filtering for JS/QML
|
||||||
// right.
|
// right.
|
||||||
connect(m_statisticsModel, &QmlProfilerStatisticsModel::dataAvailable,
|
connect(statisticsModel, &QmlProfilerStatisticsModel::dataAvailable,
|
||||||
this, &QmlProfilerStatisticsRelativesModel::dataChanged);
|
this, &QmlProfilerStatisticsRelativesModel::dataAvailable);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesMap &
|
const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesMap &
|
||||||
@@ -309,6 +343,57 @@ const QVector<QmlEventType> &QmlProfilerStatisticsRelativesModel::getTypes() con
|
|||||||
return m_modelManager->qmlModel()->eventTypes();
|
return m_modelManager->qmlModel()->eventTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QmlProfilerStatisticsRelativesModel::loadEvent(const QmlEvent &event)
|
||||||
|
{
|
||||||
|
// level computation
|
||||||
|
if (m_endtimesPerLevel[m_level] > event.timestamp()) {
|
||||||
|
m_level++;
|
||||||
|
} else {
|
||||||
|
while (m_level > Constants::QML_MIN_LEVEL &&
|
||||||
|
m_endtimesPerLevel[m_level-1] <= event.timestamp())
|
||||||
|
m_level--;
|
||||||
|
}
|
||||||
|
m_endtimesPerLevel[m_level] = event.timestamp() + event.duration();
|
||||||
|
|
||||||
|
int parentTypeIndex = -1;
|
||||||
|
if (m_level > Constants::QML_MIN_LEVEL && m_lastParent.contains(m_level-1))
|
||||||
|
parentTypeIndex = m_lastParent[m_level-1];
|
||||||
|
|
||||||
|
int relativeTypeIndex = (m_relation == QmlProfilerStatisticsParents) ? parentTypeIndex :
|
||||||
|
event.typeIndex();
|
||||||
|
int selfTypeIndex = (m_relation == QmlProfilerStatisticsParents) ? event.typeIndex() :
|
||||||
|
parentTypeIndex;
|
||||||
|
|
||||||
|
QmlStatisticsRelativesMap &relativesMap = m_data[selfTypeIndex];
|
||||||
|
QmlStatisticsRelativesMap::Iterator it = relativesMap.find(relativeTypeIndex);
|
||||||
|
if (it != relativesMap.end()) {
|
||||||
|
it.value().calls++;
|
||||||
|
it.value().duration += event.duration();
|
||||||
|
} else {
|
||||||
|
QmlStatisticsRelativesData relative = {
|
||||||
|
event.duration(),
|
||||||
|
1,
|
||||||
|
false
|
||||||
|
};
|
||||||
|
relativesMap.insert(relativeTypeIndex, relative);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now lastparent is the new type
|
||||||
|
m_lastParent[m_level] = event.typeIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlProfilerStatisticsRelativesModel::finalize(const QSet<int> &eventsInBindingLoop)
|
||||||
|
{
|
||||||
|
for (auto map = m_data.begin(), mapEnd = m_data.end(); map != mapEnd; ++map) {
|
||||||
|
auto itemEnd = map->end();
|
||||||
|
foreach (int typeIndex, eventsInBindingLoop) {
|
||||||
|
auto item = map->find(typeIndex);
|
||||||
|
if (item != itemEnd)
|
||||||
|
item->isBindingLoop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int QmlProfilerStatisticsRelativesModel::count() const
|
int QmlProfilerStatisticsRelativesModel::count() const
|
||||||
{
|
{
|
||||||
return m_data.count();
|
return m_data.count();
|
||||||
@@ -317,138 +402,10 @@ int QmlProfilerStatisticsRelativesModel::count() const
|
|||||||
void QmlProfilerStatisticsRelativesModel::clear()
|
void QmlProfilerStatisticsRelativesModel::clear()
|
||||||
{
|
{
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
|
m_endtimesPerLevel.clear();
|
||||||
|
m_level = Constants::QML_MIN_LEVEL;
|
||||||
|
m_endtimesPerLevel[0] = 0;
|
||||||
|
m_lastParent.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlProfilerStatisticsRelativesModel::dataChanged()
|
} // namespace QmlProfiler
|
||||||
{
|
|
||||||
loadData();
|
|
||||||
|
|
||||||
emit dataAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
QmlProfilerStatisticsParentsModel::QmlProfilerStatisticsParentsModel(
|
|
||||||
QmlProfilerModelManager *modelManager, QmlProfilerStatisticsModel *statisticsModel,
|
|
||||||
QObject *parent) :
|
|
||||||
QmlProfilerStatisticsRelativesModel(modelManager, statisticsModel, parent)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void QmlProfilerStatisticsParentsModel::loadData()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
QmlProfilerDataModel *simpleModel = m_modelManager->qmlModel();
|
|
||||||
if (simpleModel->isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// for level computation
|
|
||||||
QHash<int, qint64> endtimesPerLevel;
|
|
||||||
int level = Constants::QML_MIN_LEVEL;
|
|
||||||
endtimesPerLevel[0] = 0;
|
|
||||||
|
|
||||||
const QSet<int> &eventsInBindingLoop = m_statisticsModel->eventsInBindingLoop();
|
|
||||||
|
|
||||||
// compute parent-child relationship and call count
|
|
||||||
QHash<int, int> lastParent;
|
|
||||||
const QVector<QmlEvent> eventList = simpleModel->events();
|
|
||||||
const QVector<QmlEventType> typesList = simpleModel->eventTypes();
|
|
||||||
foreach (const QmlEvent &event, eventList) {
|
|
||||||
// whitelist
|
|
||||||
if (!m_statisticsModel->eventTypeAccepted(typesList[event.typeIndex()].rangeType))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// level computation
|
|
||||||
if (endtimesPerLevel[level] > event.timestamp()) {
|
|
||||||
level++;
|
|
||||||
} else {
|
|
||||||
while (level > Constants::QML_MIN_LEVEL &&
|
|
||||||
endtimesPerLevel[level-1] <= event.timestamp())
|
|
||||||
level--;
|
|
||||||
}
|
|
||||||
endtimesPerLevel[level] = event.timestamp() + event.duration();
|
|
||||||
|
|
||||||
int parentTypeIndex = -1;
|
|
||||||
if (level > Constants::QML_MIN_LEVEL && lastParent.contains(level-1))
|
|
||||||
parentTypeIndex = lastParent[level-1];
|
|
||||||
|
|
||||||
QmlStatisticsRelativesMap &relativesMap = m_data[event.typeIndex()];
|
|
||||||
QmlStatisticsRelativesMap::Iterator it = relativesMap.find(parentTypeIndex);
|
|
||||||
if (it != relativesMap.end()) {
|
|
||||||
it.value().calls++;
|
|
||||||
it.value().duration += event.duration();
|
|
||||||
} else {
|
|
||||||
QmlStatisticsRelativesData parent = {
|
|
||||||
event.duration(),
|
|
||||||
1,
|
|
||||||
eventsInBindingLoop.contains(parentTypeIndex)
|
|
||||||
};
|
|
||||||
relativesMap.insert(parentTypeIndex, parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now lastparent is the new type
|
|
||||||
lastParent[level] = event.typeIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QmlProfilerStatisticsChildrenModel::QmlProfilerStatisticsChildrenModel(
|
|
||||||
QmlProfilerModelManager *modelManager, QmlProfilerStatisticsModel *statisticsModel,
|
|
||||||
QObject *parent) :
|
|
||||||
QmlProfilerStatisticsRelativesModel(modelManager, statisticsModel, parent)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void QmlProfilerStatisticsChildrenModel::loadData()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
QmlProfilerDataModel *simpleModel = m_modelManager->qmlModel();
|
|
||||||
if (simpleModel->isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// for level computation
|
|
||||||
QHash<int, qint64> endtimesPerLevel;
|
|
||||||
int level = Constants::QML_MIN_LEVEL;
|
|
||||||
endtimesPerLevel[0] = 0;
|
|
||||||
|
|
||||||
const QSet<int> &eventsInBindingLoop = m_statisticsModel->eventsInBindingLoop();
|
|
||||||
|
|
||||||
// compute parent-child relationship and call count
|
|
||||||
QHash<int, int> lastParent;
|
|
||||||
const QVector<QmlEvent> &eventList = simpleModel->events();
|
|
||||||
const QVector<QmlEventType> &typesList = simpleModel->eventTypes();
|
|
||||||
foreach (const QmlEvent &event, eventList) {
|
|
||||||
// whitelist
|
|
||||||
if (!m_statisticsModel->eventTypeAccepted(typesList[event.typeIndex()].rangeType))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// level computation
|
|
||||||
if (endtimesPerLevel[level] > event.timestamp()) {
|
|
||||||
level++;
|
|
||||||
} else {
|
|
||||||
while (level > Constants::QML_MIN_LEVEL &&
|
|
||||||
endtimesPerLevel[level-1] <= event.timestamp())
|
|
||||||
level--;
|
|
||||||
}
|
|
||||||
endtimesPerLevel[level] = event.timestamp() + event.duration();
|
|
||||||
|
|
||||||
int parentId = -1;
|
|
||||||
|
|
||||||
if (level > Constants::QML_MIN_LEVEL && lastParent.contains(level-1))
|
|
||||||
parentId = lastParent[level-1];
|
|
||||||
|
|
||||||
QmlStatisticsRelativesMap &relativesMap = m_data[parentId];
|
|
||||||
QmlStatisticsRelativesMap::Iterator it = relativesMap.find(event.typeIndex());
|
|
||||||
if (it != relativesMap.end()) {
|
|
||||||
it.value().calls++;
|
|
||||||
it.value().duration += event.duration();
|
|
||||||
} else {
|
|
||||||
QmlStatisticsRelativesData child = {
|
|
||||||
event.duration(),
|
|
||||||
1,
|
|
||||||
eventsInBindingLoop.contains(parentId)
|
|
||||||
};
|
|
||||||
relativesMap.insert(event.typeIndex(), child);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now lastparent is the new type
|
|
||||||
lastParent[level] = event.typeIndex();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -37,6 +37,12 @@
|
|||||||
|
|
||||||
namespace QmlProfiler {
|
namespace QmlProfiler {
|
||||||
class QmlProfilerModelManager;
|
class QmlProfilerModelManager;
|
||||||
|
class QmlProfilerStatisticsRelativesModel;
|
||||||
|
|
||||||
|
enum QmlProfilerStatisticsRelation {
|
||||||
|
QmlProfilerStatisticsChilden,
|
||||||
|
QmlProfilerStatisticsParents
|
||||||
|
};
|
||||||
|
|
||||||
class QmlProfilerStatisticsModel : public QObject
|
class QmlProfilerStatisticsModel : public QObject
|
||||||
{
|
{
|
||||||
@@ -63,7 +69,6 @@ public:
|
|||||||
~QmlProfilerStatisticsModel();
|
~QmlProfilerStatisticsModel();
|
||||||
|
|
||||||
void setEventTypeAccepted(RangeType type, bool accepted);
|
void setEventTypeAccepted(RangeType type, bool accepted);
|
||||||
bool eventTypeAccepted(RangeType) const;
|
|
||||||
|
|
||||||
const QHash<int, QmlEventStats> &getData() const;
|
const QHash<int, QmlEventStats> &getData() const;
|
||||||
const QVector<QmlEventType> &getTypes() const;
|
const QVector<QmlEventType> &getTypes() const;
|
||||||
@@ -73,6 +78,8 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
void limitToRange(qint64 rangeStart, qint64 rangeEnd);
|
void limitToRange(qint64 rangeStart, qint64 rangeEnd);
|
||||||
|
void setRelativesModel(QmlProfilerStatisticsRelativesModel *childModel,
|
||||||
|
QmlProfilerStatisticsRelation relation);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dataAvailable();
|
void dataAvailable();
|
||||||
@@ -80,7 +87,8 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void loadData(qint64 rangeStart = -1, qint64 rangeEnd = -1);
|
void loadData(qint64 rangeStart = -1, qint64 rangeEnd = -1);
|
||||||
const QSet<int> &eventsInBindingLoop() const;
|
void loadEvent(const QmlEvent &event, const QmlEventType &type);
|
||||||
|
void finalize();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void dataChanged();
|
void dataChanged();
|
||||||
@@ -89,15 +97,13 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
class QmlProfilerStatisticsModelPrivate;
|
class QmlProfilerStatisticsModelPrivate;
|
||||||
QmlProfilerStatisticsModelPrivate *d;
|
QmlProfilerStatisticsModelPrivate *d;
|
||||||
|
|
||||||
friend class QmlProfilerStatisticsParentsModel;
|
|
||||||
friend class QmlProfilerStatisticsChildrenModel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlProfilerStatisticsRelativesModel : public QObject
|
class QmlProfilerStatisticsRelativesModel : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct QmlStatisticsRelativesData {
|
struct QmlStatisticsRelativesData {
|
||||||
qint64 duration;
|
qint64 duration;
|
||||||
qint64 calls;
|
qint64 calls;
|
||||||
@@ -107,6 +113,7 @@ public:
|
|||||||
|
|
||||||
QmlProfilerStatisticsRelativesModel(QmlProfilerModelManager *modelManager,
|
QmlProfilerStatisticsRelativesModel(QmlProfilerModelManager *modelManager,
|
||||||
QmlProfilerStatisticsModel *statisticsModel,
|
QmlProfilerStatisticsModel *statisticsModel,
|
||||||
|
QmlProfilerStatisticsRelation relation,
|
||||||
QObject *parent = 0);
|
QObject *parent = 0);
|
||||||
|
|
||||||
int count() const;
|
int count() const;
|
||||||
@@ -115,42 +122,23 @@ public:
|
|||||||
const QmlStatisticsRelativesMap &getData(int typeId) const;
|
const QmlStatisticsRelativesMap &getData(int typeId) const;
|
||||||
const QVector<QmlEventType> &getTypes() const;
|
const QVector<QmlEventType> &getTypes() const;
|
||||||
|
|
||||||
protected:
|
void loadEvent(const QmlEvent &event);
|
||||||
virtual void loadData() = 0;
|
void finalize(const QSet<int> &eventsInBindingLoop);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void dataAvailable();
|
void dataAvailable();
|
||||||
|
|
||||||
protected slots:
|
|
||||||
void dataChanged();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash <int, QmlStatisticsRelativesMap> m_data;
|
QHash <int, QmlStatisticsRelativesMap> m_data;
|
||||||
QmlProfilerModelManager *m_modelManager;
|
QmlProfilerModelManager *m_modelManager;
|
||||||
QmlProfilerStatisticsModel *m_statisticsModel;
|
|
||||||
|
// for level computation
|
||||||
|
QHash<int, qint64> m_endtimesPerLevel;
|
||||||
|
int m_level = Constants::QML_MIN_LEVEL;
|
||||||
|
|
||||||
|
// compute parent-child relationship and call count
|
||||||
|
QHash<int, int> m_lastParent;
|
||||||
|
const QmlProfilerStatisticsRelation m_relation;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlProfilerStatisticsParentsModel : public QmlProfilerStatisticsRelativesModel
|
} // namespace QmlProfiler
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
QmlProfilerStatisticsParentsModel(QmlProfilerModelManager *modelManager,
|
|
||||||
QmlProfilerStatisticsModel *statisticsModel,
|
|
||||||
QObject *parent = 0);
|
|
||||||
protected:
|
|
||||||
virtual void loadData();
|
|
||||||
};
|
|
||||||
|
|
||||||
class QmlProfilerStatisticsChildrenModel : public QmlProfilerStatisticsRelativesModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
QmlProfilerStatisticsChildrenModel(QmlProfilerModelManager *modelManager,
|
|
||||||
QmlProfilerStatisticsModel *statisticsModel,
|
|
||||||
QObject *parent = 0);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void loadData();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -191,10 +191,12 @@ QmlProfilerStatisticsView::QmlProfilerStatisticsView(QWidget *parent,
|
|||||||
this, &QmlProfilerStatisticsView::typeSelected);
|
this, &QmlProfilerStatisticsView::typeSelected);
|
||||||
|
|
||||||
d->m_eventChildren = new QmlProfilerStatisticsRelativesView(
|
d->m_eventChildren = new QmlProfilerStatisticsRelativesView(
|
||||||
new QmlProfilerStatisticsChildrenModel(profilerModelManager, d->model, this),
|
new QmlProfilerStatisticsRelativesModel(profilerModelManager, d->model,
|
||||||
|
QmlProfilerStatisticsChilden, this),
|
||||||
this);
|
this);
|
||||||
d->m_eventParents = new QmlProfilerStatisticsRelativesView(
|
d->m_eventParents = new QmlProfilerStatisticsRelativesView(
|
||||||
new QmlProfilerStatisticsParentsModel(profilerModelManager, d->model, this),
|
new QmlProfilerStatisticsRelativesModel(profilerModelManager, d->model,
|
||||||
|
QmlProfilerStatisticsParents, this),
|
||||||
this);
|
this);
|
||||||
connect(d->m_eventTree, &QmlProfilerStatisticsMainView::typeSelected,
|
connect(d->m_eventTree, &QmlProfilerStatisticsMainView::typeSelected,
|
||||||
d->m_eventChildren, &QmlProfilerStatisticsRelativesView::displayType);
|
d->m_eventChildren, &QmlProfilerStatisticsRelativesView::displayType);
|
||||||
@@ -935,7 +937,7 @@ void QmlProfilerStatisticsRelativesView::clear()
|
|||||||
|
|
||||||
void QmlProfilerStatisticsRelativesView::updateHeader()
|
void QmlProfilerStatisticsRelativesView::updateHeader()
|
||||||
{
|
{
|
||||||
bool calleesView = qobject_cast<QmlProfilerStatisticsChildrenModel *>(d->model) != 0;
|
bool calleesView = qobject_cast<QmlProfilerStatisticsRelativesModel *>(d->model) != 0;
|
||||||
|
|
||||||
if (treeModel()) {
|
if (treeModel()) {
|
||||||
treeModel()->setColumnCount(5);
|
treeModel()->setColumnCount(5);
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ public slots:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void rebuildTree(const QmlProfilerStatisticsParentsModel::QmlStatisticsRelativesMap &map);
|
void rebuildTree(const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesMap &map);
|
||||||
void updateHeader();
|
void updateHeader();
|
||||||
QStandardItemModel *treeModel();
|
QStandardItemModel *treeModel();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user