QmlProfiler: Remove detailed progress tracking

The progress bar in the state widget was rather meaningless. We rarely
know how many events we expect and it's rather hard to tell how long
each model will take to process them. Instead, we just show a 0-ranged
progress bar to tell the user that "something is happening".

Change-Id: Icb80840d1f0a1538bcf254faa37cbb36e25d342c
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Ulf Hermann
2016-05-11 13:58:20 +02:00
parent 46e043ed1e
commit 1093be0425
15 changed files with 9 additions and 126 deletions

View File

@@ -116,11 +116,9 @@ void DebugMessagesModel::loadData()
MessageData(event.string(), event.typeIndex()));
if (type.detailType > m_maximumMsgType)
m_maximumMsgType = event.typeIndex();
updateProgress(count(), simpleModel->events().count());
}
setCollapsedRowCount(2);
setExpandedRowCount(m_maximumMsgType + 2);
updateProgress(1, 1);
}
void DebugMessagesModel::clear()

View File

@@ -50,16 +50,12 @@ FlameGraphModel::FlameGraphModel(QmlProfilerModelManager *modelManager,
this, [this](int typeId, int, int){loadNotes(typeId, true);});
m_modelId = modelManager->registerModelProxy();
// We're iterating twice in loadData.
modelManager->setProxyCountWeight(m_modelId, 2);
m_acceptedTypes << Compiling << Creating << Binding << HandlingSignal << Javascript;
modelManager->announceFeatures(m_modelId, Constants::QML_JS_RANGE_FEATURES);
}
void FlameGraphModel::clear()
{
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
m_stackBottom = FlameGraphData();
m_typeIdsWithNotes.clear();
}
@@ -134,8 +130,6 @@ void FlameGraphModel::loadData(qint64 rangeStart, qint64 rangeEnd)
callStack.push(event);
stackTop = pushChild(stackTop, event);
m_modelManager->modelProxyCountUpdated(m_modelId, i, eventList.count());
}
foreach (FlameGraphData *child, m_stackBottom.children)
@@ -143,7 +137,6 @@ void FlameGraphModel::loadData(qint64 rangeStart, qint64 rangeEnd)
loadNotes(-1, false);
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
endResetModel();
}

View File

@@ -162,11 +162,9 @@ void InputEventsModel::loadData()
} else if (m_keyTypeId == -1) {
m_keyTypeId = event.typeIndex();
}
updateProgress(count(), simpleModel->events().count());
}
setCollapsedRowCount(2);
setExpandedRowCount(3);
updateProgress(1, 1);
}
void InputEventsModel::clear()

View File

@@ -217,8 +217,6 @@ void MemoryUsageModel::loadData()
m_data.insert(currentJSHeapIndex, allocation);
}
}
updateProgress(count(), simpleModel->events().count());
}
if (currentJSHeapIndex != -1)
@@ -232,7 +230,6 @@ void MemoryUsageModel::loadData()
computeNesting();
setExpandedRowCount(3);
setCollapsedRowCount(3);
updateProgress(1, 1);
}
void MemoryUsageModel::clear()

View File

@@ -397,8 +397,6 @@ void PixmapCacheModel::loadData()
default:
break;
}
updateProgress(count(), 2 * simpleModel->events().count());
}
if (lastCacheSizeEvent != -1)
@@ -410,8 +408,6 @@ void PixmapCacheModel::loadData()
computeMaxCacheSize();
flattenLoads();
computeNesting();
updateProgress(1, 1);
}
void PixmapCacheModel::clear()

View File

@@ -110,14 +110,11 @@ void QmlProfilerAnimationsModel::loadData()
m_maxRenderThreadAnimations);
minNextStartTimes[lastThread] = event.timestamp() + 1;
updateProgress(count(), referenceList.count());
}
computeNesting();
setExpandedRowCount((m_maxGuiThreadAnimations == 0 || m_maxRenderThreadAnimations == 0) ? 2 : 3);
setCollapsedRowCount(expandedRowCount());
updateProgress(1, 1);
}
int QmlProfilerAnimationsModel::rowFromThreadId(int threadId) const

