diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-05-21 10:35:42 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-06-09 18:31:55 +0000 |
commit | db69cd87d3c70a4094825846e6d208c2c492c010 (patch) | |
tree | 68006c2d5ec745d8ca862289322c2580d65db43a /tools | |
parent | 08533d26596bb56f971081e2951d48ca26ff90a5 (diff) |
qmlprofiler: Allow specification of features to record
Task-number: QTBUG-43066
Change-Id: I963a5a483f961dd150f00de3d96c723c8b62edb8
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qmlprofiler/qmlprofilerapplication.cpp | 72 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerapplication.h | 1 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerclient.cpp | 47 | ||||
-rw-r--r-- | tools/qmlprofiler/qmlprofilerclient.h | 2 |
4 files changed, 120 insertions, 2 deletions
diff --git a/tools/qmlprofiler/qmlprofilerapplication.cpp b/tools/qmlprofiler/qmlprofilerapplication.cpp index fbea376082..02dabea6e5 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.cpp +++ b/tools/qmlprofiler/qmlprofilerapplication.cpp @@ -59,6 +59,20 @@ static const char commandTextC[] = " Terminate the program if started from qmlprofiler,\n" " and qmlprofiler itself."; +static const char *features[] = { + "javascript", + "memory", + "pixmapcache", + "scenegraph", + "animations", + "painting", + "compiling", + "creating", + "binding", + "handlingsignal", + "inputevents" +}; + static const char TraceFileExtension[] = ".qtd"; QmlProfilerApplication::QmlProfilerApplication(int &argc, char **argv) : @@ -172,6 +186,26 @@ void QmlProfilerApplication::parseArguments() QLatin1String("on|off"), QLatin1String("on")); parser.addOption(record); + QStringList featureList; + for (int i = 0; i < QQmlProfilerService::MaximumProfileFeature; ++i) + featureList << QLatin1String(features[i]); + + QCommandLineOption include(QLatin1String("include"), + tr("Comma-separated list of features to record. By default all " + "features supported by the QML engine are recorded. If --include " + "is specified, only the given features will be recorded. " + "The following features are unserstood by qmlprofiler: %1").arg( + featureList.join(", ")), + QLatin1String("feature,...")); + parser.addOption(include); + + QCommandLineOption exclude(QLatin1String("exclude"), + tr("Comma-separated list of features to exclude when recording. By " + "default all features supported by the QML engine are recorded. " + "See --include for the features understood by qmlprofiler."), + QLatin1String("feature,...")); + parser.addOption(exclude); + QCommandLineOption interactive(QLatin1String("interactive"), tr("Manually control the recording from the command line. The " "profiler will not terminate itself when the application " @@ -213,6 +247,23 @@ void QmlProfilerApplication::parseArguments() m_recording = (parser.value(record) == QLatin1String("on")); m_interactive = parser.isSet(interactive); + quint64 features = std::numeric_limits<quint64>::max(); + if (parser.isSet(include)) { + if (parser.isSet(exclude)) { + logError(tr("qmlprofiler can only process either --include or --exclude, not both.")); + parser.showHelp(4); + } + features = parseFeatures(featureList, parser.value(include), false); + } + + if (parser.isSet(exclude)) + features = parseFeatures(featureList, parser.value(exclude), true); + + if (features == 0) + parser.showHelp(4); + + m_qmlProfilerClient.setFeatures(features); + if (parser.isSet(verbose)) m_verbose = true; @@ -244,6 +295,27 @@ bool QmlProfilerApplication::isInteractive() const return m_interactive; } +quint64 QmlProfilerApplication::parseFeatures(const QStringList &featureList, const QString &values, + bool exclude) +{ + quint64 features = exclude ? std::numeric_limits<quint64>::max() : 0; + QStringList givenFeatures = values.split(QLatin1Char(',')); + foreach (const QString &f, givenFeatures) { + int index = featureList.indexOf(f); + if (index < 0) { + logError(tr("Unknown feature '%1'").arg(f)); + return 0; + } + quint64 flag = static_cast<quint64>(1) << index; + features = (exclude ? (features ^ flag) : (features | flag)); + } + if (features == 0) { + logError(exclude ? tr("No features remaining to record after processing --exclude.") : + tr("No features specified for --include.")); + } + return features; +} + void QmlProfilerApplication::flush() { if (m_recording) { diff --git a/tools/qmlprofiler/qmlprofilerapplication.h b/tools/qmlprofiler/qmlprofilerapplication.h index 183bb9d644..25d9cf136d 100644 --- a/tools/qmlprofiler/qmlprofilerapplication.h +++ b/tools/qmlprofiler/qmlprofilerapplication.h @@ -90,6 +90,7 @@ private slots: void v8Complete(); private: + quint64 parseFeatures(const QStringList &featureList, const QString &values, bool exclude); bool checkOutputFile(PendingRequest pending); void flush(); void output(); diff --git a/tools/qmlprofiler/qmlprofilerclient.cpp b/tools/qmlprofiler/qmlprofilerclient.cpp index 4f06514d8d..4976a5a0d9 100644 --- a/tools/qmlprofiler/qmlprofilerclient.cpp +++ b/tools/qmlprofiler/qmlprofilerclient.cpp @@ -71,7 +71,7 @@ class QmlProfilerClientPrivate { public: QmlProfilerClientPrivate() - : inProgressRanges(0) + : inProgressRanges(0) , features(std::numeric_limits<quint64>::max()) { ::memset(rangeCount, 0, QQmlProfilerService::MaximumRangeType * sizeof(int)); @@ -83,6 +83,8 @@ public: QStack<QmlEventLocation> rangeLocations[QQmlProfilerService::MaximumRangeType]; QStack<QQmlProfilerService::BindingType> bindingTypes; int rangeCount[QQmlProfilerService::MaximumRangeType]; + + quint64 features; }; QmlProfilerClient::QmlProfilerClient( @@ -97,6 +99,11 @@ QmlProfilerClient::~QmlProfilerClient() delete d; } +void QmlProfilerClient::setFeatures(quint64 features) +{ + d->features = features; +} + void QmlProfilerClient::clearData() { ::memset(d->rangeCount, 0, @@ -109,15 +116,39 @@ void QmlProfilerClient::sendRecordingStatus(bool record) { QByteArray ba; QDataStream stream(&ba, QIODevice::WriteOnly); - stream << record; + stream << record << -1 << d->features; sendMessage(ba); } +inline QQmlProfilerService::ProfileFeature featureFromRangeType( + QQmlProfilerService::RangeType range) +{ + switch (range) { + case QQmlProfilerService::Painting: + return QQmlProfilerService::ProfilePainting; + case QQmlProfilerService::Compiling: + return QQmlProfilerService::ProfileCompiling; + case QQmlProfilerService::Creating: + return QQmlProfilerService::ProfileCreating; + case QQmlProfilerService::Binding: + return QQmlProfilerService::ProfileBinding; + case QQmlProfilerService::HandlingSignal: + return QQmlProfilerService::ProfileHandlingSignal; + case QQmlProfilerService::Javascript: + return QQmlProfilerService::ProfileJavaScript; + default: + return QQmlProfilerService::MaximumProfileFeature; + } +} + void QmlProfilerClient::messageReceived(const QByteArray &data) { QByteArray rwData = data; QDataStream stream(&rwData, QIODevice::ReadOnly); + // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings + const quint64 one = static_cast<quint64>(1); + qint64 time; int messageType; @@ -133,6 +164,8 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) if (event == QQmlProfilerService::EndTrace) { emit this->traceFinished(time); } else if (event == QQmlProfilerService::AnimationFrame) { + if (!(d->features & one << QQmlProfilerService::ProfileAnimations)) + return; int frameRate, animationCount; int threadId = 0; stream >> frameRate >> animationCount; @@ -149,6 +182,8 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) } else if (messageType == QQmlProfilerService::Complete) { emit complete(); } else if (messageType == QQmlProfilerService::SceneGraphFrame) { + if (!(d->features & one << QQmlProfilerService::ProfileSceneGraph)) + return; int sgEventType; int count = 0; qint64 params[5]; @@ -162,6 +197,8 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) emit sceneGraphFrame((QQmlProfilerService::SceneGraphFrameType)sgEventType, time, params[0], params[1], params[2], params[3], params[4]); } else if (messageType == QQmlProfilerService::PixmapCacheEvent) { + if (!(d->features & one << QQmlProfilerService::ProfilePixmapCache)) + return; int pixEvTy, width = 0, height = 0, refcount = 0; QString pixUrl; stream >> pixEvTy >> pixUrl; @@ -175,6 +212,8 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) emit pixmapCache((QQmlProfilerService::PixmapEventType)pixEvTy, time, QmlEventLocation(pixUrl,0,0), width, height, refcount); } else if (messageType == QQmlProfilerService::MemoryAllocation) { + if (!(d->features & one << QQmlProfilerService::ProfileMemory)) + return; int type; qint64 delta; stream >> type >> delta; @@ -186,6 +225,10 @@ void QmlProfilerClient::messageReceived(const QByteArray &data) if (range >= QQmlProfilerService::MaximumRangeType) return; + if (!(d->features & one << featureFromRangeType( + static_cast<QQmlProfilerService::RangeType>(range)))) + return; + if (messageType == QQmlProfilerService::RangeStart) { d->rangeStartTimes[range].push(time); d->inProgressRanges |= (static_cast<qint64>(1) << range); diff --git a/tools/qmlprofiler/qmlprofilerclient.h b/tools/qmlprofiler/qmlprofilerclient.h index 1dd5ccfea9..f41ebbd4c9 100644 --- a/tools/qmlprofiler/qmlprofilerclient.h +++ b/tools/qmlprofiler/qmlprofilerclient.h @@ -74,6 +74,8 @@ public: QmlProfilerClient(QQmlDebugConnection *client); ~QmlProfilerClient(); + void setFeatures(quint64 features); + public slots: void clearData(); void sendRecordingStatus(bool record); |