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()) {
|
while (!stream.atEnd()) {
|
||||||
stream >> params[count++];
|
stream >> params[count++];
|
||||||
}
|
}
|
||||||
|
while (count<5)
|
||||||
|
params[count++] = 0;
|
||||||
emit sceneGraphFrame(SceneGraphFrameEvent, sgEventType, time, params[0], params[1], params[2], params[3], params[4]);
|
emit sceneGraphFrame(SceneGraphFrameEvent, sgEventType, time, params[0], params[1], params[2], params[3], params[4]);
|
||||||
} else if (messageType == PixmapCacheEvent) {
|
} else if (messageType == PixmapCacheEvent) {
|
||||||
int pixEvTy, width = -1, height = -1, refcount = -1;
|
int pixEvTy, width = -1, height = -1, refcount = -1;
|
||||||
|
@@ -302,7 +302,11 @@ void QmlProfilerModelManager::load()
|
|||||||
SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)));
|
SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)));
|
||||||
connect(&reader, SIGNAL(traceStartTime(qint64)), traceTime(), SLOT(setStartTime(qint64)));
|
connect(&reader, SIGNAL(traceStartTime(qint64)), traceTime(), SLOT(setStartTime(qint64)));
|
||||||
connect(&reader, SIGNAL(traceEndTime(qint64)), traceTime(), SLOT(setEndTime(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.setV8DataModel(d->v8Model);
|
||||||
reader.load(&file);
|
reader.load(&file);
|
||||||
|
|
||||||
|
@@ -151,19 +151,22 @@ void PaintEventsModelProxy::loadData()
|
|||||||
if (!eventAccepted(event))
|
if (!eventAccepted(event))
|
||||||
continue;
|
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
|
// the duration of the events is estimated from the framerate
|
||||||
// we need to correct it before appending a new event
|
// we need to correct it before appending a new event
|
||||||
if (d->eventList.count() > 0) {
|
if (d->eventList.count() > 0) {
|
||||||
QmlPaintEventData *lastEvent = &d->eventList[d->eventList.count()-1];
|
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
|
// 1 nanosecond less to prevent overlap
|
||||||
lastEvent->duration = event.startTime - lastEvent->startTime - 1;
|
lastEvent->duration = realStartTime - lastEvent->startTime - 1;
|
||||||
lastEvent->framerate = 1e9/lastEvent->duration;
|
lastEvent->framerate = 1e9/lastEvent->duration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QmlPaintEventData newEvent = {
|
QmlPaintEventData newEvent = {
|
||||||
event.startTime,
|
realStartTime,
|
||||||
event.duration,
|
event.duration,
|
||||||
(int)event.numericData1,
|
(int)event.numericData1,
|
||||||
(int)event.numericData2
|
(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)
|
void QmlProfilerSimpleModel::addFrameEvent(qint64 time, int framerate, int animationcount)
|
||||||
{
|
{
|
||||||
qint64 duration = 1e9 / framerate;
|
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);
|
eventList.append(eventData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,11 +110,12 @@ void QmlProfilerSimpleModel::complete()
|
|||||||
|
|
||||||
QString QmlProfilerSimpleModel::getHashString(const QmlProfilerSimpleModel::QmlEventData &event)
|
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,
|
event.location.filename,
|
||||||
QString::number(event.location.line),
|
QString::number(event.location.line),
|
||||||
QString::number(event.location.column),
|
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_CREATING_STR[] = "Creating";
|
||||||
const char TYPE_BINDING_STR[] = "Binding";
|
const char TYPE_BINDING_STR[] = "Binding";
|
||||||
const char TYPE_HANDLINGSIGNAL_STR[] = "HandlingSignal";
|
const char TYPE_HANDLINGSIGNAL_STR[] = "HandlingSignal";
|
||||||
|
const char TYPE_PIXMAPCACHE_STR[] = "PixmapCache";
|
||||||
|
const char TYPE_SCENEGRAPH_STR[] = "SceneGraph";
|
||||||
|
|
||||||
#define _(X) QLatin1String(X)
|
#define _(X) QLatin1String(X)
|
||||||
|
|
||||||
@@ -71,6 +73,10 @@ static QmlEventType qmlEventTypeAsEnum(const QString &typeString)
|
|||||||
return Binding;
|
return Binding;
|
||||||
} else if (typeString == _(TYPE_HANDLINGSIGNAL_STR)) {
|
} else if (typeString == _(TYPE_HANDLINGSIGNAL_STR)) {
|
||||||
return HandlingSignal;
|
return HandlingSignal;
|
||||||
|
} else if (typeString == _(TYPE_PIXMAPCACHE_STR)) {
|
||||||
|
return PixmapCacheEvent;
|
||||||
|
} else if (typeString == _(TYPE_SCENEGRAPH_STR)) {
|
||||||
|
return SceneGraphFrameEvent;
|
||||||
} else {
|
} else {
|
||||||
bool isNumber = false;
|
bool isNumber = false;
|
||||||
int type = typeString.toUInt(&isNumber);
|
int type = typeString.toUInt(&isNumber);
|
||||||
@@ -99,6 +105,12 @@ static QString qmlEventTypeAsString(QmlEventType typeEnum)
|
|||||||
case HandlingSignal:
|
case HandlingSignal:
|
||||||
return _(TYPE_HANDLINGSIGNAL_STR);
|
return _(TYPE_HANDLINGSIGNAL_STR);
|
||||||
break;
|
break;
|
||||||
|
case PixmapCacheEvent:
|
||||||
|
return _(TYPE_PIXMAPCACHE_STR);
|
||||||
|
break;
|
||||||
|
case SceneGraphFrameEvent:
|
||||||
|
return _(TYPE_SCENEGRAPH_STR);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return QString::number((int)typeEnum);
|
return QString::number((int)typeEnum);
|
||||||
}
|
}
|
||||||
@@ -249,7 +261,10 @@ void QmlProfilerFileReader::loadEventData(QXmlStreamReader &stream)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elementName == _("bindingType")) {
|
if (elementName == _("bindingType") ||
|
||||||
|
elementName == _("animationFrame") ||
|
||||||
|
elementName == _("cacheEventType") ||
|
||||||
|
elementName == _("sgEventType")) {
|
||||||
event.bindingType = readData.toInt();
|
event.bindingType = readData.toInt();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -288,20 +303,45 @@ void QmlProfilerFileReader::loadProfilerDataModel(QXmlStreamReader &stream)
|
|||||||
switch (token) {
|
switch (token) {
|
||||||
case QXmlStreamReader::StartElement: {
|
case QXmlStreamReader::StartElement: {
|
||||||
if (elementName == _("range")) {
|
if (elementName == _("range")) {
|
||||||
Range range = { 0, 0 };
|
Range range = { 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
const QXmlStreamAttributes attributes = stream.attributes();
|
const QXmlStreamAttributes attributes = stream.attributes();
|
||||||
if (!attributes.hasAttribute(_("startTime"))
|
if (!attributes.hasAttribute(_("startTime"))
|
||||||
|| !attributes.hasAttribute(_("duration"))
|
|
||||||
|| !attributes.hasAttribute(_("eventIndex"))) {
|
|| !attributes.hasAttribute(_("eventIndex"))) {
|
||||||
// ignore incomplete entry
|
// ignore incomplete entry
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
range.startTime = attributes.value(_("startTime")).toString().toLongLong();
|
range.startTime = attributes.value(_("startTime")).toString().toLongLong();
|
||||||
|
if (attributes.hasAttribute(_("duration")))
|
||||||
range.duration = attributes.value(_("duration")).toString().toLongLong();
|
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();
|
int eventIndex = attributes.value(_("eventIndex")).toString().toInt();
|
||||||
|
|
||||||
|
|
||||||
m_ranges.append(QPair<Range,int>(range, eventIndex));
|
m_ranges.append(QPair<Range,int>(range, eventIndex));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -332,12 +372,20 @@ void QmlProfilerFileReader::processQmlEvents()
|
|||||||
|
|
||||||
QmlEvent &event = m_qmlEvents[eventIndex];
|
QmlEvent &event = m_qmlEvents[eventIndex];
|
||||||
|
|
||||||
|
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,
|
emit rangedEvent(event.type, event.bindingType, range.startTime, range.duration,
|
||||||
QStringList(event.displayName), QmlEventLocation(event.filename,
|
QStringList(event.displayName), QmlEventLocation(event.filename,
|
||||||
event.line,
|
event.line,
|
||||||
event.column));
|
event.column));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QmlProfilerFileWriter::QmlProfilerFileWriter(QObject *parent) :
|
QmlProfilerFileWriter::QmlProfilerFileWriter(QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
@@ -377,7 +425,7 @@ void QmlProfilerFileWriter::setQmlEvents(const QVector<QmlProfilerSimpleModel::Q
|
|||||||
m_qmlEvents.insert(hashStr, e);
|
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));
|
m_ranges.append(QPair<Range, QString>(r, hashStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +463,13 @@ void QmlProfilerFileWriter::save(QIODevice *device)
|
|||||||
}
|
}
|
||||||
stream.writeTextElement(_("details"), event.details);
|
stream.writeTextElement(_("details"), event.details);
|
||||||
if (event.type == Binding)
|
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();
|
||||||
}
|
}
|
||||||
stream.writeEndElement(); // eventData
|
stream.writeEndElement(); // eventData
|
||||||
@@ -429,10 +483,45 @@ void QmlProfilerFileWriter::save(QIODevice *device)
|
|||||||
|
|
||||||
stream.writeStartElement(_("range"));
|
stream.writeStartElement(_("range"));
|
||||||
stream.writeAttribute(_("startTime"), QString::number(range.startTime));
|
stream.writeAttribute(_("startTime"), QString::number(range.startTime));
|
||||||
|
if (range.duration > 0) // no need to store duration of instantaneous events
|
||||||
stream.writeAttribute(_("duration"), QString::number(range.duration));
|
stream.writeAttribute(_("duration"), QString::number(range.duration));
|
||||||
stream.writeAttribute(_("eventIndex"), QString::number(m_qmlEvents.keys().indexOf(eventHash)));
|
stream.writeAttribute(_("eventIndex"), QString::number(m_qmlEvents.keys().indexOf(eventHash)));
|
||||||
|
|
||||||
QmlEvent event = m_qmlEvents.value(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) {
|
// if (event.type == QmlDebug::Painting && range.animationCount >= 0) {
|
||||||
// // animation frame
|
// // animation frame
|
||||||
// stream.writeAttribute(_("framerate"), QString::number(rangedEvent.frameRate));
|
// stream.writeAttribute(_("framerate"), QString::number(rangedEvent.frameRate));
|
||||||
|
@@ -61,6 +61,13 @@ struct QmlEvent {
|
|||||||
struct Range {
|
struct Range {
|
||||||
qint64 startTime;
|
qint64 startTime;
|
||||||
qint64 duration;
|
qint64 duration;
|
||||||
|
|
||||||
|
// numeric data used by animations, pixmap cache, scenegraph
|
||||||
|
qint64 numericData1;
|
||||||
|
qint64 numericData2;
|
||||||
|
qint64 numericData3;
|
||||||
|
qint64 numericData4;
|
||||||
|
qint64 numericData5;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlProfilerFileReader : public QObject
|
class QmlProfilerFileReader : public QObject
|
||||||
@@ -80,7 +87,9 @@ signals:
|
|||||||
|
|
||||||
void rangedEvent(int type, int bindingType, qint64 startTime, qint64 length,
|
void rangedEvent(int type, int bindingType, qint64 startTime, qint64 length,
|
||||||
const QStringList &data, const QmlDebug::QmlEventLocation &location);
|
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);
|
void error(const QString &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Reference in New Issue
Block a user