forked from qt-creator/qt-creator
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:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user