QmlProfiler: Filter event types also on client side

Like this we can still save some time and memory if the profiled
application doesn't support filtering.

Change-Id: I534ad4a11f62d28bd2fcfbffdc44f3902758dcbe
Task-number: QTBUG-41118
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Ulf Hermann
2014-09-10 13:51:36 +02:00
parent 6d58de0bad
commit 69743fef93
3 changed files with 174 additions and 137 deletions

View File

@@ -136,6 +136,26 @@ enum ProfileFeature {
MaximumProfileFeature MaximumProfileFeature
}; };
inline ProfileFeature featureFromRangeType(RangeType range)
{
switch (range) {
case Painting:
return ProfilePainting;
case Compiling:
return ProfileCompiling;
case Creating:
return ProfileCreating;
case Binding:
return ProfileBinding;
case HandlingSignal:
return ProfileHandlingSignal;
case Javascript:
return ProfileJavaScript;
default:
return MaximumProfileFeature;
}
}
namespace Constants { namespace Constants {
const int QML_MIN_LEVEL = 1; // Set to 0 to remove the empty line between models in the timeline const int QML_MIN_LEVEL = 1; // Set to 0 to remove the empty line between models in the timeline

View File

@@ -159,26 +159,34 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
qint64 time; qint64 time;
int messageType; int messageType;
int subtype;
stream >> time >> messageType; stream >> time >> messageType;
if (!stream.atEnd())
if (messageType >= MaximumMessage) stream >> subtype;
return; else
subtype = -1;
if (time > (d->maximumTime + GAP_TIME) && 0 == d->inProgressRanges) if (time > (d->maximumTime + GAP_TIME) && 0 == d->inProgressRanges)
emit gap(time); emit gap(time);
if (messageType == Event) { switch (messageType) {
int event; case Event: {
stream >> event; switch (subtype) {
case StartTrace: {
// stop with the first data if (!d->recording)
if (d->recording && event != StartTrace)
setRecordingFromServer(false);
else if ((!d->recording) && event == StartTrace)
setRecordingFromServer(true); setRecordingFromServer(true);
QList<int> engineIds;
if (event == EndTrace) { while (!stream.atEnd()) {
int id;
stream >> id;
engineIds << id;
}
emit this->traceStarted(time, engineIds);
d->maximumTime = time;
break;
}
case EndTrace: {
QList<int> engineIds; QList<int> engineIds;
while (!stream.atEnd()) { while (!stream.atEnd()) {
int id; int id;
@@ -188,7 +196,11 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
emit this->traceFinished(time, engineIds); emit this->traceFinished(time, engineIds);
d->maximumTime = time; d->maximumTime = time;
d->maximumTime = qMax(time, d->maximumTime); d->maximumTime = qMax(time, d->maximumTime);
} else if (event == AnimationFrame) { break;
}
case AnimationFrame: {
if (!(d->features & (1 << ProfileAnimations)))
break;
int frameRate, animationCount; int frameRate, animationCount;
int threadId; int threadId;
stream >> frameRate >> animationCount; stream >> frameRate >> animationCount;
@@ -196,94 +208,107 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
stream >> threadId; stream >> threadId;
else else
threadId = 0; threadId = 0;
emit rangedEvent(Event, MaximumRangeType, AnimationFrame, time, 0, QString(), emit rangedEvent(Event, MaximumRangeType, AnimationFrame, time, 0, QString(),
QmlDebug::QmlEventLocation(), frameRate, animationCount, threadId,0,0); QmlDebug::QmlEventLocation(), frameRate, animationCount, threadId,
0, 0);
d->maximumTime = qMax(time, d->maximumTime); d->maximumTime = qMax(time, d->maximumTime);
} else if (event == StartTrace) { break;
QList<int> engineIds;
while (!stream.atEnd()) {
int id;
stream >> id;
engineIds << id;
} }
emit this->traceStarted(time, engineIds); case Key:
d->maximumTime = time; case Mouse:
} else if (event < MaximumEventType) { if (!(d->features & (1 << ProfileInputEvents)))
emit this->event((EventType)event, time); break;
emit this->event((EventType)subtype, time);
d->maximumTime = qMax(time, d->maximumTime); d->maximumTime = qMax(time, d->maximumTime);
break;
} }
} else if (messageType == Complete) {
break;
}
case Complete:
emit complete(d->maximumTime); emit complete(d->maximumTime);
} else if (messageType == SceneGraphFrame) { break;
int sgEventType; case SceneGraphFrame: {
if (!(d->features & (1 << ProfileSceneGraph)))
break;
int count = 0; int count = 0;
qint64 params[5]; qint64 params[5];
stream >> sgEventType;
while (!stream.atEnd()) { while (!stream.atEnd()) {
stream >> params[count++]; stream >> params[count++];
} }
while (count<5) while (count<5)
params[count++] = 0; params[count++] = 0;
emit rangedEvent(SceneGraphFrame, QmlDebug::MaximumRangeType, sgEventType,time, 0, emit rangedEvent(SceneGraphFrame, QmlDebug::MaximumRangeType, subtype,time, 0,
QString(), QmlDebug::QmlEventLocation(), params[0], params[1], QString(), QmlDebug::QmlEventLocation(), params[0], params[1],
params[2], params[3], params[4]); params[2], params[3], params[4]);
} else if (messageType == PixmapCacheEvent) { break;
int pixEvTy, width = 0, height = 0, refcount = 0; }
case PixmapCacheEvent: {
if (!(d->features & (1 << ProfilePixmapCache)))
break;
int width = 0, height = 0, refcount = 0;
QString pixUrl; QString pixUrl;
stream >> pixEvTy >> pixUrl; stream >> pixUrl;
if (pixEvTy == (int)PixmapReferenceCountChanged || pixEvTy == (int)PixmapCacheCountChanged) { if (subtype == (int)PixmapReferenceCountChanged || subtype == (int)PixmapCacheCountChanged) {
stream >> refcount; stream >> refcount;
} else if (pixEvTy == (int)PixmapSizeKnown) { } else if (subtype == (int)PixmapSizeKnown) {
stream >> width >> height; stream >> width >> height;
refcount = 1; refcount = 1;
} }
emit rangedEvent(QmlDebug::PixmapCacheEvent, QmlDebug::MaximumRangeType, pixEvTy, time, 0, emit rangedEvent(QmlDebug::PixmapCacheEvent, QmlDebug::MaximumRangeType, subtype, time, 0,
QString(), QmlDebug::QmlEventLocation(pixUrl,0,0), width, height, QString(), QmlDebug::QmlEventLocation(pixUrl,0,0), width, height,
refcount, 0, 0); refcount, 0, 0);
d->maximumTime = qMax(time, d->maximumTime); d->maximumTime = qMax(time, d->maximumTime);
} else if (messageType == MemoryAllocation) { break;
int type; }
case MemoryAllocation: {
if (!(d->features & (1 << ProfileMemory)))
break;
qint64 delta; qint64 delta;
stream >> type >> delta; stream >> delta;
emit rangedEvent(QmlDebug::MemoryAllocation, QmlDebug::MaximumRangeType, type, time, 0, emit rangedEvent(QmlDebug::MemoryAllocation, QmlDebug::MaximumRangeType, subtype, time, 0,
QString(), QmlDebug::QmlEventLocation(), delta, 0, 0, 0, 0); QString(), QmlDebug::QmlEventLocation(), delta, 0, 0, 0, 0);
d->maximumTime = qMax(time, d->maximumTime); d->maximumTime = qMax(time, d->maximumTime);
} else { break;
int range; }
stream >> range; case RangeStart: {
if (!(d->features & (1 << featureFromRangeType(static_cast<RangeType>(subtype)))))
if (range >= MaximumRangeType) break;
return; d->rangeStartTimes[subtype].push(time);
d->inProgressRanges |= (static_cast<qint64>(1) << subtype);
if (messageType == RangeStart) { ++d->rangeCount[subtype];
d->rangeStartTimes[range].push(time);
d->inProgressRanges |= (static_cast<qint64>(1) << range);
++d->rangeCount[range];
// read binding type // read binding type
if ((RangeType)range == Binding) { if ((RangeType)subtype == Binding) {
int bindingType = (int)QmlBinding; int bindingType = (int)QmlBinding;
if (!stream.atEnd()) if (!stream.atEnd())
stream >> bindingType; stream >> bindingType;
d->bindingTypes.push((BindingType)bindingType); d->bindingTypes.push((BindingType)bindingType);
} }
break;
// stop with the first data }
if (d->recording) case RangeData: {
setRecordingFromServer(false); if (!(d->features & (1 << featureFromRangeType(static_cast<RangeType>(subtype)))))
} else if (messageType == RangeData) { break;
QString data; QString data;
stream >> data; stream >> data;
int count = d->rangeCount[range]; int count = d->rangeCount[subtype];
if (count > 0) { if (count > 0) {
while (d->rangeDatas[range].count() < count) while (d->rangeDatas[subtype].count() < count)
d->rangeDatas[range].push(QString()); d->rangeDatas[subtype].push(QString());
d->rangeDatas[range][count-1] = data; d->rangeDatas[subtype][count-1] = data;
} }
break;
} else if (messageType == RangeLocation) { }
case RangeLocation: {
if (!(d->features & (1 << featureFromRangeType(static_cast<RangeType>(subtype)))))
break;
QString fileName; QString fileName;
int line; int line;
int column = -1; int column = -1;
@@ -292,34 +317,45 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
if (!stream.atEnd()) if (!stream.atEnd())
stream >> column; stream >> column;
if (d->rangeCount[range] > 0) if (d->rangeCount[subtype] > 0)
d->rangeLocations[range].push(QmlEventLocation(fileName, line, column)); d->rangeLocations[subtype].push(QmlEventLocation(fileName, line, column));
} else { break;
if (d->rangeCount[range] > 0) { }
--d->rangeCount[range]; case RangeEnd: {
if (d->inProgressRanges & (static_cast<qint64>(1) << range)) if (!(d->features & (1 << featureFromRangeType(static_cast<RangeType>(subtype)))))
d->inProgressRanges &= ~(static_cast<qint64>(1) << range); break;
if (d->rangeCount[subtype] == 0)
break;
--d->rangeCount[subtype];
if (d->inProgressRanges & (static_cast<qint64>(1) << subtype))
d->inProgressRanges &= ~(static_cast<qint64>(1) << subtype);
d->maximumTime = qMax(time, d->maximumTime); d->maximumTime = qMax(time, d->maximumTime);
QString data = d->rangeDatas[range].count() ? d->rangeDatas[range].pop() : QString(); QString data = d->rangeDatas[subtype].count() ? d->rangeDatas[subtype].pop() : QString();
QmlEventLocation location = d->rangeLocations[range].count() ? d->rangeLocations[range].pop() : QmlEventLocation(); QmlEventLocation location = d->rangeLocations[subtype].count() ? d->rangeLocations[subtype].pop() : QmlEventLocation();
qint64 startTime = d->rangeStartTimes[range].pop(); qint64 startTime = d->rangeStartTimes[subtype].pop();
BindingType bindingType = QmlBinding; BindingType bindingType = QmlBinding;
if ((RangeType)range == Binding) if ((RangeType)subtype == Binding)
bindingType = d->bindingTypes.pop(); bindingType = d->bindingTypes.pop();
if ((RangeType)range == Painting) if ((RangeType)subtype == Painting)
bindingType = QPainterEvent; bindingType = QPainterEvent;
emit rangedEvent(MaximumMessage, (RangeType)range, bindingType, startTime, emit rangedEvent(MaximumMessage, (RangeType)subtype, bindingType, startTime,
time - startTime, data, location, 0, 0, 0, 0, 0); time - startTime, data, location, 0, 0, 0, 0, 0);
if (d->rangeCount[range] == 0) { if (d->rangeCount[subtype] == 0) {
int count = d->rangeDatas[range].count() + int count = d->rangeDatas[subtype].count() +
d->rangeStartTimes[range].count() + d->rangeStartTimes[subtype].count() +
d->rangeLocations[range].count(); d->rangeLocations[subtype].count();
if (count != 0) if (count != 0)
qWarning() << "incorrectly nested data"; qWarning() << "incorrectly nested data";
} }
break;
} }
default:
break;
} }
}
// stop with the first data
if (messageType != Event || subtype != StartTrace)
setRecordingFromServer(false);
} }

View File

@@ -44,15 +44,6 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
static const QmlDebug::ProfileFeature RangeFeatures[QmlDebug::MaximumRangeType] = {
QmlDebug::ProfilePainting,
QmlDebug::ProfileCompiling,
QmlDebug::ProfileCreating,
QmlDebug::ProfileBinding,
QmlDebug::ProfileHandlingSignal,
QmlDebug::ProfileJavaScript
};
class RangeTimelineModel::RangeTimelineModelPrivate : public AbstractTimelineModelPrivate class RangeTimelineModel::RangeTimelineModelPrivate : public AbstractTimelineModelPrivate
{ {
public: public:
@@ -82,7 +73,7 @@ RangeTimelineModel::RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *p
quint64 RangeTimelineModel::features() const quint64 RangeTimelineModel::features() const
{ {
Q_D(const RangeTimelineModel); Q_D(const RangeTimelineModel);
return 1 << RangeFeatures[d->rangeType]; return 1 << QmlDebug::featureFromRangeType(d->rangeType);
} }
void RangeTimelineModel::clear() void RangeTimelineModel::clear()
@@ -239,18 +230,8 @@ int RangeTimelineModel::rowCount() const
QString RangeTimelineModel::categoryLabel(QmlDebug::RangeType rangeType) QString RangeTimelineModel::categoryLabel(QmlDebug::RangeType rangeType)
{ {
switch (rangeType) {
case QmlDebug::Painting:
case QmlDebug::Compiling:
case QmlDebug::Creating:
case QmlDebug::Binding:
case QmlDebug::HandlingSignal:
case QmlDebug::Javascript:
return QCoreApplication::translate("MainView", return QCoreApplication::translate("MainView",
QmlProfilerModelManager::featureName(RangeFeatures[rangeType])); QmlProfilerModelManager::featureName(QmlDebug::featureFromRangeType(rangeType)));
default:
return QString();
}
} }
int RangeTimelineModel::row(int index) const int RangeTimelineModel::row(int index) const