aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-04-05 09:47:33 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-04-19 08:09:07 +0000
commit1c2e0f387f552d3fbe98050f8629c11829ec95f7 (patch)
tree1a03f9f0e5c68f384d5940f19a59017f648a820a /src/plugins/qmlprofiler/qmlprofilertracefile.cpp
parent7099f215865d90b69906dc92da77857fa0e66165 (diff)
QmlProfiler: Move parts of model manager and trace file to Timeline
This way we can use the trace file loading and saving mechanism for other profilers. Change-Id: I98ec1cdde6f7abcea152cabf72e64d4e696dfa59 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/qmlprofiler/qmlprofilertracefile.cpp')
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertracefile.cpp464
1 files changed, 212 insertions, 252 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
index ec1fe76e1d..83b7023559 100644
--- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
@@ -24,6 +24,8 @@
****************************************************************************/
#include "qmlprofilertracefile.h"
+#include "qmlprofilernotesmodel.h"
+#include "qmlprofilerconstants.h"
#include <utils/qtcassert.h>
@@ -114,13 +116,7 @@ static QString qmlTypeAsString(Message message, RangeType rangeType)
return QString::number((int)rangeType);
}
-
-QmlProfilerFileReader::QmlProfilerFileReader(QObject *parent) :
- QObject(parent),
- m_traceStart(-1),
- m_traceEnd(-1),
- m_future(0),
- m_loadedFeatures(0)
+QmlProfilerTraceFile::QmlProfilerTraceFile(QObject *parent) : Timeline::TimelineTraceFile(parent)
{
static int meta[] = {
qRegisterMetaType<QVector<QmlEvent> >(),
@@ -130,16 +126,25 @@ QmlProfilerFileReader::QmlProfilerFileReader(QObject *parent) :
Q_UNUSED(meta);
}
-void QmlProfilerFileReader::setFuture(QFutureInterface<void> *future)
+void QmlProfilerTraceFile::load(QIODevice *device)
{
- m_future = future;
- if (m_future) {
- m_future->setProgressRange(0, 1000);
- m_future->setProgressValue(0);
- }
+ const QFile *file = qobject_cast<QFile *>(device);
+ if (file && file->fileName().endsWith(Constants::QtdFileExtension))
+ loadQtd(device);
+ else
+ loadQzt(device);
+}
+
+void QmlProfilerTraceFile::save(QIODevice *device)
+{
+ const QFile *file = qobject_cast<QFile *>(device);
+ if (file && file->fileName().endsWith(Constants::QtdFileExtension))
+ saveQtd(device);
+ else
+ saveQzt(device);
}
-void QmlProfilerFileReader::loadQtd(QIODevice *device)
+void QmlProfilerTraceFile::loadQtd(QIODevice *device)
{
QXmlStreamReader stream(device);
@@ -158,14 +163,13 @@ void QmlProfilerFileReader::loadQtd(QIODevice *device)
else
validVersion = false;
if (attributes.hasAttribute(_("traceStart")))
- m_traceStart = attributes.value(_("traceStart")).toLongLong();
+ setTraceStart(attributes.value(_("traceStart")).toLongLong());
if (attributes.hasAttribute(_("traceEnd")))
- m_traceEnd = attributes.value(_("traceEnd")).toLongLong();
+ setTraceEnd(attributes.value(_("traceEnd")).toLongLong());
}
if (elementName == _("eventData")) {
loadEventTypes(stream);
- emit typesLoaded(m_eventTypes);
break;
}
@@ -176,7 +180,6 @@ void QmlProfilerFileReader::loadQtd(QIODevice *device)
if (elementName == _("noteData")) {
loadNotes(stream);
- emit notesLoaded(m_notes);
break;
}
@@ -194,7 +197,7 @@ void QmlProfilerFileReader::loadQtd(QIODevice *device)
emit success();
}
-void QmlProfilerFileReader::loadQzt(QIODevice *device)
+void QmlProfilerTraceFile::loadQzt(QIODevice *device)
{
QDataStream stream(device);
stream.setVersion(QDataStream::Qt_5_5);
@@ -215,44 +218,48 @@ void QmlProfilerFileReader::loadQzt(QIODevice *device)
}
stream.setVersion(dataStreamVersion);
- stream >> m_traceStart >> m_traceEnd;
+ qint64 traceStart, traceEnd;
+ stream >> traceStart >> traceEnd;
+ setTraceStart(traceStart);
+ setTraceEnd(traceEnd);
QBuffer buffer;
QDataStream bufferStream(&buffer);
bufferStream.setVersion(dataStreamVersion);
QByteArray data;
- updateProgress(device);
+ setDeviceProgress(device);
if (!isCanceled()) {
stream >> data;
buffer.setData(qUncompress(data));
buffer.open(QIODevice::ReadOnly);
+ QVector<QmlEventType> eventTypes;
quint32 numEventTypes;
bufferStream >> numEventTypes;
if (numEventTypes > std::numeric_limits<int>::max()) {
emit error(tr("Excessive number of event types: %1").arg(numEventTypes));
return;
}
- QTC_ASSERT(m_eventTypes.isEmpty(), m_eventTypes.clear());
- m_eventTypes.reserve(static_cast<int>(numEventTypes));
+ eventTypes.reserve(static_cast<int>(numEventTypes));
QmlEventType type;
for (int typeId = 0; typeId < static_cast<int>(numEventTypes); ++typeId) {
bufferStream >> type;
- m_eventTypes.append(type);
+ eventTypes.append(type);
}
buffer.close();
- emit typesLoaded(m_eventTypes);
- updateProgress(device);
+ modelManager()->addEventTypes(eventTypes);
+ setDeviceProgress(device);
}
if (!isCanceled()) {
stream >> data;
buffer.setData(qUncompress(data));
buffer.open(QIODevice::ReadOnly);
- bufferStream >> m_notes;
+ QVector<QmlNote> notes;
+ bufferStream >> notes;
buffer.close();
- emit notesLoaded(m_notes);
- updateProgress(device);
+ qmlNotes()->setNotes(notes);
+ setDeviceProgress(device);
}
QVector<QmlEvent> eventBuffer;
@@ -264,11 +271,11 @@ void QmlProfilerFileReader::loadQzt(QIODevice *device)
QmlEvent event;
bufferStream >> event;
if (bufferStream.status() == QDataStream::Ok) {
- if (event.typeIndex() >= m_eventTypes.length()) {
+ if (event.typeIndex() >= traceManager()->numEventTypes()) {
emit error(tr("Invalid type index %1").arg(event.typeIndex()));
return;
}
- m_loadedFeatures |= (1ULL << m_eventTypes[event.typeIndex()].feature());
+ addFeature(modelManager()->eventType(event.typeIndex()).feature());
if (event.timestamp() < 0)
event.setTimestamp(0);
} else if (bufferStream.status() == QDataStream::ReadPastEnd) {
@@ -281,28 +288,35 @@ void QmlProfilerFileReader::loadQzt(QIODevice *device)
}
eventBuffer.append(event);
}
- emit qmlEventsLoaded(eventBuffer);
+ modelManager()->addEvents(eventBuffer);
eventBuffer.clear();
buffer.close();
- updateProgress(device);
+ setDeviceProgress(device);
}
if (isCanceled()) {
emit canceled();
} else {
- emit qmlEventsLoaded(eventBuffer);
+ modelManager()->addEvents(eventBuffer);
emit success();
}
}
-quint64 QmlProfilerFileReader::loadedFeatures() const
+void QmlProfilerTraceFile::addEventsProgress(qint64 timestamp)
+{
+ addProgressValue(static_cast<float>(timestamp) / static_cast<float>(traceEnd() - traceStart())
+ * ProgressEvents);
+}
+
+void QmlProfilerTraceFile::addStageProgress(QmlProfilerTraceFile::ProgressValues stage)
{
- return m_loadedFeatures;
+ addProgressValue(stage);
}
-void QmlProfilerFileReader::loadEventTypes(QXmlStreamReader &stream)
+void QmlProfilerTraceFile::loadEventTypes(QXmlStreamReader &stream)
{
QTC_ASSERT(stream.name() == _("eventData"), return);
+ QVector<QmlEventType> eventTypes;
int typeIndex = -1;
@@ -330,7 +344,7 @@ void QmlProfilerFileReader::loadEventTypes(QXmlStreamReader &stream)
switch (token) {
case QXmlStreamReader::StartElement: {
if (elementName == _("event")) {
- updateProgress(stream.device());
+ setDeviceProgress(stream.device());
clearType();
const QXmlStreamAttributes attributes = stream.attributes();
@@ -407,20 +421,21 @@ void QmlProfilerFileReader::loadEventTypes(QXmlStreamReader &stream)
case QXmlStreamReader::EndElement: {
if (elementName == _("event")) {
if (typeIndex >= 0) {
- if (typeIndex >= m_eventTypes.size())
- m_eventTypes.resize(typeIndex + 1);
+ if (typeIndex >= eventTypes.length())
+ eventTypes.resize(typeIndex + 1);
QmlEventType type(messageAndRange.first, messageAndRange.second, detailType,
QmlEventLocation(filename, line, column), data, displayName);
- m_eventTypes[typeIndex] = type;
- quint8 feature = type.feature();
+ eventTypes[typeIndex] = type;
+ const quint8 feature = type.feature();
if (feature != MaximumProfileFeature)
- m_loadedFeatures |= (1ULL << static_cast<uint>(feature));
+ addFeature(feature);
}
break;
}
if (elementName == _("eventData")) {
// done reading eventData
+ modelManager()->addEventTypes(eventTypes);
return;
}
break;
@@ -497,7 +512,7 @@ QVector<QmlEvent> EventList::finalize()
return result;
}
-void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
+void QmlProfilerTraceFile::loadEvents(QXmlStreamReader &stream)
{
QTC_ASSERT(stream.name() == _("profilerDataModel"), return);
EventList events;
@@ -510,7 +525,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
switch (token) {
case QXmlStreamReader::StartElement: {
if (elementName == _("range")) {
- updateProgress(stream.device());
+ setDeviceProgress(stream.device());
QmlEvent event;
const QXmlStreamAttributes attributes = stream.attributes();
@@ -574,7 +589,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
case QXmlStreamReader::EndElement: {
if (elementName == _("profilerDataModel")) {
// done reading profilerDataModel
- emit qmlEventsLoaded(events.finalize());
+ modelManager()->addEvents(events.finalize());
return;
}
break;
@@ -584,7 +599,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
}
}
-void QmlProfilerFileReader::loadNotes(QXmlStreamReader &stream)
+void QmlProfilerTraceFile::loadNotes(QXmlStreamReader &stream)
{
QmlNote currentNote;
while (!stream.atEnd() && !stream.hasError() && !isCanceled()) {
@@ -595,7 +610,7 @@ void QmlProfilerFileReader::loadNotes(QXmlStreamReader &stream)
switch (token) {
case QXmlStreamReader::StartElement: {
if (elementName == _("note")) {
- updateProgress(stream.device());
+ setDeviceProgress(stream.device());
QXmlStreamAttributes attrs = stream.attributes();
int collapsedRow = attrs.hasAttribute(_("collapsedRow")) ?
attrs.value(_("collapsedRow")).toInt() : -1;
@@ -613,7 +628,7 @@ void QmlProfilerFileReader::loadNotes(QXmlStreamReader &stream)
}
case QXmlStreamReader::EndElement: {
if (elementName == _("note")) {
- m_notes.append(currentNote);
+ qmlNotes()->addNote(currentNote);
} else if (elementName == _("noteData")) {
return;
}
@@ -625,55 +640,7 @@ void QmlProfilerFileReader::loadNotes(QXmlStreamReader &stream)
}
}
-void QmlProfilerFileReader::updateProgress(QIODevice *device)
-{
- if (!m_future)
- return;
-
- m_future->setProgressValue(device->pos() * 1000 / device->size());
-}
-
-bool QmlProfilerFileReader::isCanceled() const
-{
- return m_future && m_future->isCanceled();
-}
-
-QmlProfilerFileWriter::QmlProfilerFileWriter(QObject *parent) :
- QObject(parent),
- m_startTime(0),
- m_endTime(0),
- m_measuredTime(0),
- m_future(0)
-{
-}
-
-void QmlProfilerFileWriter::setTraceTime(qint64 startTime, qint64 endTime, qint64 measuredTime)
-{
- m_startTime = startTime;
- m_endTime = endTime;
- m_measuredTime = measuredTime;
-}
-
-void QmlProfilerFileWriter::setData(const QmlProfilerModelManager *model)
-{
- m_modelManager = model;
-}
-
-void QmlProfilerFileWriter::setNotes(const QVector<QmlNote> &notes)
-{
- m_notes = notes;
-}
-
-void QmlProfilerFileWriter::setFuture(QFutureInterface<void> *future)
-{
- m_future = future;
- if (m_future) {
- m_future->setProgressRange(0, ProgressTotal);
- m_future->setProgressValue(0);
- }
-}
-
-void QmlProfilerFileWriter::saveQtd(QIODevice *device)
+void QmlProfilerTraceFile::saveQtd(QIODevice *device)
{
QXmlStreamWriter stream(device);
@@ -683,15 +650,16 @@ void QmlProfilerFileWriter::saveQtd(QIODevice *device)
stream.writeStartElement(_("trace"));
stream.writeAttribute(_("version"), _(PROFILER_FILE_VERSION));
- stream.writeAttribute(_("traceStart"), QString::number(m_startTime));
- stream.writeAttribute(_("traceEnd"), QString::number(m_endTime));
+ stream.writeAttribute(_("traceStart"), QString::number(traceStart()));
+ stream.writeAttribute(_("traceEnd"), QString::number(traceEnd()));
stream.writeStartElement(_("eventData"));
- stream.writeAttribute(_("totalTime"), QString::number(m_measuredTime));
- for (int typeIndex = 0, end = m_modelManager->numEventTypes();
- typeIndex < end && !isCanceled(); ++typeIndex) {
+ stream.writeAttribute(_("totalTime"), QString::number(measuredTime()));
+ const QmlProfilerModelManager *manager = modelManager();
+ for (int typeIndex = 0, end = manager->numEventTypes(); typeIndex < end && !isCanceled();
+ ++typeIndex) {
- const QmlEventType &type = m_modelManager->eventType(typeIndex);
+ const QmlEventType &type = manager->eventType(typeIndex);
stream.writeStartElement(_("event"));
stream.writeAttribute(_("index"), QString::number(typeIndex));
@@ -734,210 +702,202 @@ void QmlProfilerFileWriter::saveQtd(QIODevice *device)
}
stream.writeEndElement();
}
- updateProgress(ProgressTypes);
+ addStageProgress(ProgressTypes);
stream.writeEndElement(); // eventData
- if (!isCanceled()) {
- stream.writeStartElement(_("profilerDataModel"));
+ if (isCanceled()) {
+ emit canceled();
+ return;
+ }
- QStack<QmlEvent> stack;
- const bool success = m_modelManager->replayEvents(
- -1, -1, [this, &stack, &stream](const QmlEvent &event,
- const QmlEventType &type) {
- if (isCanceled())
- return;
+ QStack<QmlEvent> stack;
+ qint64 lastProgressTimestamp = traceStart();
+ modelManager()->replayEvents(-1, -1, [&](const QmlEvent &event, const QmlEventType &type) {
+ if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeStart) {
+ stack.push(event);
+ return;
+ }
- if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeStart) {
- stack.push(event);
- return;
- }
+ stream.writeStartElement(_("range"));
+ if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeEnd) {
+ QmlEvent start = stack.pop();
+ stream.writeAttribute(_("startTime"), QString::number(start.timestamp()));
+ stream.writeAttribute(_("duration"),
+ QString::number(event.timestamp() - start.timestamp()));
+ } else {
+ stream.writeAttribute(_("startTime"), QString::number(event.timestamp()));
+ }
- stream.writeStartElement(_("range"));
- if (type.rangeType() != MaximumRangeType && event.rangeStage() == RangeEnd) {
- QmlEvent start = stack.pop();
- stream.writeAttribute(_("startTime"), QString::number(start.timestamp()));
- stream.writeAttribute(_("duration"),
- QString::number(event.timestamp() - start.timestamp()));
- } else {
- stream.writeAttribute(_("startTime"), QString::number(event.timestamp()));
+ stream.writeAttribute(_("eventIndex"), QString::number(event.typeIndex()));
+
+ if (type.message() == Event) {
+ if (type.detailType() == AnimationFrame) {
+ // special: animation event
+ stream.writeAttribute(_("framerate"), QString::number(event.number<qint32>(0)));
+ stream.writeAttribute(_("animationcount"),
+ QString::number(event.number<qint32>(1)));
+ stream.writeAttribute(_("thread"), QString::number(event.number<qint32>(2)));
+ } else if (type.detailType() == Key || type.detailType() == Mouse) {
+ // special: input event
+ stream.writeAttribute(_("type"), QString::number(event.number<qint32>(0)));
+ stream.writeAttribute(_("data1"), QString::number(event.number<qint32>(1)));
+ stream.writeAttribute(_("data2"), QString::number(event.number<qint32>(2)));
}
+ }
- stream.writeAttribute(_("eventIndex"), QString::number(event.typeIndex()));
-
- if (type.message() == Event) {
- if (type.detailType() == AnimationFrame) {
- // special: animation event
- stream.writeAttribute(_("framerate"), QString::number(event.number<qint32>(0)));
- stream.writeAttribute(_("animationcount"),
- QString::number(event.number<qint32>(1)));
- stream.writeAttribute(_("thread"), QString::number(event.number<qint32>(2)));
- } else if (type.detailType() == Key || type.detailType() == Mouse) {
- // special: input event
- stream.writeAttribute(_("type"), QString::number(event.number<qint32>(0)));
- stream.writeAttribute(_("data1"), QString::number(event.number<qint32>(1)));
- stream.writeAttribute(_("data2"), QString::number(event.number<qint32>(2)));
- }
+ // special: pixmap cache event
+ if (type.message() == PixmapCacheEvent) {
+ if (type.detailType() == PixmapSizeKnown) {
+ stream.writeAttribute(_("width"), QString::number(event.number<qint32>(0)));
+ stream.writeAttribute(_("height"), QString::number(event.number<qint32>(1)));
}
- // special: pixmap cache event
- if (type.message() == PixmapCacheEvent) {
- if (type.detailType() == PixmapSizeKnown) {
- stream.writeAttribute(_("width"), QString::number(event.number<qint32>(0)));
- stream.writeAttribute(_("height"), QString::number(event.number<qint32>(1)));
- }
-
- if (type.detailType() == PixmapReferenceCountChanged
- || type.detailType() == PixmapCacheCountChanged)
- stream.writeAttribute(_("refCount"), QString::number(event.number<qint32>(2)));
- }
+ if (type.detailType() == PixmapReferenceCountChanged
+ || type.detailType() == PixmapCacheCountChanged)
+ stream.writeAttribute(_("refCount"), QString::number(event.number<qint32>(2)));
+ }
- if (type.message() == SceneGraphFrame) {
- // special: scenegraph frame events
- for (int i = 0; i < 5; ++i) {
- qint64 number = event.number<qint64>(i);
- if (number <= 0)
- continue;
- stream.writeAttribute(QString::fromLatin1("timing%1").arg(i + 1),
- QString::number(number));
- }
+ if (type.message() == SceneGraphFrame) {
+ // special: scenegraph frame events
+ for (int i = 0; i < 5; ++i) {
+ qint64 number = event.number<qint64>(i);
+ if (number <= 0)
+ continue;
+ stream.writeAttribute(QString::fromLatin1("timing%1").arg(i + 1),
+ QString::number(number));
}
+ }
- // special: memory allocation event
- if (type.message() == MemoryAllocation)
- stream.writeAttribute(_("amount"), QString::number(event.number<qint64>(0)));
+ // special: memory allocation event
+ if (type.message() == MemoryAllocation)
+ stream.writeAttribute(_("amount"), QString::number(event.number<qint64>(0)));
- if (type.message() == DebugMessage)
- stream.writeAttribute(_("text"), event.string());
+ if (type.message() == DebugMessage)
+ stream.writeAttribute(_("text"), event.string());
- stream.writeEndElement();
+ stream.writeEndElement();
- // Update the progress roughly every 4k events. It doesn't have to be precise.
- if ((event.timestamp() & 0xfff) == 0)
- updateProgress(event.timestamp());
- });
- if (!success) {
- emit error(tr("Could not re-read events from temporary trace file. Saving failed."));
- return;
+ if (isProgressUpdateNeeded()) {
+ addEventsProgress(event.timestamp() - lastProgressTimestamp);
+ lastProgressTimestamp = event.timestamp();
}
-
+ }, [&stream](){
+ stream.writeStartElement(_("profilerDataModel"));
+ }, [this, &stream]() {
stream.writeEndElement(); // profilerDataModel
- }
-
- if (!isCanceled()) {
- stream.writeStartElement(_("noteData"));
- for (int noteIndex = 0; noteIndex < m_notes.size() && !isCanceled(); ++noteIndex) {
-
- const QmlNote &note = m_notes[noteIndex];
- stream.writeStartElement(_("note"));
- stream.writeAttribute(_("startTime"), QString::number(note.startTime()));
- stream.writeAttribute(_("duration"), QString::number(note.duration()));
- stream.writeAttribute(_("eventIndex"), QString::number(note.typeIndex()));
- stream.writeAttribute(_("collapsedRow"), QString::number(note.collapsedRow()));
- stream.writeCharacters(note.text());
- stream.writeEndElement(); // note
+ if (!isCanceled()) {
+ stream.writeStartElement(_("noteData"));
+ const QVector<QmlNote> &notes = qmlNotes()->notes();
+ for (int noteIndex = 0; noteIndex < notes.length() && !isCanceled(); ++noteIndex) {
+ const QmlNote &note = notes[noteIndex];
+ stream.writeStartElement(_("note"));
+ stream.writeAttribute(_("startTime"), QString::number(note.startTime()));
+ stream.writeAttribute(_("duration"), QString::number(note.duration()));
+ stream.writeAttribute(_("eventIndex"), QString::number(note.typeIndex()));
+ stream.writeAttribute(_("collapsedRow"), QString::number(note.collapsedRow()));
+ stream.writeCharacters(note.text());
+ stream.writeEndElement(); // note
+ }
+ stream.writeEndElement(); // noteData
+ addStageProgress(ProgressNotes);
}
- stream.writeEndElement(); // noteData
- updateProgress(ProgressNotes);
- }
-
- stream.writeEndElement(); // trace
- stream.writeEndDocument();
- if (isCanceled()) {
- emit canceled();
- } else if (stream.hasError()) {
- emit error(tr("Error writing trace file."));
- } else {
- emit success();
- }
+ stream.writeEndElement(); // trace
+ stream.writeEndDocument();
+
+ if (isCanceled())
+ emit canceled();
+ else if (stream.hasError())
+ emit error(tr("Error writing trace file."));
+ else
+ emit success();
+ }, [this](const QString &message) {
+ emit error(tr("Could not re-read events from temporary trace file: %s\nSaving failed.")
+ .arg(message));
+ }, future());
}
-void QmlProfilerFileWriter::saveQzt(QFile *file)
+void QmlProfilerTraceFile::saveQzt(QIODevice *device)
{
- QDataStream stream(file);
+ QDataStream stream(device);
stream.setVersion(QDataStream::Qt_5_5);
stream << QByteArray("QMLPROFILER");
stream << static_cast<qint32>(QDataStream::Qt_DefaultCompiledVersion);
stream.setVersion(QDataStream::Qt_DefaultCompiledVersion);
- stream << m_startTime << m_endTime;
+ stream << traceStart() << traceEnd();
QBuffer buffer;
QDataStream bufferStream(&buffer);
buffer.open(QIODevice::WriteOnly);
if (!isCanceled()) {
- const int numEventTypes = m_modelManager->numEventTypes();
+ const QmlProfilerModelManager *manager = modelManager();
+ const int numEventTypes = manager->numEventTypes();
bufferStream << static_cast<quint32>(numEventTypes);
for (int typeId = 0; typeId < numEventTypes; ++typeId)
- bufferStream << m_modelManager->eventType(typeId);
+ bufferStream << manager->eventType(typeId);
stream << qCompress(buffer.data());
buffer.close();
buffer.buffer().clear();
- updateProgress(ProgressTypes);
+ addStageProgress(ProgressTypes);
}
if (!isCanceled()) {
buffer.open(QIODevice::WriteOnly);
- bufferStream << m_notes;
+ bufferStream << qmlNotes()->notes();
stream << qCompress(buffer.data());
buffer.close();
buffer.buffer().clear();
- updateProgress(ProgressNotes);
- }
-
- if (!isCanceled()) {
- buffer.open(QIODevice::WriteOnly);
- const bool success = m_modelManager->replayEvents(
- -1, -1, [this, &stream, &buffer, &bufferStream](const QmlEvent &event,
- const QmlEventType &type) {
- Q_UNUSED(type);
- bufferStream << event;
- // 32MB buffer should be plenty for efficient compression
- if (buffer.data().length() > (1 << 25)) {
- stream << qCompress(buffer.data());
- buffer.close();
- buffer.buffer().clear();
- if (isCanceled())
- return;
- buffer.open(QIODevice::WriteOnly);
- updateProgress(event.timestamp());
- }
- });
- if (!success) {
- emit error(tr("Could not re-read events from temporary trace file. Saving failed."));
- return;
- }
+ addStageProgress(ProgressNotes);
}
if (isCanceled()) {
emit canceled();
- } else {
- stream << qCompress(buffer.data());
- buffer.close();
- buffer.buffer().clear();
- updateProgress(m_endTime);
- emit success();
+ return;
}
+
+ qint64 lastProgressTimestamp = traceStart();
+ modelManager()->replayEvents(-1, -1, [&](const QmlEvent &event, const QmlEventType &type) {
+ Q_UNUSED(type);
+ bufferStream << event;
+ // 32MB buffer should be plenty for efficient compression
+ if (buffer.data().length() > (1 << 25)) {
+ stream << qCompress(buffer.data());
+ buffer.close();
+ buffer.buffer().clear();
+ buffer.open(QIODevice::WriteOnly);
+ if (isProgressUpdateNeeded()) {
+ addEventsProgress(event.timestamp() - lastProgressTimestamp);
+ lastProgressTimestamp = event.timestamp();
+ }
+ }
+ }, [&]() {
+ buffer.open(QIODevice::WriteOnly);
+ }, [&]() {
+ if (isCanceled()) {
+ emit canceled();
+ } else {
+ stream << qCompress(buffer.data());
+ buffer.close();
+ buffer.buffer().clear();
+ addEventsProgress(traceEnd() - lastProgressTimestamp);
+ emit success();
+ }
+ }, [this](const QString &message) {
+ emit error(tr("Could not re-read events from temporary trace file: %s\nSaving failed.")
+ .arg(message));
+ }, future());
}
-void QmlProfilerFileWriter::updateProgress(qint64 timestamp)
+QmlProfilerModelManager *QmlProfilerTraceFile::modelManager()
{
- if (!m_future)
- return;
-
- if (timestamp < 0) {
- m_future->setProgressValue(m_future->progressValue() - timestamp);
- } else {
- m_future->setProgressValue(m_future->progressValue()
- + float(m_endTime - timestamp) / float(m_endTime - m_startTime)
- * ProgressEvents);
- }
+ return static_cast<QmlProfilerModelManager *>(traceManager());
}
-bool QmlProfilerFileWriter::isCanceled() const
+QmlProfilerNotesModel *QmlProfilerTraceFile::qmlNotes()
{
- return m_future && m_future->isCanceled();
+ return static_cast<QmlProfilerNotesModel *>(notes());
}
} // namespace Internal