View File

@@ -111,9 +111,6 @@ QmlProfilerDataModel::QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinde
this, &QmlProfilerDataModel::detailsDone);
connect(this, &QmlProfilerDataModel::requestReload,
d->detailsRewriter, &QmlProfilerDetailsRewriter::reloadDocuments);
// The document loading is very expensive.
d->modelManager->setProxyCountWeight(d->modelId, 4);
}
QmlProfilerDataModel::~QmlProfilerDataModel()
@@ -145,8 +142,6 @@ void QmlProfilerDataModel::setData(qint64 traceStart, qint64 traceEnd,
d->eventTypes = types;
for (int id = 0; id < types.count(); ++id)
d->eventTypeIds[types[id]] = id;
// Half the work is done. processData() will do the rest.
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 2);
}
int QmlProfilerDataModel::count() const
@@ -162,7 +157,6 @@ void QmlProfilerDataModel::clear()
d->eventTypes.clear();
d->eventTypeIds.clear();
d->detailsRewriter->clearRequests();
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
emit changed();
}
@@ -228,7 +222,6 @@ void QmlProfilerDataModel::processData()
continue;
d->detailsRewriter->requestDetailsForLocation(i, event->location);
d->modelManager->modelProxyCountUpdated(d->modelId, i + n, n * 2);
}
// Allow changed() event only after documents have been reloaded to avoid
@@ -260,9 +253,6 @@ void QmlProfilerDataModel::addEvent(Message message, RangeType rangeType, int de
}
d->eventList.append(eventData);
d->modelManager->modelProxyCountUpdated(d->modelId, startTime,
d->modelManager->traceTime()->duration() * 2);
}
qint64 QmlProfilerDataModel::lastTimeMark() const
@@ -287,7 +277,6 @@ void QmlProfilerDataModel::detailsDone()
{
Q_D(QmlProfilerDataModel);
emit changed();
d->modelManager->modelProxyCountUpdated(d->modelId, isEmpty() ? 0 : 1, 1);
d->modelManager->processingDone();
}

View File

