Commit ffc11d5e authored by Ulf Hermann's avatar Ulf Hermann

QmlProfiler: allow for multiple sequential traces to be aggregated

Task-number: QTCREATORBUG-13317
Change-Id: Ic7d1d5c94d8d522741b6c4207a21a43f521da5fb
Reviewed-by: default avatarJoerg Bornemann <joerg.bornemann@theqtcompany.com>
parent 030acfdf
......@@ -63,6 +63,7 @@ public:
quint64 tcpPort;
QString sysroot;
quint32 flushInterval;
bool aggregateTraces;
QmlProfilerModelManager *modelManager;
};
......@@ -77,6 +78,7 @@ QmlProfilerClientManager::QmlProfilerClientManager(QObject *parent) :
d->connection = 0;
d->connectionAttempts = 0;
d->flushInterval = 0;
d->aggregateTraces = true;
d->modelManager = 0;
......@@ -101,6 +103,16 @@ void QmlProfilerClientManager::setFlushInterval(quint32 flushInterval)
d->flushInterval = flushInterval;
}
bool QmlProfilerClientManager::aggregateTraces() const
{
return d->aggregateTraces;
}
void QmlProfilerClientManager::setAggregateTraces(bool aggregateTraces)
{
d->aggregateTraces = aggregateTraces;
}
void QmlProfilerClientManager::setTcpConnection(QString host, quint64 port)
{
d->tcpHost = host;
......@@ -349,7 +361,7 @@ void QmlProfilerClientManager::retryMessageBoxFinished(int result)
void QmlProfilerClientManager::qmlComplete(qint64 maximumTime)
{
d->modelManager->traceTime()->increaseEndTime(maximumTime);
if (d->modelManager)
if (d->modelManager && !d->aggregateTraces)
d->modelManager->acquiringDone();
}
......
......@@ -61,6 +61,9 @@ public:
void setModelManager(QmlProfilerModelManager *m);
void setFlushInterval(quint32 flushInterval);
bool aggregateTraces() const;
void setAggregateTraces(bool aggregateTraces);
signals:
void connectionFailed();
void connectionClosed();
......
......@@ -46,6 +46,9 @@ QmlProfilerConfigWidget::QmlProfilerConfigWidget(QmlProfilerSettings *settings,
connect(m_ui->flushInterval, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
m_settings, &QmlProfilerSettings::setFlushInterval);
connect(m_ui->aggregateTraces, &QCheckBox::toggled,
m_settings, &QmlProfilerSettings::setAggregateTraces);
connect(m_settings, &QmlProfilerSettings::changed, this, &QmlProfilerConfigWidget::updateUi);
}
......@@ -59,6 +62,7 @@ void QmlProfilerConfigWidget::updateUi()
m_ui->flushEnabled->setChecked(m_settings->flushEnabled());
m_ui->flushInterval->setEnabled(m_settings->flushEnabled());
m_ui->flushInterval->setValue(m_settings->flushInterval());
m_ui->aggregateTraces->setChecked(m_settings->aggregateTraces());
}
} // Internal
......
......@@ -47,6 +47,23 @@ itself takes time. </string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="aggregateTracesLabel">
<property name="text">
<string>Process data only when process ends:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="aggregateTraces">
<property name="toolTip">
<string>Only process data when the process being profiled ends, not when the current recording
session ends. This way multiple recording sessions can be aggregated in a single trace,
for example if multiple QML engines start and stop sequentially during a single run of
the program.</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
......
......@@ -41,6 +41,7 @@ const char TASK_SAVE[] = "QmlProfiler.TaskSave";
const char FLUSH_ENABLED[] = "Analyzer.QmlProfiler.FlushEnabled";
const char FLUSH_INTERVAL[] = "Analyzer.QmlProfiler.FlushInterval";
const char LAST_TRACE_FILE[] = "Analyzer.QmlProfiler.LastTraceFile";
const char AGGREGATE_TRACES[] = "Analyzer.QmlProfiler.AggregateTraces";
const char SETTINGS[] = "Analyzer.QmlProfiler.Settings";
const char ANALYZER[] = "Analyzer";
......
......@@ -45,6 +45,7 @@ QmlProfilerSettings::QmlProfilerSettings()
defaults.insert(QLatin1String(Constants::FLUSH_INTERVAL), 1000);
defaults.insert(QLatin1String(Constants::FLUSH_ENABLED), false);
defaults.insert(QLatin1String(Constants::LAST_TRACE_FILE), QString());
defaults.insert(QLatin1String(Constants::AGGREGATE_TRACES), false);
// Read stored values
QSettings *settings = Core::ICore::settings();
......@@ -106,6 +107,19 @@ void QmlProfilerSettings::setLastTraceFile(const QString &lastTracePath)
}
}
bool QmlProfilerSettings::aggregateTraces() const
{
return m_aggregateTraces;
}
void QmlProfilerSettings::setAggregateTraces(bool aggregateTraces)
{
if (m_aggregateTraces != aggregateTraces) {
m_aggregateTraces = aggregateTraces;
emit changed();
}
}
void QmlProfilerSettings::writeGlobalSettings() const
{
QSettings *settings = Core::ICore::settings();
......@@ -122,6 +136,7 @@ void QmlProfilerSettings::toMap(QVariantMap &map) const
map[QLatin1String(Constants::FLUSH_INTERVAL)] = m_flushInterval;
map[QLatin1String(Constants::FLUSH_ENABLED)] = m_flushEnabled;
map[QLatin1String(Constants::LAST_TRACE_FILE)] = m_lastTraceFile;
map[QLatin1String(Constants::AGGREGATE_TRACES)] = m_aggregateTraces;
}
void QmlProfilerSettings::fromMap(const QVariantMap &map)
......@@ -129,6 +144,7 @@ void QmlProfilerSettings::fromMap(const QVariantMap &map)
m_flushEnabled = map.value(QLatin1String(Constants::FLUSH_ENABLED)).toBool();
m_flushInterval = map.value(QLatin1String(Constants::FLUSH_INTERVAL)).toUInt();
m_lastTraceFile = map.value(QLatin1String(Constants::LAST_TRACE_FILE)).toString();
m_aggregateTraces = map.value(QLatin1String(Constants::AGGREGATE_TRACES)).toBool();
emit changed();
}
......
......@@ -53,6 +53,9 @@ public:
QString lastTraceFile() const;
void setLastTraceFile(const QString &lastTraceFile);
bool aggregateTraces() const;
void setAggregateTraces(bool aggregateTraces);
void writeGlobalSettings() const;
signals:
......@@ -66,6 +69,7 @@ private:
bool m_flushEnabled;
quint32 m_flushInterval;
QString m_lastTraceFile;
bool m_aggregateTraces;
};
} // Internal
......
......@@ -30,6 +30,8 @@
#include "qmlprofilerstatewidget.h"
#include <utils/qtcassert.h>
#include <QPainter>
#include <QVBoxLayout>
#include <QLabel>
......@@ -202,11 +204,23 @@ void QmlProfilerStateWidget::updateDisplay()
return;
}
} else if (d->m_modelManager->progress() != 0 && !d->m_modelManager->isEmpty()) {
// When datamodel is acquiring data
if (d->m_profilerState->currentState() != QmlProfilerStateManager::Idle)
showText(tr("Loading data"), true);
else // Application died before all data could be read
showText(tr("Application stopped before loading all data"), true);
// When datamodel is acquiring or processing data
if (state == QmlProfilerModelManager::ProcessingData) {
showText(tr("Processing data"), true);
} else if (d->m_profilerState->currentState() != QmlProfilerStateManager::Idle) {
if (state == QmlProfilerModelManager::AcquiringData) {
// we don't know how much more, so progress numbers are strange here
showText(tr("Waiting for more data"));
} else if (state == QmlProfilerModelManager::ClearingData) {
// when starting a second recording from the same process without aggregation
showText(tr("Clearing old trace"));
}
} else if (state == QmlProfilerModelManager::AcquiringData) {
// Application died before all data could be read
showText(tr("Application stopped before loading all data"));
} else if (state == QmlProfilerModelManager::ClearingData) {
showText(tr("Clearing old trace"));
}
return;
} else if (state == QmlProfilerModelManager::AcquiringData) {
showText(tr("Waiting for data"));
......
......@@ -209,6 +209,7 @@ AnalyzerRunControl *QmlProfilerTool::createRunControl(const AnalyzerStartParamet
d->m_profilerConnections->setFlushInterval(settings->flushEnabled() ?
settings->flushInterval() : 0);
d->m_profilerConnections->setAggregateTraces(settings->aggregateTraces());
QmlProfilerRunControl *engine = new QmlProfilerRunControl(sp, runConfiguration);
......@@ -373,7 +374,9 @@ void QmlProfilerTool::recordingButtonChanged(bool recording)
if (recording && d->m_profilerState->currentState() == QmlProfilerStateManager::AppRunning) {
if (checkForUnsavedNotes()) {
clearData(); // clear right away, before the application starts
if (!d->m_profilerConnections->aggregateTraces() ||
d->m_profilerModelManager->state() == QmlProfilerModelManager::Done)
clearData(); // clear before the recording starts, unless we aggregate recordings
if (d->m_profilerState->clientRecording())
d->m_profilerState->setClientRecording(false);
d->m_profilerState->setClientRecording(true);
......@@ -652,9 +655,13 @@ void QmlProfilerTool::clientsDisconnected()
if (d->m_profilerState->currentState() == QmlProfilerStateManager::AppDying ||
d->m_profilerState->currentState() == QmlProfilerStateManager::Idle) {
if (d->m_profilerModelManager->state() == QmlProfilerModelManager::AcquiringData) {
showNonmodalWarning(tr("Application finished before loading profiled data.\n"
"Please use the stop button instead."));
d->m_profilerModelManager->clear();
if (d->m_profilerConnections->aggregateTraces()) {
d->m_profilerModelManager->acquiringDone();
} else {
showNonmodalWarning(tr("Application finished before loading profiled data.\n"
"Please use the stop button instead."));
d->m_profilerModelManager->clear();
}
}
// ... and return to the "base" state
......@@ -822,13 +829,16 @@ void QmlProfilerTool::serverRecordingChanged()
showSaveDialog();
setRecording(true);
clearData();
if (!d->m_profilerConnections->aggregateTraces() ||
d->m_profilerModelManager->state() == QmlProfilerModelManager::Done)
clearData();
d->m_profilerModelManager->prepareForWriting();
} else {
setRecording(false);
// changes back once loading is finished, see profilerDataModelStateChanged()
d->m_recordButton->setEnabled(false);
if (!d->m_profilerConnections->aggregateTraces())
d->m_recordButton->setEnabled(false);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment