forked from qt-creator/qt-creator
QmlProfiler: load and save extra data
Change-Id: I97a9bc3c86b330015d1c40850eabbcfa37088521 Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
committed by
Kai Koehne
parent
bf467e258b
commit
483e607f27
@@ -190,6 +190,8 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
|
||||
while (!stream.atEnd()) {
|
||||
stream >> params[count++];
|
||||
}
|
||||
while (count<5)
|
||||
params[count++] = 0;
|
||||
emit sceneGraphFrame(SceneGraphFrameEvent, sgEventType, time, params[0], params[1], params[2], params[3], params[4]);
|
||||
} else if (messageType == PixmapCacheEvent) {
|
||||
int pixEvTy, width = -1, height = -1, refcount = -1;
|
||||
|
@@ -302,7 +302,11 @@ void QmlProfilerModelManager::load()
|
||||
SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)));
|
||||
connect(&reader, SIGNAL(traceStartTime(qint64)), traceTime(), SLOT(setStartTime(qint64)));
|
||||
connect(&reader, SIGNAL(traceEndTime(qint64)), traceTime(), SLOT(setEndTime(qint64)));
|
||||
|
||||
connect(&reader, SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64)),
|
||||
this, SLOT(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64)));
|
||||
connect(&reader, SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)),
|
||||
this, SLOT(addPixmapCacheEvent(qint64,int,QString,int,int,int)));
|
||||
connect(&reader, SIGNAL(frame(qint64,int,int)), this, SLOT(addFrameEvent(qint64,int,int)));
|
||||
reader.setV8DataModel(d->v8Model);
|
||||
reader.load(&file);
|
||||
|
||||
|
@@ -151,19 +151,22 @@ void PaintEventsModelProxy::loadData()
|
||||
if (!eventAccepted(event))
|
||||
continue;
|
||||
|
||||
// the profiler registers the animation events at the end of them
|
||||
qint64 realStartTime = event.startTime - event.duration;
|
||||
|
||||
// the duration of the events is estimated from the framerate
|
||||
// we need to correct it before appending a new event
|
||||
if (d->eventList.count() > 0) {
|
||||
QmlPaintEventData *lastEvent = &d->eventList[d->eventList.count()-1];
|
||||
if (lastEvent->startTime + lastEvent->duration >= event.startTime) {
|
||||
if (lastEvent->startTime + lastEvent->duration >= realStartTime) {
|
||||
// 1 nanosecond less to prevent overlap
|
||||
lastEvent->duration = event.startTime - lastEvent->startTime - 1;
|
||||
lastEvent->duration = realStartTime - lastEvent->startTime - 1;
|
||||
lastEvent->framerate = 1e9/lastEvent->duration;
|
||||
}
|
||||
}
|
||||
|
||||
QmlPaintEventData newEvent = {
|
||||
event.startTime,
|
||||
realStartTime,
|
||||
event.duration,
|
||||
(int)event.numericData1,
|
||||
(int)event.numericData2
|
||||
|
@@ -78,7 +78,7 @@ void QmlProfilerSimpleModel::addRangedEvent(int type, int bindingType, qint64 st
|
||||
void QmlProfilerSimpleModel::addFrameEvent(qint64 time, int framerate, int animationcount)
|
||||
{
|
||||
qint64 duration = 1e9 / framerate;
|
||||
QmlEventData eventData = {tr("Animations"), QmlDebug::Painting, QmlDebug::AnimationFrame, time - duration, duration, QStringList(), QmlDebug::QmlEventLocation(), framerate, animationcount, 0, 0, 0};
|
||||
QmlEventData eventData = {tr("Animations"), QmlDebug::Painting, QmlDebug::AnimationFrame, time, duration, QStringList(), QmlDebug::QmlEventLocation(), framerate, animationcount, 0, 0, 0};
|
||||
eventList.append(eventData);
|
||||
}
|
||||
|
||||
@@ -110,11 +110,12 @@ void QmlProfilerSimpleModel::complete()
|
||||
|
||||
QString QmlProfilerSimpleModel::getHashString(const QmlProfilerSimpleModel::QmlEventData &event)
|
||||
{
|
||||
return QString::fromLatin1("%1:%2:%3:%4").arg(
|
||||
return QString::fromLatin1("%1:%2:%3:%4:%5").arg(
|
||||
event.location.filename,
|
||||
QString::number(event.location.line),
|
||||
QString::number(event.location.column),
|
||||
QString::number(event.eventType));
|
||||
QString::number(event.eventType),
|
||||
QString::number(event.bindingType));
|
||||
}
|
||||
|
||||
|
||||
|
@@ -48,6 +48,8 @@ const char TYPE_COMPILING_STR[] = "Compiling";
|
||||
const char TYPE_CREATING_STR[] = "Creating";
|
||||
const char TYPE_BINDING_STR[] = "Binding";
|
||||
const char TYPE_HANDLINGSIGNAL_STR[] = "HandlingSignal";
|
||||
const char TYPE_PIXMAPCACHE_STR[] = "PixmapCache";
|
||||
const char TYPE_SCENEGRAPH_STR[] = "SceneGraph";
|
||||
|
||||
#define _(X) QLatin1String(X)
|
||||
|
||||
@@ -71,6 +73,10 @@ static QmlEventType qmlEventTypeAsEnum(const QString &typeString)
|
||||
return Binding;
|
||||
} else if (typeString == _(TYPE_HANDLINGSIGNAL_STR)) {
|
||||
return HandlingSignal;
|
||||
} else if (typeString == _(TYPE_PIXMAPCACHE_STR)) {
|
||||
return PixmapCacheEvent;
|
||||
} else if (typeString == _(TYPE_SCENEGRAPH_STR)) {
|
||||
return SceneGraphFrameEvent;
|
||||
} else {
|
||||
bool isNumber = false;
|
||||
int type = typeString.toUInt(&isNumber);
|
||||
@@ -99,6 +105,12 @@ static QString qmlEventTypeAsString(QmlEventType typeEnum)
|
||||
case HandlingSignal:
|
||||
return _(TYPE_HANDLINGSIGNAL_STR);
|
||||
break;
|
||||
case PixmapCacheEvent:
|
||||
return _(TYPE_PIXMAPCACHE_STR);
|
||||
break;
|
||||
case SceneGraphFrameEvent:
|
||||
return _(TYPE_SCENEGRAPH_STR);
|
||||
break;
|
||||
default:
|
||||
return QString::number((int)typeEnum);
|
||||
}
|
||||
@@ -249,7 +261,10 @@ void QmlProfilerFileReader::loadEventData(QXmlStreamReader &stream)
|
||||
break;
|
||||
}
|
||||
|
||||
if (elementName == _("bindingType")) {
|
||||
if (elementName == _("bindingType") ||
|
||||
elementName == _("animationFrame") ||
|
||||
elementName == _("cacheEventType") ||
|
||||
elementName == _("sgEventType")) {
|
||||
event.bindingType = readData.toInt();
|
||||
break;
|
||||
}
|
||||
@@ -288,20 +303,45 @@ void QmlProfilerFileReader::loadProfilerDataModel(QXmlStreamReader &stream)
|
||||
switch (token) {
|
||||
case QXmlStreamReader::StartElement: {
|
||||
if (elementName == _("range")) {
|
||||
Range range = { 0, 0 };
|
||||
Range range = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
const QXmlStreamAttributes attributes = stream.attributes();
|
||||
if (!attributes.hasAttribute(_("startTime"))
|
||||
|| !attributes.hasAttribute(_("duration"))
|
||||
|| !attributes.hasAttribute(_("eventIndex"))) {
|
||||
// ignore incomplete entry
|
||||
continue;
|
||||
}
|
||||
|
||||
range.startTime = attributes.value(_("startTime")).toString().toLongLong();
|
||||
range.duration = attributes.value(_("duration")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("duration")))
|
||||
range.duration = attributes.value(_("duration")).toString().toLongLong();
|
||||
|
||||
// attributes for special events
|
||||
if (attributes.hasAttribute(_("framerate")))
|
||||
range.numericData1 = attributes.value(_("framerate")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("animationcount")))
|
||||
range.numericData2 = attributes.value(_("animationcount")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("width")))
|
||||
range.numericData1 = attributes.value(_("width")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("height")))
|
||||
range.numericData2 = attributes.value(_("height")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("refCount")))
|
||||
range.numericData3 = attributes.value(_("refCount")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("timing1")))
|
||||
range.numericData1 = attributes.value(_("timing1")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("timing2")))
|
||||
range.numericData2 = attributes.value(_("timing2")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("timing3")))
|
||||
range.numericData3 = attributes.value(_("timing3")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("timing4")))
|
||||
range.numericData4 = attributes.value(_("timing4")).toString().toLongLong();
|
||||
if (attributes.hasAttribute(_("timing5")))
|
||||
range.numericData5 = attributes.value(_("timing5")).toString().toLongLong();
|
||||
|
||||
|
||||
int eventIndex = attributes.value(_("eventIndex")).toString().toInt();
|
||||
|
||||
|
||||
m_ranges.append(QPair<Range,int>(range, eventIndex));
|
||||
}
|
||||
break;
|
||||
@@ -332,10 +372,18 @@ void QmlProfilerFileReader::processQmlEvents()
|
||||
|
||||
QmlEvent &event = m_qmlEvents[eventIndex];
|
||||
|
||||
emit rangedEvent(event.type, event.bindingType, range.startTime, range.duration,
|
||||
if (event.type == Painting && event.bindingType == QmlDebug::AnimationFrame) {
|
||||
emit frame(range.startTime, range.numericData1, range.numericData2);
|
||||
} else if (event.type == PixmapCacheEvent) {
|
||||
emit pixmapCacheEvent(range.startTime, event.bindingType, event.filename, range.numericData1, range.numericData2, range.numericData3);
|
||||
} else if (event.type == SceneGraphFrameEvent) {
|
||||
emit sceneGraphFrame(SceneGraphFrameEvent, event.bindingType, range.startTime, range.numericData1, range.numericData2, range.numericData3, range.numericData4, range.numericData5);
|
||||
} else {
|
||||
emit rangedEvent(event.type, event.bindingType, range.startTime, range.duration,
|
||||
QStringList(event.displayName), QmlEventLocation(event.filename,
|
||||
event.line,
|
||||
event.column));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +425,7 @@ void QmlProfilerFileWriter::setQmlEvents(const QVector<QmlProfilerSimpleModel::Q
|
||||
m_qmlEvents.insert(hashStr, e);
|
||||
}
|
||||
|
||||
Range r = { event.startTime, event.duration, };
|
||||
Range r = { event.startTime, event.duration, event.numericData1, event.numericData2, event.numericData3, event.numericData4, event.numericData5 };
|
||||
m_ranges.append(QPair<Range, QString>(r, hashStr));
|
||||
}
|
||||
|
||||
@@ -415,7 +463,13 @@ void QmlProfilerFileWriter::save(QIODevice *device)
|
||||
}
|
||||
stream.writeTextElement(_("details"), event.details);
|
||||
if (event.type == Binding)
|
||||
stream.writeTextElement(_("bindingType"), QString::number((int)event.bindingType));
|
||||
stream.writeTextElement(_("bindingType"), QString::number(event.bindingType));
|
||||
if (event.type == Painting && event.bindingType == AnimationFrame)
|
||||
stream.writeTextElement(_("animationFrame"), QString::number(event.bindingType));
|
||||
if (event.type == PixmapCacheEvent)
|
||||
stream.writeTextElement(_("cacheEventType"), QString::number(event.bindingType));
|
||||
if (event.type == SceneGraphFrameEvent)
|
||||
stream.writeTextElement(_("sgEventType"), QString::number(event.bindingType));
|
||||
stream.writeEndElement();
|
||||
}
|
||||
stream.writeEndElement(); // eventData
|
||||
@@ -429,10 +483,45 @@ void QmlProfilerFileWriter::save(QIODevice *device)
|
||||
|
||||
stream.writeStartElement(_("range"));
|
||||
stream.writeAttribute(_("startTime"), QString::number(range.startTime));
|
||||
stream.writeAttribute(_("duration"), QString::number(range.duration));
|
||||
if (range.duration > 0) // no need to store duration of instantaneous events
|
||||
stream.writeAttribute(_("duration"), QString::number(range.duration));
|
||||
stream.writeAttribute(_("eventIndex"), QString::number(m_qmlEvents.keys().indexOf(eventHash)));
|
||||
|
||||
QmlEvent event = m_qmlEvents.value(eventHash);
|
||||
|
||||
// special: animation event
|
||||
if (event.type == QmlDebug::Painting && event.bindingType == QmlDebug::AnimationFrame) {
|
||||
|
||||
stream.writeAttribute(_("framerate"), QString::number(range.numericData1));
|
||||
stream.writeAttribute(_("animationcount"), QString::number(range.numericData2));
|
||||
}
|
||||
|
||||
// special: pixmap cache event
|
||||
if (event.type == QmlDebug::PixmapCacheEvent) {
|
||||
// pixmap image size
|
||||
if (event.bindingType == 0) {
|
||||
stream.writeAttribute(_("width"), QString::number(range.numericData1));
|
||||
stream.writeAttribute(_("height"), QString::number(range.numericData2));
|
||||
}
|
||||
|
||||
// reference count (1) / cache size changed (2)
|
||||
if (event.bindingType == 1 || event.bindingType == 2)
|
||||
stream.writeAttribute(_("refCount"), QString::number(range.numericData3));
|
||||
}
|
||||
|
||||
if (event.type == QmlDebug::SceneGraphFrameEvent) {
|
||||
// special: scenegraph frame events
|
||||
if (range.numericData1 > 0)
|
||||
stream.writeAttribute(_("timing1"), QString::number(range.numericData1));
|
||||
if (range.numericData2 > 0)
|
||||
stream.writeAttribute(_("timing2"), QString::number(range.numericData2));
|
||||
if (range.numericData3 > 0)
|
||||
stream.writeAttribute(_("timing3"), QString::number(range.numericData3));
|
||||
if (range.numericData4 > 0)
|
||||
stream.writeAttribute(_("timing4"), QString::number(range.numericData4));
|
||||
if (range.numericData5 > 0)
|
||||
stream.writeAttribute(_("timing5"), QString::number(range.numericData5));
|
||||
}
|
||||
// if (event.type == QmlDebug::Painting && range.animationCount >= 0) {
|
||||
// // animation frame
|
||||
// stream.writeAttribute(_("framerate"), QString::number(rangedEvent.frameRate));
|
||||
|
@@ -61,6 +61,13 @@ struct QmlEvent {
|
||||
struct Range {
|
||||
qint64 startTime;
|
||||
qint64 duration;
|
||||
|
||||
// numeric data used by animations, pixmap cache, scenegraph
|
||||
qint64 numericData1;
|
||||
qint64 numericData2;
|
||||
qint64 numericData3;
|
||||
qint64 numericData4;
|
||||
qint64 numericData5;
|
||||
};
|
||||
|
||||
class QmlProfilerFileReader : public QObject
|
||||
@@ -80,7 +87,9 @@ signals:
|
||||
|
||||
void rangedEvent(int type, int bindingType, qint64 startTime, qint64 length,
|
||||
const QStringList &data, const QmlDebug::QmlEventLocation &location);
|
||||
|
||||
void frame(qint64 time, int frameRate, int animationCount);
|
||||
void sceneGraphFrame(int eventType, int sgEventType, qint64 time, qint64 param1, qint64 param2, qint64 param3, qint64 param4, qint64 param5);
|
||||
void pixmapCacheEvent(qint64 time, int cacheEventType, const QString& url, int width, int height, int refCount);
|
||||
void error(const QString &error);
|
||||
|
||||
private:
|
||||
|
Reference in New Issue
Block a user