forked from qt-creator/qt-creator
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:
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user