QmlProfiler: Make sure animation paint events don't overlap

Previously the animation paint events could overlap if the framerate
estimates were off by more than 1 event. Furthermore the duration could
be negative or 0, with a potential crash in the latter case. Also it's
a bad idea to change the server-provided framerate to suit our estimated
durations.

Change-Id: I14da0855d7248a6ef32509572caa439ebb2d430e
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Ulf Hermann
2014-01-13 11:18:10 +01:00
parent d0e231977e
commit f10eccff3e

View File

@@ -119,44 +119,36 @@ void PaintEventsModelProxy::loadData()
const QVector<QmlProfilerSimpleModel::QmlEventData> referenceList = simpleModel->getEvents(); const QVector<QmlProfilerSimpleModel::QmlEventData> referenceList = simpleModel->getEvents();
QmlPaintEventData lastEvent; QmlPaintEventData lastEvent;
qint64 lastStartTime = -1; qint64 minNextStartTime = 0;
qint64 lastDuration = -1;
foreach (const QmlProfilerSimpleModel::QmlEventData &event, referenceList) { foreach (const QmlProfilerSimpleModel::QmlEventData &event, referenceList) {
if (!eventAccepted(event)) if (!eventAccepted(event))
continue; continue;
qint64 estimatedDuration = 0;
// initial estimation of the event duration: 1/framerate // initial estimation of the event duration: 1/framerate
if (event.numericData1 > 0) qint64 estimatedDuration = event.numericData1 > 0 ? 1e9/event.numericData1 : 1;
estimatedDuration = 1e9/event.numericData1;
// the profiler registers the animation events at the end of them // the profiler registers the animation events at the end of them
qint64 realStartTime = event.startTime - estimatedDuration; qint64 realEndTime = event.startTime;
// the duration of the events is estimated from the framerate // ranges should not overlap. If they do, our estimate wasn't accurate enough
// we need to correct it before appending a new event qint64 realStartTime = qMax(event.startTime - estimatedDuration, minNextStartTime);
if (lastStartTime != -1) {
if (lastStartTime + lastDuration >= realStartTime) {
// 1 nanosecond less to prevent overlap
lastDuration = realStartTime - lastStartTime - 1;
lastEvent.framerate = 1e9 / lastDuration;
}
}
d->insert(lastStartTime, lastDuration, lastEvent); // 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.framerate = (int)event.numericData1; lastEvent.framerate = (int)event.numericData1;
lastEvent.animationcount = (int)event.numericData2; lastEvent.animationcount = (int)event.numericData2;
lastStartTime = realStartTime; d->insert(realStartTime, realEndTime - realStartTime, lastEvent);
lastDuration = estimatedDuration;
minNextStartTime = event.startTime + 1;
m_modelManager->modelProxyCountUpdated(m_modelId, d->count(), referenceList.count()); m_modelManager->modelProxyCountUpdated(m_modelId, d->count(), referenceList.count());
} }
if (lastStartTime != -1)
d->insert(lastStartTime, lastDuration, lastEvent);
d->computeAnimationCountLimit(); d->computeAnimationCountLimit();
d->computeNesting(); d->computeNesting();