QmlProfiler: Load the timeline model data event by event

All the models do the same thing when loading the data: They iterate
the list of events, determine for each one if they accept it, and if
so, they load it. After the list has been fully loaded, they do some
finalization. This can be centralized, and ultimately we won't need to
expose the central QVector<QmlEvent> for that anymore.

Change-Id: Ia82facfdc3968200bbec323a02f2fcc02ac44e9e
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Ulf Hermann
2016-04-26 13:23:35 +02:00
parent 67378a7928
commit 5ba6f04d4b
16 changed files with 460 additions and 496 deletions

View File

@@ -44,11 +44,11 @@ QmlProfilerAnimationsModel::QmlProfilerAnimationsModel(QmlProfilerModelManager *
QObject *parent) :
QmlProfilerTimelineModel(manager, Event, MaximumRangeType, ProfileAnimations, parent)
{
m_maxGuiThreadAnimations = m_maxRenderThreadAnimations = 0;
}
void QmlProfilerAnimationsModel::clear()
{
m_minNextStartTimes[0] = m_minNextStartTimes[1] = 0;
m_maxGuiThreadAnimations = m_maxRenderThreadAnimations = 0;
m_data.clear();
QmlProfilerTimelineModel::clear();
@@ -59,59 +59,46 @@ bool QmlProfilerAnimationsModel::accepted(const QmlEventType &event) const
return QmlProfilerTimelineModel::accepted(event) && event.detailType == AnimationFrame;
}
void QmlProfilerAnimationsModel::loadData()
void QmlProfilerAnimationsModel::loadEvent(const QmlEvent &event, const QmlEventType &type)
{
QmlProfilerDataModel *simpleModel = modelManager()->qmlModel();
if (simpleModel->isEmpty())
return;
Q_UNUSED(type);
AnimationThread lastThread = (AnimationThread)event.number<qint32>(2);
// collect events
const QVector<QmlEvent> &referenceList = simpleModel->events();
const QVector<QmlEventType> &typeList = simpleModel->eventTypes();
// initial estimation of the event duration: 1/framerate
qint64 estimatedDuration = event.number<qint32>(0) > 0 ? 1e9 / event.number<qint32>(0) : 1;
AnimationThread lastThread;
// the profiler registers the animation events at the end of them
qint64 realEndTime = event.timestamp();
// ranges should not overlap. If they do, our estimate wasn't accurate enough
qint64 realStartTime = qMax(event.timestamp() - estimatedDuration,
m_minNextStartTimes[lastThread]);
// Sometimes our estimate is far off or the server has miscalculated the frame rate
if (realStartTime >= realEndTime)
realEndTime = realStartTime + 1;
// 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.
QmlPaintEventData lastEvent;
qint64 minNextStartTimes[] = {0, 0};
lastEvent.typeId = event.typeIndex();
lastEvent.framerate = event.number<qint32>(0);
lastEvent.animationcount = event.number<qint32>(1);
QTC_ASSERT(lastEvent.animationcount > 0, return);
foreach (const QmlEvent &event, referenceList) {
const QmlEventType &type = typeList[event.typeIndex()];
if (!accepted(type))
continue;
m_data.insert(insert(realStartTime, realEndTime - realStartTime, lastThread), lastEvent);
lastThread = (AnimationThread)event.number<qint32>(2);
if (lastThread == GuiThread)
m_maxGuiThreadAnimations = qMax(lastEvent.animationcount, m_maxGuiThreadAnimations);
else
m_maxRenderThreadAnimations = qMax(lastEvent.animationcount,
m_maxRenderThreadAnimations);
// initial estimation of the event duration: 1/framerate
qint64 estimatedDuration = event.number<qint32>(0) > 0 ? 1e9 / event.number<qint32>(0) : 1;
// the profiler registers the animation events at the end of them
qint64 realEndTime = event.timestamp();
// ranges should not overlap. If they do, our estimate wasn't accurate enough
qint64 realStartTime = qMax(event.timestamp() - estimatedDuration,
minNextStartTimes[lastThread]);
// Sometimes our estimate is far off or the server has miscalculated the frame rate
if (realStartTime >= realEndTime)
realEndTime = realStartTime + 1;
// 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 = event.number<qint32>(0);
lastEvent.animationcount = event.number<qint32>(1);
QTC_ASSERT(lastEvent.animationcount > 0, continue);
m_data.insert(insert(realStartTime, realEndTime - realStartTime, lastThread), lastEvent);
if (lastThread == GuiThread)
m_maxGuiThreadAnimations = qMax(lastEvent.animationcount, m_maxGuiThreadAnimations);
else
m_maxRenderThreadAnimations = qMax(lastEvent.animationcount,
m_maxRenderThreadAnimations);
minNextStartTimes[lastThread] = event.timestamp() + 1;
}
m_minNextStartTimes[lastThread] = event.timestamp() + 1;
}
void QmlProfilerAnimationsModel::finalize()
{
computeNesting();
setExpandedRowCount((m_maxGuiThreadAnimations == 0 || m_maxRenderThreadAnimations == 0) ? 2 : 3);
setCollapsedRowCount(expandedRowCount());