aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-05-21 10:35:42 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-06-09 18:31:55 +0000
commitdb69cd87d3c70a4094825846e6d208c2c492c010 (patch)
tree68006c2d5ec745d8ca862289322c2580d65db43a /tools
parent08533d26596bb56f971081e2951d48ca26ff90a5 (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.cpp72
-rw-r--r--tools/qmlprofiler/qmlprofilerapplication.h1
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.cpp47
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.h2
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);