forked from qt-creator/qt-creator
QmlProfiler: switch storage for typeId and selectionId
The selectionIds are an integral part of the timeline and have to be given for each event. The typeIds are optional. Thus it makes more sense to store the selectionIds in the basic Range classes and have the derived models handle the typeIds instead of doing it the other way around. Change-Id: I824224b6f58e8d45311134887482586283fbff41 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@theqtcompany.com> Reviewed-by: Kai Koehne <kai.koehne@theqtcompany.com>
This commit is contained in:
@@ -304,10 +304,15 @@ qint64 AbstractTimelineModel::endTime(int index) const
|
||||
return d->ranges[index].start + d->ranges[index].duration;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the type ID of the event with event ID \a index. The type ID is a globally valid ID which
|
||||
can be used to communicate metainformation about events to other parts of the program. By default
|
||||
it is -1, which means there is no global type information about the event.
|
||||
*/
|
||||
int AbstractTimelineModel::typeId(int index) const
|
||||
{
|
||||
Q_D(const AbstractTimelineModel);
|
||||
return d->ranges[index].typeId;
|
||||
Q_UNUSED(index)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -374,10 +379,17 @@ QVariantMap AbstractTimelineModel::location(int index) const
|
||||
return map;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns \c true if this model can contain events of global type Id \a typeIndex. Otherwise
|
||||
returns \c false.
|
||||
*/
|
||||
bool AbstractTimelineModel::handlesTypeId(int typeIndex) const
|
||||
{
|
||||
Q_UNUSED(typeIndex);
|
||||
if (typeIndex < 0)
|
||||
return false;
|
||||
|
||||
Q_D(const AbstractTimelineModel);
|
||||
return accepted(d->modelManager->qmlModel()->getEventTypes().at(typeIndex));
|
||||
}
|
||||
|
||||
int AbstractTimelineModel::selectionIdForLocation(const QString &filename, int line, int column) const
|
||||
@@ -453,16 +465,17 @@ QColor AbstractTimelineModel::colorByHue(int hue) const
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn int AbstractTimelineModel::insert(qint64 startTime, qint64 duration)
|
||||
Inserts a range at the given time position and returns its index.
|
||||
Inserts an event at the time specified by \a startTime with the given \a duration and returns
|
||||
its index. The \a selectionId determines the selection group the new event belongs to.
|
||||
\sa selectionId()
|
||||
*/
|
||||
int AbstractTimelineModel::insert(qint64 startTime, qint64 duration, int typeId)
|
||||
int AbstractTimelineModel::insert(qint64 startTime, qint64 duration, int selectionId)
|
||||
{
|
||||
Q_D(AbstractTimelineModel);
|
||||
/* Doing insert-sort here is preferable as most of the time the times will actually be
|
||||
* presorted in the right way. So usually this will just result in appending. */
|
||||
int index = d->insertSorted(d->ranges,
|
||||
AbstractTimelineModelPrivate::Range(startTime, duration, typeId));
|
||||
AbstractTimelineModelPrivate::Range(startTime, duration, selectionId));
|
||||
if (index < d->ranges.size() - 1)
|
||||
d->incrementStartIndices(index);
|
||||
d->insertSorted(d->endTimes,
|
||||
@@ -471,15 +484,15 @@ int AbstractTimelineModel::insert(qint64 startTime, qint64 duration, int typeId)
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn int AbstractTimelineModel::insertStart(qint64 startTime, int typeId)
|
||||
Inserts the given data as range start at the given time position and
|
||||
returns its index. The range end is not set.
|
||||
Inserts a range start at the time given by \a startTime and returns its index. The range end is
|
||||
not set. The \a selectionId determines the selection group the new event belongs to.
|
||||
\sa selectionId()
|
||||
*/
|
||||
int AbstractTimelineModel::insertStart(qint64 startTime, int typeId)
|
||||
int AbstractTimelineModel::insertStart(qint64 startTime, int selectionId)
|
||||
{
|
||||
Q_D(AbstractTimelineModel);
|
||||
int index = d->insertSorted(d->ranges,
|
||||
AbstractTimelineModelPrivate::Range(startTime, 0, typeId));
|
||||
AbstractTimelineModelPrivate::Range(startTime, 0, selectionId));
|
||||
if (index < d->ranges.size() - 1)
|
||||
d->incrementStartIndices(index);
|
||||
return index;
|
||||
@@ -567,10 +580,18 @@ int AbstractTimelineModel::rowCount() const
|
||||
return d->expanded ? d->expandedRowCount : d->collapsedRowCount;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the ID of the selection group the event with event Id \a index belongs to. Selection
|
||||
groups are local to the model and the model can arbitrarily assign events to selection groups
|
||||
when inserting them.
|
||||
If one event from a selection group is selected, all visible other events from the same
|
||||
selection group are highlighted. Rows are expected to correspond to selection IDs when the view
|
||||
is expanded.
|
||||
*/
|
||||
int AbstractTimelineModel::selectionId(int index) const
|
||||
{
|
||||
Q_D(const AbstractTimelineModel);
|
||||
return d->ranges[index].typeId;
|
||||
return d->ranges[index].selectionId;
|
||||
}
|
||||
|
||||
void AbstractTimelineModel::clear()
|
||||
|
||||
@@ -73,13 +73,12 @@ public:
|
||||
qint64 duration(int index) const;
|
||||
qint64 startTime(int index) const;
|
||||
qint64 endTime(int index) const;
|
||||
int typeId(int index) const;
|
||||
int selectionId(int index) const;
|
||||
|
||||
int firstIndex(qint64 startTime) const;
|
||||
int firstIndexNoParents(qint64 startTime) const;
|
||||
int lastIndex(qint64 endTime) const;
|
||||
|
||||
bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const;
|
||||
bool expanded() const;
|
||||
bool hidden() const;
|
||||
void setExpanded(bool expanded);
|
||||
@@ -97,8 +96,9 @@ public:
|
||||
// Methods which can optionally be implemented by child models.
|
||||
// returned map should contain "file", "line", "column" properties, or be empty
|
||||
virtual QVariantMap location(int index) const;
|
||||
virtual int selectionId(int index) const;
|
||||
virtual int typeId(int index) const;
|
||||
virtual bool handlesTypeId(int typeId) const;
|
||||
virtual bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const;
|
||||
virtual int selectionIdForLocation(const QString &filename, int line, int column) const;
|
||||
virtual int bindingLoopDest(int index) const;
|
||||
virtual float relativeHeight(int index) const;
|
||||
@@ -120,8 +120,8 @@ protected:
|
||||
QColor colorByFraction(double fraction) const;
|
||||
QColor colorByHue(int hue) const;
|
||||
|
||||
int insert(qint64 startTime, qint64 duration, int typeId);
|
||||
int insertStart(qint64 startTime, int typeId);
|
||||
int insert(qint64 startTime, qint64 duration, int selectionId);
|
||||
int insertStart(qint64 startTime, int selectionId);
|
||||
void insertEnd(int index, qint64 duration);
|
||||
void computeNesting();
|
||||
|
||||
|
||||
@@ -48,12 +48,12 @@ public:
|
||||
};
|
||||
|
||||
struct Range {
|
||||
Range() : start(-1), duration(-1), typeId(-1), parent(-1) {}
|
||||
Range(qint64 start, qint64 duration, int typeId) :
|
||||
start(start), duration(duration), typeId(typeId), parent(-1) {}
|
||||
Range() : start(-1), duration(-1), selectionId(-1), parent(-1) {}
|
||||
Range(qint64 start, qint64 duration, int selectionId) :
|
||||
start(start), duration(duration), selectionId(selectionId), parent(-1) {}
|
||||
qint64 start;
|
||||
qint64 duration;
|
||||
int typeId;
|
||||
int selectionId;
|
||||
int parent;
|
||||
inline qint64 timestamp() const {return start;}
|
||||
};
|
||||
|
||||
@@ -82,6 +82,7 @@ void QmlProfilerAnimationsModel::loadData()
|
||||
const QVector<QmlProfilerDataModel::QmlEventData> &referenceList = simpleModel->getEvents();
|
||||
const QVector<QmlProfilerDataModel::QmlEventTypeData> &typeList = simpleModel->getEventTypes();
|
||||
|
||||
QmlDebug::AnimationThread lastThread;
|
||||
QmlPaintEventData lastEvent;
|
||||
qint64 minNextStartTimes[] = {0, 0};
|
||||
|
||||
@@ -90,7 +91,7 @@ void QmlProfilerAnimationsModel::loadData()
|
||||
if (!accepted(type))
|
||||
continue;
|
||||
|
||||
lastEvent.threadId = (QmlDebug::AnimationThread)event.numericData3;
|
||||
lastThread = (QmlDebug::AnimationThread)event.numericData3;
|
||||
|
||||
// initial estimation of the event duration: 1/framerate
|
||||
qint64 estimatedDuration = event.numericData1 > 0 ? 1e9/event.numericData1 : 1;
|
||||
@@ -99,7 +100,7 @@ void QmlProfilerAnimationsModel::loadData()
|
||||
qint64 realEndTime = event.startTime;
|
||||
|
||||
// ranges should not overlap. If they do, our estimate wasn't accurate enough
|
||||
qint64 realStartTime = qMax(event.startTime - estimatedDuration, minNextStartTimes[lastEvent.threadId]);
|
||||
qint64 realStartTime = qMax(event.startTime - estimatedDuration, minNextStartTimes[lastThread]);
|
||||
|
||||
// Sometimes our estimate is far off or the server has miscalculated the frame rate
|
||||
if (realStartTime >= realEndTime)
|
||||
@@ -107,18 +108,19 @@ void QmlProfilerAnimationsModel::loadData()
|
||||
|
||||
// Don't "fix" the framerate even if we've fixed the duration.
|
||||
// The server should know better after all and if it doesn't we want to see that.
|
||||
lastEvent.typeId = event.typeIndex;
|
||||
lastEvent.framerate = (int)event.numericData1;
|
||||
lastEvent.animationcount = (int)event.numericData2;
|
||||
QTC_ASSERT(lastEvent.animationcount > 0, continue);
|
||||
|
||||
m_data.insert(insert(realStartTime, realEndTime - realStartTime, event.typeIndex), lastEvent);
|
||||
m_data.insert(insert(realStartTime, realEndTime - realStartTime, lastThread), lastEvent);
|
||||
|
||||
if (lastEvent.threadId == QmlDebug::GuiThread)
|
||||
if (lastThread == QmlDebug::GuiThread)
|
||||
m_maxGuiThreadAnimations = qMax(lastEvent.animationcount, m_maxGuiThreadAnimations);
|
||||
else
|
||||
m_maxRenderThreadAnimations = qMax(lastEvent.animationcount, m_maxRenderThreadAnimations);
|
||||
|
||||
minNextStartTimes[lastEvent.threadId] = event.startTime + 1;
|
||||
minNextStartTimes[lastThread] = event.startTime + 1;
|
||||
|
||||
updateProgress(count(), referenceList.count());
|
||||
}
|
||||
@@ -131,14 +133,14 @@ void QmlProfilerAnimationsModel::loadData()
|
||||
|
||||
/////////////////// QML interface
|
||||
|
||||
int QmlProfilerAnimationsModel::rowFromThreadId(QmlDebug::AnimationThread threadId) const
|
||||
int QmlProfilerAnimationsModel::rowFromThreadId(int threadId) const
|
||||
{
|
||||
return (threadId == QmlDebug::GuiThread || m_maxGuiThreadAnimations == 0) ? 1 : 2;
|
||||
}
|
||||
|
||||
int QmlProfilerAnimationsModel::row(int index) const
|
||||
{
|
||||
return rowFromThreadId(m_data[index].threadId);
|
||||
return rowFromThreadId(selectionId(index));
|
||||
}
|
||||
|
||||
int QmlProfilerAnimationsModel::rowMaxValue(int rowNumber) const
|
||||
@@ -153,9 +155,9 @@ int QmlProfilerAnimationsModel::rowMaxValue(int rowNumber) const
|
||||
}
|
||||
}
|
||||
|
||||
int QmlProfilerAnimationsModel::selectionId(int index) const
|
||||
int QmlProfilerAnimationsModel::typeId(int index) const
|
||||
{
|
||||
return m_data[index].threadId;
|
||||
return m_data[index].typeId;
|
||||
}
|
||||
|
||||
QColor QmlProfilerAnimationsModel::color(int index) const
|
||||
@@ -170,15 +172,15 @@ QColor QmlProfilerAnimationsModel::color(int index) const
|
||||
|
||||
float QmlProfilerAnimationsModel::relativeHeight(int index) const
|
||||
{
|
||||
const QmlPaintEventData &data = m_data[index];
|
||||
const int thread = selectionId(index);
|
||||
|
||||
// Add some height to the events if we're far from the scale threshold of 2 * DefaultRowHeight.
|
||||
// Like that you can see the smaller events more easily.
|
||||
int scaleThreshold = 2 * defaultRowHeight() - rowHeight(rowFromThreadId(data.threadId));
|
||||
int scaleThreshold = 2 * defaultRowHeight() - rowHeight(rowFromThreadId(thread));
|
||||
float boost = scaleThreshold > 0 ? (0.15 * scaleThreshold / defaultRowHeight()) : 0;
|
||||
|
||||
return boost + (1.0 - boost) * (float)data.animationcount /
|
||||
(float)(data.threadId == QmlDebug::GuiThread ? m_maxGuiThreadAnimations :
|
||||
return boost + (1.0 - boost) * (float)m_data[index].animationcount /
|
||||
(float)(thread == QmlDebug::GuiThread ? m_maxGuiThreadAnimations :
|
||||
m_maxRenderThreadAnimations);
|
||||
}
|
||||
|
||||
@@ -213,8 +215,8 @@ QVariantMap QmlProfilerAnimationsModel::details(int index) const
|
||||
result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(duration(index)));
|
||||
result.insert(tr("Framerate"), QString::fromLatin1("%1 FPS").arg(m_data[index].framerate));
|
||||
result.insert(tr("Animations"), QString::fromLatin1("%1").arg(m_data[index].animationcount));
|
||||
result.insert(tr("Context"), tr(m_data[index].threadId == QmlDebug::GuiThread ?
|
||||
"GUI Thread" : "Render Thread"));
|
||||
result.insert(tr("Context"), tr(selectionId(index) == QmlDebug::GuiThread ? "GUI Thread" :
|
||||
"Render Thread"));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,14 +57,14 @@ public:
|
||||
struct QmlPaintEventData {
|
||||
int framerate;
|
||||
int animationcount;
|
||||
QmlDebug::AnimationThread threadId;
|
||||
int typeId;
|
||||
};
|
||||
|
||||
QmlProfilerAnimationsModel(QObject *parent = 0);
|
||||
|
||||
int rowMaxValue(int rowNumber) const;
|
||||
|
||||
int selectionId(int index) const;
|
||||
int typeId(int index) const;
|
||||
int row(int index) const;
|
||||
|
||||
QColor color(int index) const;
|
||||
@@ -84,7 +84,7 @@ private:
|
||||
QVector<QmlProfilerAnimationsModel::QmlPaintEventData> m_data;
|
||||
int m_maxGuiThreadAnimations;
|
||||
int m_maxRenderThreadAnimations;
|
||||
int rowFromThreadId(QmlDebug::AnimationThread threadId) const;
|
||||
int rowFromThreadId(int threadId) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -259,15 +259,9 @@ QVariantMap QmlProfilerRangeModel::location(int index) const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QmlProfilerRangeModel::handlesTypeId(int typeId) const
|
||||
int QmlProfilerRangeModel::typeId(int index) const
|
||||
{
|
||||
if (typeId < 0)
|
||||
return false;
|
||||
const QmlProfilerDataModel::QmlEventTypeData &type =
|
||||
modelManager()->qmlModel()->getEventTypes().at(typeId);
|
||||
if (type.message != message() || type.rangeType != rangeType())
|
||||
return false;
|
||||
return true;
|
||||
return selectionId(index);
|
||||
}
|
||||
|
||||
int QmlProfilerRangeModel::selectionIdForLocation(const QString &filename, int line, int column) const
|
||||
|
||||
@@ -74,7 +74,7 @@ public:
|
||||
QVariantMap details(int index) const;
|
||||
QVariantMap location(int index) const;
|
||||
|
||||
bool handlesTypeId(int typeIndex) const;
|
||||
int typeId(int index) const;
|
||||
int selectionIdForLocation(const QString &filename, int line, int column) const;
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user