@@ -132,24 +132,17 @@ public:
QmlProfilerModelManager::State state;
QmlProfilerTraceTime *traceTime;
QVector<double> partialCounts;
QVector<int> partialCountWeights;
int numRegisteredModels;
quint64 availableFeatures;
quint64 visibleFeatures;
quint64 recordedFeatures;
int totalWeight;
double progress;
double previousProgress;
};
QmlProfilerModelManager::QmlProfilerModelManager(Utils::FileInProjectFinder *finder, QObject *parent) :
QObject(parent), d(new QmlProfilerModelManagerPrivate)
{
d->totalWeight = 0;
d->previousProgress = 0;
d->progress = 0;
d->numRegisteredModels = 0;
d->availableFeatures = 0;
d->visibleFeatures = 0;
d->recordedFeatures = 0;
@@ -184,42 +177,9 @@ bool QmlProfilerModelManager::isEmpty() const
return d->model->isEmpty();
}
double QmlProfilerModelManager::progress() const
{
return d->progress;
}
int QmlProfilerModelManager::registerModelProxy()
{
d->partialCounts << 0;
d->partialCountWeights << 1;
d->totalWeight++;
return d->partialCounts.count()-1;
}
void QmlProfilerModelManager::setProxyCountWeight(int proxyId, int weight)
{
d->totalWeight += weight - d->partialCountWeights[proxyId];
d->partialCountWeights[proxyId] = weight;
}
void QmlProfilerModelManager::modelProxyCountUpdated(int proxyId, qint64 count, qint64 max)
{
d->progress -= d->partialCounts[proxyId] * d->partialCountWeights[proxyId] /
d->totalWeight;
if (max <= 0)
d->partialCounts[proxyId] = 1;
else
d->partialCounts[proxyId] = (double)count / (double) max;
d->progress += d->partialCounts[proxyId] * d->partialCountWeights[proxyId] /
d->totalWeight;
if (d->progress - d->previousProgress > 0.01) {
d->previousProgress = d->progress;
emit progressChanged();
}
return d->numRegisteredModels++;
}
void QmlProfilerModelManager::announceFeatures(int proxyId, quint64 features)
@@ -423,10 +383,6 @@ QmlProfilerModelManager::State QmlProfilerModelManager::state() const
void QmlProfilerModelManager::clear()
{
setState(ClearingData);
for (int i = 0; i < d->partialCounts.count(); i++)
d->partialCounts[i] = 0;
d->progress = 0;
d->previousProgress = 0;
d->model->clear();
d->traceTime->clear();
d->notesModel->clear();

View File

@@ -90,10 +90,7 @@ public:
bool isEmpty() const;
double progress() const;
int registerModelProxy();
void setProxyCountWeight(int proxyId, int weight);
void modelProxyCountUpdated(int proxyId, qint64 count, qint64 max);
void announceFeatures(int proxyId, quint64 features);
quint64 availableFeatures() const;
quint64 visibleFeatures() const;
@@ -109,7 +106,6 @@ public:
signals:
void error(const QString &error);
void stateChanged();
void progressChanged();
void loadFinished();
void saveFinished();

View File

@@ -79,30 +79,19 @@ void QmlProfilerRangeModel::loadData()
// store starttime-based instance
m_data.insert(insert(event.timestamp(), event.duration(), event.typeIndex()),
QmlRangeEventStartInstance());
updateProgress(count(), eventList.count() * 5);
}
updateProgress(1, 5);
// compute range nesting
computeNesting();
updateProgress(2, 5);
// compute nestingLevel - nonexpanded
computeNestingContracted();
updateProgress(3, 5);
// compute nestingLevel - expanded
computeExpandedLevels();
updateProgress(4, 5);
if (supportsBindingLoops())
findBindingLoops();
updateProgress(1, 1);
}
void QmlProfilerRangeModel::computeNestingContracted()

View File

@@ -68,7 +68,7 @@ QmlProfilerStateWidget::QmlProfilerStateWidget(QmlProfilerStateManager *stateMan
d->progressBar = new QProgressBar(this);
layout->addWidget(d->progressBar);
d->progressBar->setMaximum(1000);
d->progressBar->setRange(0, 0);
d->progressBar->setVisible(false);
setLayout(layout);
@@ -77,8 +77,6 @@ QmlProfilerStateWidget::QmlProfilerStateWidget(QmlProfilerStateManager *stateMan
d->m_modelManager = modelManager;
connect(d->m_modelManager, &QmlProfilerModelManager::stateChanged,
this, &QmlProfilerStateWidget::updateDisplay);
connect(d->m_modelManager, &QmlProfilerModelManager::progressChanged,
this, &QmlProfilerStateWidget::updateDisplay);
d->m_profilerState = stateManager;
connect(d->m_profilerState, &QmlProfilerStateManager::stateChanged,
this, &QmlProfilerStateWidget::updateDisplay);
@@ -103,8 +101,6 @@ void QmlProfilerStateWidget::reposition()
void QmlProfilerStateWidget::showText(const QString &text, bool showProgress)
{
setVisible(true);
if (showProgress)
d->progressBar->setValue(d->m_modelManager->progress() * 1000);
d->progressBar->setVisible(showProgress);
d->text->setText(text);
resize(300, 70);
@@ -122,26 +118,25 @@ void QmlProfilerStateWidget::updateDisplay()
QmlProfilerModelManager::State state = d->m_modelManager->state();
if (state == QmlProfilerModelManager::Done || state == QmlProfilerModelManager::Empty) {
// After profiling, there is an empty trace
if (d->m_modelManager->traceTime()->duration() > 0 &&
(d->m_modelManager->isEmpty() || d->m_modelManager->progress() == 0)) {
if (d->m_modelManager->traceTime()->duration() > 0 && d->m_modelManager->isEmpty()) {
showText(tr("No QML events recorded"));
return;
}
} else if (d->m_modelManager->progress() != 0 && !d->m_modelManager->isEmpty()) {
} else if (!d->m_modelManager->isEmpty()) {
// When datamodel is acquiring or processing data
if (state == QmlProfilerModelManager::ProcessingData) {
showText(tr("Processing data"), true);
} else if (d->m_profilerState->currentState() != QmlProfilerStateManager::Idle) {
} 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"));
showText(tr("Loading buffered 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"));
showText(tr("Loading offline data"));
} else if (state == QmlProfilerModelManager::ClearingData) {
showText(tr("Clearing old trace"));
}

View File

@@ -63,9 +63,6 @@ QmlProfilerStatisticsModel::QmlProfilerStatisticsModel(QmlProfilerModelManager *
this, &QmlProfilerStatisticsModel::notesChanged);
d->modelId = modelManager->registerModelProxy();
// We're iterating twice in loadData.
modelManager->setProxyCountWeight(d->modelId, 2);
d->acceptedTypes << Compiling << Creating << Binding << HandlingSignal << Javascript;
modelManager->announceFeatures(d->modelId, Constants::QML_JS_RANGE_FEATURES);
@@ -106,7 +103,6 @@ const QHash<int, QString> &QmlProfilerStatisticsModel::getNotes() const
void QmlProfilerStatisticsModel::clear()
{
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
d->data.clear();
d->eventsInBindingLoop.clear();
d->notes.clear();
@@ -234,14 +230,9 @@ void QmlProfilerStatisticsModel::loadData(qint64 rangeStart, qint64 rangeEnd)
if (callStack.count() > 1)
d->data[callStack.top()->typeIndex()].durationSelf -= event->duration();
callStack.push(event);
d->modelManager->modelProxyCountUpdated(d->modelId, i, eventList.count()*2);
}
// post-process: calc mean time, median time, percentoftime
int i = d->data.size();
int total = i * 2;
for (QHash<int, QmlEventStats>::iterator it = d->data.begin(); it != d->data.end(); ++it) {
QmlEventStats* stats = &it.value();
if (stats->calls > 0)
@@ -255,7 +246,6 @@ void QmlProfilerStatisticsModel::loadData(qint64 rangeStart, qint64 rangeEnd)
stats->percentOfTime = stats->duration * 100.0 / qmlTime;
stats->percentSelf = stats->durationSelf * 100.0 / qmlTime;
d->modelManager->modelProxyCountUpdated(d->modelId, i++, total);
}
// set binding loop flag
@@ -273,7 +263,6 @@ void QmlProfilerStatisticsModel::loadData(qint64 rangeStart, qint64 rangeEnd)
d->data.insert(-1, rootEvent);
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
emit dataAvailable();
}

View File

@@ -73,7 +73,6 @@ bool QmlProfilerTimelineModel::handlesTypeId(int typeIndex) const
void QmlProfilerTimelineModel::clear()
{
TimelineModel::clear();
updateProgress(0, 1);
}
QmlProfilerModelManager *QmlProfilerTimelineModel::modelManager() const
@@ -81,11 +80,6 @@ QmlProfilerModelManager *QmlProfilerTimelineModel::modelManager() const
return m_modelManager;
}
void QmlProfilerTimelineModel::updateProgress(qint64 count, qint64 max) const
{
m_modelManager->modelProxyCountUpdated(modelId(), count, max);
}
void QmlProfilerTimelineModel::announceFeatures(quint64 features) const
{
m_modelManager->announceFeatures(modelId(), features);

View File

@@ -61,7 +61,6 @@ private slots:
void onVisibleFeaturesChanged(quint64 features);
protected:
void updateProgress(qint64 count, qint64 max) const;
void announceFeatures(quint64 features) const;
private:

View File

@@ -227,13 +227,10 @@ void SceneGraphTimelineModel::loadData()
}
default: break;
}
updateProgress(count(), simpleModel->events().count());
}
computeNesting();
flattenLoads();
updateProgress(1, 1);
}
void SceneGraphTimelineModel::flattenLoads()