Commit 8d15633a authored by Ulf Hermann's avatar Ulf Hermann

QmlProfiler: Add a QmlTypedEvent and extend QmlEvent

The QmlTypedEvent is mainly useful to read a generic QmlEvent and
QmlEventType from a QPacket. QmlEventType has a stream operator to do
exactly that. QmlEvent also gets further options to store 32-bit data
in addition to 64- and 8-bit data. Also, with the more generic storage
layout we can reduce the memory consumption of range events by 50%.
This comes at the cost of additional memory allocations for non-range
events, but as non-range events are significantly less frequent than
range events, this is a good tradeoff. Finally the new storage layout
lends itself to efficient serialization, which will help when
developing new storage and transfer formats for QML traces.

Change-Id: I420de68b0142f23c8fb2ca8b329d7ffe69c83fe0
Reviewed-by: default avatarJoerg Bornemann <joerg.bornemann@theqtcompany.com>
parent 61d94c5c
......@@ -113,7 +113,7 @@ void DebugMessagesModel::loadData()
continue;
m_data.insert(insert(event.timestamp(), 0, type.detailType),
MessageData(event.stringData(), event.typeIndex()));
MessageData(event.string(), event.typeIndex()));
if (type.detailType > m_maximumMsgType)
m_maximumMsgType = event.typeIndex();
updateProgress(count(), simpleModel->events().count());
......
......@@ -153,8 +153,8 @@ void InputEventsModel::loadData()
continue;
m_data.insert(insert(event.timestamp(), 0, type.detailType),
InputEvent(static_cast<InputEventType>(event.numericData(0)),
event.numericData(1), event.numericData(2)));
InputEvent(static_cast<InputEventType>(event.number<qint32>(0)),
event.number<qint32>(1), event.number<qint32>(2)));
if (type.detailType == Mouse) {
if (m_mouseTypeId == -1)
......
......@@ -177,12 +177,12 @@ void MemoryUsageModel::loadData()
type.detailType == selectionId(currentUsageIndex) &&
m_data[currentUsageIndex].originTypeIndex == rangeStack.top().originTypeIndex &&
rangeStack.top().startTime < startTime(currentUsageIndex)) {
m_data[currentUsageIndex].update(event.numericData(0));
m_data[currentUsageIndex].update(event.number<qint64>(0));
currentUsage = m_data[currentUsageIndex].size;
} else {
MemoryAllocationItem allocation(event.typeIndex(), currentUsage,
rangeStack.empty() ? -1 : rangeStack.top().originTypeIndex);
allocation.update(event.numericData(0));
allocation.update(event.number<qint64>(0));
currentUsage = allocation.size;
if (currentUsageIndex != -1) {
......@@ -200,12 +200,12 @@ void MemoryUsageModel::loadData()
m_data[currentJSHeapIndex].originTypeIndex ==
rangeStack.top().originTypeIndex &&
rangeStack.top().startTime < startTime(currentJSHeapIndex)) {
m_data[currentJSHeapIndex].update(event.numericData(0));
m_data[currentJSHeapIndex].update(event.number<qint64>(0));
currentSize = m_data[currentJSHeapIndex].size;
} else {
MemoryAllocationItem allocation(event.typeIndex(), currentSize,
rangeStack.empty() ? -1 : rangeStack.top().originTypeIndex);
allocation.update(event.numericData(0));
allocation.update(event.number<qint64>(0));
currentSize = allocation.size;
if (currentSize > m_maxSize)
......
......@@ -211,15 +211,15 @@ void PixmapCacheModel::loadData()
// We can't have cached it before we knew the size
Q_ASSERT(i->cacheState != Cached);
i->size.setWidth(event.numericData(0));
i->size.setHeight(event.numericData(1));
i->size.setWidth(event.number<qint32>(0));
i->size.setHeight(event.number<qint32>(1));
newEvent.sizeIndex = i - pixmap.sizes.begin();
break;
}
if (newEvent.sizeIndex == -1) {
newEvent.sizeIndex = pixmap.sizes.length();
pixmap.sizes << PixmapState(event.numericData(0), event.numericData(1));
pixmap.sizes << PixmapState(event.number<qint32>(0), event.number<qint32>(1));
}
PixmapState &state = pixmap.sizes[newEvent.sizeIndex];
......@@ -234,8 +234,8 @@ void PixmapCacheModel::loadData()
case PixmapCacheCountChanged: {// Cache Size Changed Event
pixmapStartTime = event.timestamp() + 1; // delay 1 ns for proper sorting
bool uncache = cumulatedCount > event.numericData(2);
cumulatedCount = event.numericData(2);
bool uncache = cumulatedCount > event.number<qint32>(2);
cumulatedCount = event.number<qint32>(2);
qint64 pixSize = 0;
// First try to find a preferred pixmap, which either is Corrupt and will be uncached
......
This diff is collapsed.
......@@ -39,6 +39,7 @@ SOURCES += \
qmlprofilertracefile.cpp \
qmlprofilertraceview.cpp \
qmlprofilerviewmanager.cpp \
qmltypedevent.cpp \
scenegraphtimelinemodel.cpp
HEADERS += \
......@@ -84,6 +85,7 @@ HEADERS += \
qmlprofilertracefile.h \
qmlprofilertraceview.h \
qmlprofilerviewmanager.h \
qmltypedevent.h \
scenegraphtimelinemodel.h
RESOURCES += \
......
......@@ -59,6 +59,7 @@ QtcPlugin {
"qmlprofilertracefile.cpp", "qmlprofilertracefile.h",
"qmlprofilertraceview.cpp", "qmlprofilertraceview.h",
"qmlprofilerviewmanager.cpp", "qmlprofilerviewmanager.h",
"qmltypedevent.cpp", "qmltypedevent.h",
"scenegraphtimelinemodel.cpp", "scenegraphtimelinemodel.h",
]
}
......
......@@ -78,10 +78,10 @@ void QmlProfilerAnimationsModel::loadData()
if (!accepted(type))
continue;
lastThread = (AnimationThread)event.numericData(2);
lastThread = (AnimationThread)event.number<qint32>(2);
// initial estimation of the event duration: 1/framerate
qint64 estimatedDuration = event.numericData(0) > 0 ? 1e9/event.numericData(0) : 1;
qint64 estimatedDuration = event.number<qint32>(0) > 0 ? 1e9 / event.number<qint32>(0) : 1;
// the profiler registers the animation events at the end of them
qint64 realEndTime = event.timestamp();
......@@ -97,8 +97,8 @@ void QmlProfilerAnimationsModel::loadData()
// 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.typeId = event.typeIndex();
lastEvent.framerate = (int)event.numericData(0);
lastEvent.animationcount = (int)event.numericData(1);
lastEvent.framerate = event.number<qint32>(0);
lastEvent.animationcount = event.number<qint32>(1);
QTC_ASSERT(lastEvent.animationcount > 0, continue);
m_data.insert(insert(realStartTime, realEndTime - realStartTime, lastThread), lastEvent);
......
......@@ -248,7 +248,7 @@ void QmlProfilerDataModel::addEvent(Message message, RangeType rangeType, int de
message == DebugMessage ? QString() : data);
QmlEvent eventData = (message == DebugMessage) ?
QmlEvent(startTime, duration, -1, data) :
QmlEvent(startTime, duration, -1, ndata1, ndata2, ndata3, ndata4, ndata5);
QmlEvent(startTime, duration, -1, {ndata1, ndata2, ndata3, ndata4, ndata5});
QHash<QmlEventType, int>::Iterator it = d->eventTypeIds.find(typeData);
if (it != d->eventTypeIds.end()) {
......
......@@ -360,7 +360,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
case QXmlStreamReader::StartElement: {
if (elementName == _("range")) {
progress(stream.device());
QmlEvent event(0, 0, -1, 0, 0, 0, 0, 0);
QmlEvent event;
const QXmlStreamAttributes attributes = stream.attributes();
if (!attributes.hasAttribute(_("startTime"))
......@@ -375,37 +375,37 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
// attributes for special events
if (attributes.hasAttribute(_("framerate")))
event.setNumericData(0, attributes.value(_("framerate")).toLongLong());
event.setNumber<qint32>(0, attributes.value(_("framerate")).toInt());
if (attributes.hasAttribute(_("animationcount")))
event.setNumericData(1, attributes.value(_("animationcount")).toLongLong());
event.setNumber<qint32>(1, attributes.value(_("animationcount")).toInt());
if (attributes.hasAttribute(_("thread")))
event.setNumericData(2, attributes.value(_("thread")).toLongLong());
event.setNumber<qint32>(2, attributes.value(_("thread")).toInt());
if (attributes.hasAttribute(_("width")))
event.setNumericData(0, attributes.value(_("width")).toLongLong());
event.setNumber<qint32>(0, attributes.value(_("width")).toInt());
if (attributes.hasAttribute(_("height")))
event.setNumericData(1, attributes.value(_("height")).toLongLong());
event.setNumber<qint32>(1, attributes.value(_("height")).toInt());
if (attributes.hasAttribute(_("refCount")))
event.setNumericData(2, attributes.value(_("refCount")).toLongLong());
event.setNumber<qint32>(2, attributes.value(_("refCount")).toInt());
if (attributes.hasAttribute(_("amount")))
event.setNumericData(0, attributes.value(_("amount")).toLongLong());
event.setNumber<qint64>(0, attributes.value(_("amount")).toLongLong());
if (attributes.hasAttribute(_("timing1")))
event.setNumericData(0, attributes.value(_("timing1")).toLongLong());
event.setNumber<qint64>(0, attributes.value(_("timing1")).toLongLong());
if (attributes.hasAttribute(_("timing2")))
event.setNumericData(1, attributes.value(_("timing2")).toLongLong());
event.setNumber<qint64>(1, attributes.value(_("timing2")).toLongLong());
if (attributes.hasAttribute(_("timing3")))
event.setNumericData(2, attributes.value(_("timing3")).toLongLong());
event.setNumber<qint64>(2, attributes.value(_("timing3")).toLongLong());
if (attributes.hasAttribute(_("timing4")))
event.setNumericData(3, attributes.value(_("timing4")).toLongLong());
event.setNumber<qint64>(3, attributes.value(_("timing4")).toLongLong());
if (attributes.hasAttribute(_("timing5")))
event.setNumericData(4, attributes.value(_("timing5")).toLongLong());
event.setNumber<qint64>(4, attributes.value(_("timing5")).toLongLong());
if (attributes.hasAttribute(_("type")))
event.setNumericData(0, attributes.value(_("type")).toLongLong());
event.setNumber<qint32>(0, attributes.value(_("type")).toInt());
if (attributes.hasAttribute(_("data1")))
event.setNumericData(1, attributes.value(_("data1")).toLongLong());
event.setNumber<qint32>(1, attributes.value(_("data1")).toInt());
if (attributes.hasAttribute(_("data2")))
event.setNumericData(2, attributes.value(_("data2")).toLongLong());
event.setNumber<qint32>(2, attributes.value(_("data2")).toInt());
if (attributes.hasAttribute(_("text")))
event.setStringData(attributes.value(_("text")).toString());
event.setString(attributes.value(_("text")).toString());
event.setTypeIndex(attributes.value(_("eventIndex")).toInt());
......@@ -601,49 +601,47 @@ void QmlProfilerFileWriter::save(QIODevice *device)
if (type.message == Event) {
if (type.detailType == AnimationFrame) {
// special: animation event
stream.writeAttribute(_("framerate"), QString::number(event.numericData(0)));
stream.writeAttribute(_("animationcount"), QString::number(event.numericData(1)));
stream.writeAttribute(_("thread"), QString::number(event.numericData(2)));
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.numericData(0)));
stream.writeAttribute(_("data1"), QString::number(event.numericData(1)));
stream.writeAttribute(_("data2"), QString::number(event.numericData(2)));
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.numericData(0)));
stream.writeAttribute(_("height"), QString::number(event.numericData(1)));
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.numericData(2)));
stream.writeAttribute(_("refCount"), QString::number(event.number<qint32>(2)));
}
if (type.message == SceneGraphFrame) {
// special: scenegraph frame events
if (event.numericData(0) > 0)
stream.writeAttribute(_("timing1"), QString::number(event.numericData(0)));
if (event.numericData(1) > 0)
stream.writeAttribute(_("timing2"), QString::number(event.numericData(1)));
if (event.numericData(2) > 0)
stream.writeAttribute(_("timing3"), QString::number(event.numericData(2)));
if (event.numericData(3) > 0)
stream.writeAttribute(_("timing4"), QString::number(event.numericData(3)));
if (event.numericData(4) > 0)
stream.writeAttribute(_("timing5"), QString::number(event.numericData(4)));
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.numericData(0)));
stream.writeAttribute(_("amount"), QString::number(event.number<qint64>(0)));
if (type.message == DebugMessage)
stream.writeAttribute(_("text"), event.stringData());
stream.writeAttribute(_("text"), event.string());
stream.writeEndElement();
incrementProgress();
......
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "qmltypedevent.h"
#include <QVarLengthArray>
namespace QmlProfiler {
QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event)
{
qint64 time;
qint32 messageType;
qint32 subtype;
stream >> time >> messageType;
RangeType rangeType = MaximumRangeType;
if (!stream.atEnd()) {
stream >> subtype;
rangeType = static_cast<RangeType>(subtype);
} else {
subtype = -1;
}
event.event.setTimestamp(time);
event.event.setTypeIndex(-1);
event.type.displayName.clear();
event.type.data.clear();
event.type.location.filename.clear();
event.type.location.line = event.type.location.column = -1;
switch (messageType) {
case Event: {
event.type.detailType = subtype;
event.type.rangeType = MaximumRangeType;
event.type.message = static_cast<Message>(messageType);
switch (subtype) {
case StartTrace:
case EndTrace: {
QVarLengthArray<qint32> engineIds;
while (!stream.atEnd()) {
qint32 id;
stream >> id;
engineIds << id;
}
event.event.setNumbers<QVarLengthArray<qint32>, qint32>(engineIds);
break;
}
case AnimationFrame: {
qint32 frameRate, animationCount;
qint32 threadId;
stream >> frameRate >> animationCount;
if (!stream.atEnd())
stream >> threadId;
else
threadId = 0;
event.event.setNumbers<qint32>({frameRate, animationCount, threadId});
break;
}
case Mouse:
case Key:
int inputType = (subtype == Key ? InputKeyUnknown : InputMouseUnknown);
if (!stream.atEnd())
stream >> inputType;
qint32 a = -1;
if (!stream.atEnd())
stream >> a;
qint32 b = -1;
if (!stream.atEnd())
stream >> b;
event.event.setNumbers<qint32>({inputType, a, b});
break;
}
break;
}
case Complete: {
event.type.message = static_cast<Message>(messageType);
event.type.rangeType = MaximumRangeType;
event.type.detailType = subtype;
break;
}
case SceneGraphFrame: {
QVarLengthArray<qint64> params;
qint64 param;
while (!stream.atEnd()) {
stream >> param;
params.push_back(param);
}
event.type.message = static_cast<Message>(messageType);
event.type.rangeType = MaximumRangeType;
event.type.detailType = subtype;
event.event.setNumbers<QVarLengthArray<qint64>, qint64>(params);
break;
}
case PixmapCacheEvent: {
qint32 width = 0, height = 0, refcount = 0;
stream >> event.type.location.filename;
if (subtype == PixmapReferenceCountChanged || subtype == PixmapCacheCountChanged) {
stream >> refcount;
} else if (subtype == PixmapSizeKnown) {
stream >> width >> height;
refcount = 1;
}
event.type.message = static_cast<Message>(messageType);
event.type.rangeType = MaximumRangeType;
event.type.location.line = event.type.location.column = 0;
event.type.detailType = subtype;
event.event.setNumbers<qint32>({width, height, refcount});
break;
}
case MemoryAllocation: {
qint64 delta;
stream >> delta;
event.type.message = static_cast<Message>(messageType);
event.type.rangeType = MaximumRangeType;
event.type.detailType = subtype;
event.event.setNumbers<qint64>({delta});
break;
}
case RangeStart: {
// read and ignore binding type
if (rangeType == Binding && !stream.atEnd()) {
qint32 bindingType;
stream >> bindingType;
}
event.type.message = MaximumMessage;
event.type.rangeType = rangeType;
event.event.setRangeStage(RangeStart);
event.type.detailType = -1;
break;
}
case RangeData: {
stream >> event.type.data;
event.type.message = MaximumMessage;
event.type.rangeType = rangeType;
event.event.setRangeStage(RangeData);
event.type.detailType = -1;
break;
}
case RangeLocation: {
stream >> event.type.location.filename
>> static_cast<qint32 &>(event.type.location.line);
if (!stream.atEnd())
stream >> static_cast<qint32 &>(event.type.location.column);
else
event.type.location.column = -1;
event.type.message = MaximumMessage;
event.type.rangeType = rangeType;
event.event.setRangeStage(RangeLocation);
event.type.detailType = -1;
break;
}
case RangeEnd: {
event.type.message = MaximumMessage;
event.type.rangeType = rangeType;
event.event.setRangeStage(RangeEnd);
event.type.detailType = -1;
break;
}
default:
event.type.message = static_cast<Message>(messageType);
event.type.rangeType = MaximumRangeType;
event.type.detailType = subtype;
break;
}
return stream;
}
} // namespace QmlProfiler
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "qmlevent.h"
#include "qmleventtype.h"
#include <QDataStream>
namespace QmlProfiler {
struct QmlTypedEvent
{
QmlEvent event;
QmlEventType type;
};
QDataStream &operator>>(QDataStream &stream, QmlTypedEvent &event);
} // namespace QmlProfiler
......@@ -150,71 +150,79 @@ void SceneGraphTimelineModel::loadData()
// look incomplete if that was left out as the printf profiler lists it, too, and people
// are apparently comparing that. Unfortunately it is somewhat redundant as the other
// parts of the breakdown are usually very short.
qint64 startTime = event.timestamp() - event.numericData(0) - event.numericData(1) -
event.numericData(2) - event.numericData(3);
startTime += insert(startTime, event.numericData(0), event.typeIndex(), RenderPreprocess);
startTime += insert(startTime, event.numericData(1), event.typeIndex(), RenderUpdate);
startTime += insert(startTime, event.numericData(2), event.typeIndex(), RenderBind);
insert(startTime, event.numericData(3), event.typeIndex(), RenderRender);
qint64 startTime = event.timestamp() - event.number<qint64>(0) - event.number<qint64>(1)
- event.number<qint64>(2) - event.number<qint64>(3);
startTime += insert(startTime, event.number<qint64>(0), event.typeIndex(),
RenderPreprocess);
startTime += insert(startTime, event.number<qint64>(1), event.typeIndex(),
RenderUpdate);
startTime += insert(startTime, event.number<qint64>(2), event.typeIndex(), RenderBind);
insert(startTime, event.number<qint64>(3), event.typeIndex(), RenderRender);
break;
}
case SceneGraphAdaptationLayerFrame: {
qint64 startTime = event.timestamp() - event.numericData(1) - event.numericData(2);
startTime += insert(startTime, event.numericData(1), event.typeIndex(), GlyphRender,
event.numericData(0));
insert(startTime, event.numericData(2), event.typeIndex(), GlyphStore, event.numericData(0));
qint64 startTime = event.timestamp() - event.number<qint64>(1)
- event.number<qint64>(2);
startTime += insert(startTime, event.number<qint64>(1), event.typeIndex(), GlyphRender,
event.number<qint64>(0));
insert(startTime, event.number<qint64>(2), event.typeIndex(), GlyphStore,
event.number<qint64>(0));
break;
}
case SceneGraphContextFrame: {
insert(event.timestamp() - event.numericData(0), event.numericData(0), event.typeIndex(),
Material);
insert(event.timestamp() - event.number<qint64>(0), event.number<qint64>(0),
event.typeIndex(), Material);
break;
}
case SceneGraphRenderLoopFrame: {
qint64 startTime = event.timestamp() - event.numericData(0) - event.numericData(1) -
event.numericData(2);
startTime += insert(startTime, event.numericData(0), event.typeIndex(),
RenderThreadSync);
startTime += insert(startTime, event.numericData(1), event.typeIndex(),
Render);
insert(startTime, event.numericData(2), event.typeIndex(), Swap);
qint64 startTime = event.timestamp() - event.number<qint64>(0) - event.number<qint64>(1)
- event.number<qint64>(2);
startTime += insert(startTime, event.number<qint64>(0), event.typeIndex(),
RenderThreadSync);
startTime += insert(startTime, event.number<qint64>(1), event.typeIndex(),
Render);
insert(startTime, event.number<qint64>(2), event.typeIndex(), Swap);
break;
}
case SceneGraphTexturePrepare: {
qint64 startTime = event.timestamp() - event.numericData(0) - event.numericData(1) -
event.numericData(2) - event.numericData(3) - event.numericData(4);
startTime += insert(startTime, event.numericData(0), event.typeIndex(), TextureBind);
startTime += insert(startTime, event.numericData(1), event.typeIndex(), TextureConvert);
startTime += insert(startTime, event.numericData(2), event.typeIndex(), TextureSwizzle);
startTime += insert(startTime, event.numericData(3), event.typeIndex(), TextureUpload);
insert(startTime, event.numericData(4), event.typeIndex(), TextureMipmap);
qint64 startTime = event.timestamp() - event.number<qint64>(0) - event.number<qint64>(1)
- event.number<qint64>(2) - event.number<qint64>(3) - event.number<qint64>(4);
startTime += insert(startTime, event.number<qint64>(0), event.typeIndex(), TextureBind);
startTime += insert(startTime, event.number<qint64>(1), event.typeIndex(),
TextureConvert);
startTime += insert(startTime, event.number<qint64>(2), event.typeIndex(),
TextureSwizzle);
startTime += insert(startTime, event.number<qint64>(3), event.typeIndex(),
TextureUpload);
insert(startTime, event.number<qint64>(4), event.typeIndex(), TextureMipmap);
break;
}
case SceneGraphTextureDeletion: {
insert(event.timestamp() - event.numericData(0), event.numericData(0), event.typeIndex(),
TextureDeletion);
insert(event.timestamp() - event.number<qint64>(0), event.number<qint64>(0),
event.typeIndex(), TextureDeletion);
break;
}
case SceneGraphPolishAndSync: {
qint64 startTime = event.timestamp() - event.numericData(0) - event.numericData(1) -
event.numericData(2) - event.numericData(3);
startTime += insert(startTime, event.numericData(0), event.typeIndex(), Polish);
startTime += insert(startTime, event.numericData(1), event.typeIndex(), Wait);
startTime += insert(startTime, event.numericData(2), event.typeIndex(), GUIThreadSync);
insert(startTime, event.numericData(3), event.typeIndex(), Animations);
qint64 startTime = event.timestamp() - event.number<qint64>(0) - event.number<qint64>(1)
- event.number<qint64>(2) - event.number<qint64>(3);
startTime += insert(startTime, event.number<qint64>(0), event.typeIndex(), Polish);
startTime += insert(startTime, event.number<qint64>(1), event.typeIndex(), Wait);
startTime += insert(startTime, event.number<qint64>(2), event.typeIndex(),
GUIThreadSync);
insert(startTime, event.number<qint64>(3), event.typeIndex(), Animations);
break;
}
case SceneGraphWindowsAnimations: {
// GUI thread, separate animations stage
insert(event.timestamp() - event.numericData(0), event.numericData(0), event.typeIndex(),
Animations);
insert(event.timestamp() - event.number<qint64>(0), event.number<qint64>(0),
event.typeIndex(), Animations);
break;
}
case SceneGraphPolishFrame: {
// GUI thread, separate polish stage
insert(event.timestamp() - event.numericData(0), event.numericData(0), event.typeIndex(),
Polish);
insert(event.timestamp() - event.number<qint64>(0), event.number<qint64>(0),