QmlProfiler: Status bar for several models

Change-Id: Icb6aa70a57ef1088b1eb00eed234a6e1d6a2fbc2
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Christiaan Janssen
2013-07-25 17:29:22 +02:00
parent b65d80ab09
commit 21689299ab
15 changed files with 143 additions and 15 deletions

View File

@@ -41,6 +41,7 @@ void AbstractTimelineModel::setModelManager(QmlProfiler::Internal::QmlProfilerMo
{
m_modelManager = modelManager;
connect(modelManager->simpleModel(),SIGNAL(changed()),this,SLOT(dataChanged()));
m_modelId = modelManager->registerModelProxy();
}
qint64 AbstractTimelineModel::traceStartTime() const

View File

@@ -107,6 +107,7 @@ signals:
protected:
QmlProfiler::Internal::QmlProfilerModelManager *m_modelManager;
int m_modelId;
};

View File

@@ -56,6 +56,8 @@ public:
QmlProfilerModelManager *modelManager;
QmlProfilerEventsModelProxy *q;
int modelId;
QVector<int> acceptedTypes;
QSet<QString> eventsInBindingLoop;
};
@@ -65,6 +67,7 @@ QmlProfilerEventsModelProxy::QmlProfilerEventsModelProxy(QmlProfilerModelManager
{
d->modelManager = modelManager;
connect(modelManager->simpleModel(), SIGNAL(changed()), this, SLOT(dataChanged()));
d->modelId = modelManager->registerModelProxy();
d->acceptedTypes << QmlDebug::Compiling << QmlDebug::Creating << QmlDebug::Binding << QmlDebug::HandlingSignal;
}
@@ -81,6 +84,7 @@ const QList<QmlProfilerEventsModelProxy::QmlEventStats> QmlProfilerEventsModelPr
void QmlProfilerEventsModelProxy::clear()
{
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
d->data.clear();
d->eventsInBindingLoop.clear();
}
@@ -92,7 +96,11 @@ void QmlProfilerEventsModelProxy::limitToRange(qint64 rangeStart, qint64 rangeEn
void QmlProfilerEventsModelProxy::dataChanged()
{
loadData();
if (d->modelManager->state() == QmlProfilerDataState::Done)
loadData();
if (d->modelManager->state() == QmlProfilerDataState::Empty)
clear();
}
QSet<QString> QmlProfilerEventsModelProxy::eventsInBindingLoop() const
@@ -199,6 +207,8 @@ void QmlProfilerEventsModelProxy::loadData(qint64 rangeStart, qint64 rangeEnd)
CallStackEntry newEntry(hash, event);
callStack.push(newEntry);
d->modelManager->modelProxyCountUpdated(d->modelId, i, eventList.count()*2);
}
// post-process: calc mean time, median time, percentoftime
@@ -243,6 +253,7 @@ void QmlProfilerEventsModelProxy::loadData(qint64 rangeStart, qint64 rangeEnd)
d->data.insert(rootEventName, rootEvent);
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
emit dataAvailable();
}

View File

@@ -139,6 +139,10 @@ public:
QmlProfilerDataState *dataState;
QmlProfilerTraceTime *traceTime;
QVector <double> partialCounts;
double progress;
qint64 estimatedTime;
// file to load
QString fileName;
};
@@ -184,6 +188,43 @@ int QmlProfilerModelManager::count() const
return d->model->count();
}
double QmlProfilerModelManager::progress() const
{
return d->progress;
}
int QmlProfilerModelManager::registerModelProxy()
{
d->partialCounts << 0;
return d->partialCounts.count()-1;
}
void QmlProfilerModelManager::modelProxyCountUpdated(int proxyId, qint64 count, qint64 max)
{
d->progress -= d->partialCounts[proxyId] / d->partialCounts.count();
if (max <= 0)
d->partialCounts[proxyId] = 1;
else
d->partialCounts[proxyId] = (double)count / (double) max;
d->progress += d->partialCounts[proxyId] / d->partialCounts.count();
emit progressChanged();
if (d->progress > 0.99)
emit dataAvailable();
}
qint64 QmlProfilerModelManager::estimatedProfilingTime() const
{
return d->estimatedTime;
}
void QmlProfilerModelManager::newTimeEstimation(qint64 estimation)
{
d->estimatedTime = estimation;
}
void QmlProfilerModelManager::addRangedEvent(int type, int bindingType, qint64 startTime, qint64 length, const QStringList &data, const QmlDebug::QmlEventLocation &location)
{
// If trace start time was not explicitly set, use the first event
@@ -313,6 +354,7 @@ void QmlProfilerModelManager::load()
complete();
}
void QmlProfilerModelManager::setState(QmlProfilerDataState::State state)
{
d->dataState->setState(state);
@@ -325,6 +367,9 @@ QmlProfilerDataState::State QmlProfilerModelManager::state() const
void QmlProfilerModelManager::clear()
{
for (int i = 0; i < d->partialCounts.count(); i++)
d->partialCounts[i] = 0;
d->progress = 0;
d->model->clear();
d->v8Model->clear();
d->traceTime->clear();

View File

@@ -107,10 +107,18 @@ public:
bool isEmpty() const;
int count() const;
double progress() const;
int registerModelProxy();
void modelProxyCountUpdated(int proxyId, qint64 count, qint64 max);
qint64 estimatedProfilingTime() const;
signals:
void countChanged();
void error(const QString &error);
void stateChanged();
void progressChanged();
void dataAvailable();
void requestDetailsForLocation(int eventType, const QmlDebug::QmlEventLocation &location);
@@ -136,6 +144,7 @@ public slots:
void setFilename(const QString &filename);
void load();
void newTimeEstimation(qint64 estimation);
private:
void setState(QmlProfilerDataState::State state);

View File

@@ -115,6 +115,7 @@ void PaintEventsModelProxy::clear()
d->minAnimationCount = 1;
d->maxAnimationCount = 1;
d->expanded = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
}
void PaintEventsModelProxy::dataChanged()
@@ -176,12 +177,16 @@ void PaintEventsModelProxy::loadData()
};
d->eventList.append(newEvent);
m_modelManager->modelProxyCountUpdated(m_modelId, d->eventList.count(), referenceList.count());
}
d->computeAnimationCountLimit();
qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
emit countChanged();
}
@@ -202,7 +207,7 @@ qint64 PaintEventsModelProxy::lastTimeMark() const
return d->eventList.last().startTime + d->eventList.last().duration;
}
bool PaintEventsModelProxy::expanded(int category) const
bool PaintEventsModelProxy::expanded(int ) const
{
return d->expanded;
}
@@ -332,6 +337,8 @@ QColor PaintEventsModelProxy::getColor(int index) const
double fpsFraction = d->eventList[index].framerate / 60.0;
if (fpsFraction > 1.0)
fpsFraction = 1.0;
if (fpsFraction < 0.0)
fpsFraction = 0.0;
return QColor::fromHsl((fpsFraction*96)+10, 76, 166);
}

View File

@@ -28,7 +28,6 @@
****************************************************************************/
#include "qmlprofilerprocessedmodel.h"
#include <qmldebug/qmlprofilereventtypes.h>
#include <utils/qtcassert.h>
#include <QUrl>

View File

@@ -28,6 +28,7 @@
****************************************************************************/
#include "qmlprofilersimplemodel.h"
#include "qmlprofilermodelmanager.h"
#include <QStringList>
#include <QVector>
#include <QDebug>
@@ -39,6 +40,9 @@ namespace Internal {
QmlProfilerSimpleModel::QmlProfilerSimpleModel(QObject *parent)
: QObject(parent)
{
m_modelManager = qobject_cast<QmlProfilerModelManager *>(parent);
Q_ASSERT(m_modelManager);
m_modelId = m_modelManager->registerModelProxy();
}
QmlProfilerSimpleModel::~QmlProfilerSimpleModel()
@@ -47,6 +51,7 @@ QmlProfilerSimpleModel::~QmlProfilerSimpleModel()
void QmlProfilerSimpleModel::clear()
{
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
eventList.clear();
emit changed();
}
@@ -73,6 +78,8 @@ void QmlProfilerSimpleModel::addRangedEvent(int type, int bindingType, qint64 st
QString::number(location.line));
QmlEventData eventData = {displayName, type, bindingType, startTime, duration, data, location, 0, 0, 0, 0, 0};
eventList.append(eventData);
m_modelManager->modelProxyCountUpdated(m_modelId, startTime, m_modelManager->estimatedProfilingTime());
}
void QmlProfilerSimpleModel::addFrameEvent(qint64 time, int framerate, int animationcount)
@@ -80,12 +87,14 @@ void QmlProfilerSimpleModel::addFrameEvent(qint64 time, int framerate, int anima
qint64 duration = 1e9 / framerate;
QmlEventData eventData = {tr("Animations"), QmlDebug::Painting, QmlDebug::AnimationFrame, time, duration, QStringList(), QmlDebug::QmlEventLocation(), framerate, animationcount, 0, 0, 0};
eventList.append(eventData);
m_modelManager->modelProxyCountUpdated(m_modelId, time, m_modelManager->estimatedProfilingTime());
}
void QmlProfilerSimpleModel::addSceneGraphEvent(int eventType, int SGEtype, qint64 startTime, qint64 timing1, qint64 timing2, qint64 timing3, qint64 timing4, qint64 timing5)
{
QmlEventData eventData = {QString(), eventType, SGEtype, startTime, 0, QStringList(), QmlDebug::QmlEventLocation(), timing1, timing2, timing3, timing4, timing5};
eventList.append(eventData);
m_modelManager->modelProxyCountUpdated(m_modelId, startTime, m_modelManager->estimatedProfilingTime());
}
void QmlProfilerSimpleModel::addPixmapCacheEvent(qint64 time, int cacheEventType, const QString &url, int width, int height, int refCount)
@@ -93,6 +102,7 @@ void QmlProfilerSimpleModel::addPixmapCacheEvent(qint64 time, int cacheEventType
QmlDebug::QmlEventLocation location(url, 0, 0);
QmlEventData eventData = {QString(), QmlDebug::PixmapCacheEvent, cacheEventType, time, 0, QStringList(), location, width, height, refCount, -1, -1};
eventList.append(eventData);
m_modelManager->modelProxyCountUpdated(m_modelId, time, m_modelManager->estimatedProfilingTime());
}
qint64 QmlProfilerSimpleModel::lastTimeMark() const
@@ -105,6 +115,7 @@ qint64 QmlProfilerSimpleModel::lastTimeMark() const
void QmlProfilerSimpleModel::complete()
{
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
emit changed();
}

View File

@@ -82,6 +82,8 @@ signals:
protected:
QVector<QmlEventData> eventList;
QmlProfilerModelManager *m_modelManager;
int m_modelId;
};
}

View File

@@ -35,6 +35,7 @@
#include <QLabel>
#include <QProgressBar>
#include <QTime>
#include <QDebug>
namespace QmlProfiler {
namespace Internal {
@@ -78,6 +79,7 @@ QmlProfilerStateWidget::QmlProfilerStateWidget(QmlProfilerStateManager *stateMan
d->progressBar = new QProgressBar(this);
layout->addWidget(d->progressBar);
d->progressBar->setMaximum(1000);
d->progressBar->setVisible(false);
setLayout(layout);
@@ -93,6 +95,8 @@ QmlProfilerStateWidget::QmlProfilerStateWidget(QmlProfilerStateManager *stateMan
d->m_modelManager = modelManager;
connect(d->m_modelManager,SIGNAL(stateChanged()), this, SLOT(dataStateChanged()));
connect(d->m_modelManager,SIGNAL(countChanged()), this, SLOT(dataStateChanged()));
connect(d->m_modelManager,SIGNAL(progressChanged()), this, SLOT(dataStateChanged()));
connect(this, SIGNAL(newTimeEstimation(qint64)), d->m_modelManager, SLOT(newTimeEstimation(qint64)));
d->m_profilerState = stateManager;
connect(d->m_profilerState,SIGNAL(stateChanged()), this, SLOT(profilerStateChanged()));
connect(d->m_profilerState, SIGNAL(serverRecordingChanged()),
@@ -194,9 +198,9 @@ void QmlProfilerStateWidget::updateDisplay()
if (d->isRecording) {
d->isRecording = false;
d->estimatedProfilingTime = d->profilingTimer.elapsed();
emit newTimeEstimation(d->estimatedProfilingTime);
}
d->progressBar->setMaximum(d->estimatedProfilingTime);
d->progressBar->setValue(d->m_modelManager->traceTime()->endTime() * 1e-6);
d->progressBar->setValue(d->m_modelManager->progress() * 1000);
d->progressBar->setVisible(true);
resize(300,70);
reposition();
@@ -230,9 +234,9 @@ void QmlProfilerStateWidget::updateDisplay()
if (d->isRecording) {
d->isRecording = false;
d->estimatedProfilingTime = d->profilingTimer.elapsed();
emit newTimeEstimation(d->estimatedProfilingTime);
}
d->progressBar->setMaximum(d->estimatedProfilingTime);
d->progressBar->setValue(d->m_modelManager->traceTime()->endTime() * 1e-6);
d->progressBar->setValue(d->m_modelManager->progress() * 1000);
d->progressBar->setVisible(true);
resize(300,70);
reposition();
@@ -250,15 +254,17 @@ void QmlProfilerStateWidget::updateDisplay()
// }
// There is a trace on view, hide this dialog
d->progressBar->setVisible(false);
setVisible(false);
}
void QmlProfilerStateWidget::dataStateChanged()
{
d->loadingDone = d->m_modelManager->state() == QmlProfilerDataState::Done ||
// consider possible rounding errors
d->loadingDone = d->m_modelManager->progress() >= 0.99 ||
d->m_modelManager->state() == QmlProfilerDataState::Empty;
d->traceAvailable = d->m_modelManager->traceTime()->duration() > 0;
d->emptyList = d->m_modelManager->isEmpty();
d->emptyList = d->m_modelManager->isEmpty() || d->m_modelManager->progress() == 0;
updateDisplay();
}
@@ -273,8 +279,11 @@ void QmlProfilerStateWidget::profilerStateChanged()
d->isRecording = d->m_profilerState->serverRecording();
if (d->isRecording)
d->profilingTimer.start();
else
d->estimatedProfilingTime = d->profilingTimer.elapsed();
else {
// estimated time in ns
d->estimatedProfilingTime = d->profilingTimer.elapsed() * 1e6;
emit newTimeEstimation(d->estimatedProfilingTime);
}
updateDisplay();
}

View File

@@ -52,6 +52,9 @@ private slots:
void profilerStateChanged();
void reposition();
signals:
void newTimeEstimation(qint64);
protected:
void paintEvent(QPaintEvent *event);

View File

@@ -126,11 +126,17 @@ void BasicTimelineModel::clear()
d->startTimeData.clear();
d->endTimeData.clear();
d->categorySpan.clear();
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
}
void BasicTimelineModel::dataChanged()
{
loadData();
if (m_modelManager->state() == QmlProfilerDataState::Done)
loadData();
if (m_modelManager->state() == QmlProfilerDataState::Empty)
clear();
emit stateChanged();
emit dataAvailable();
@@ -209,23 +215,37 @@ void BasicTimelineModel::loadData()
-1 // bindingLoopHead
};
d->startTimeData.append(eventStartInstance);
m_modelManager->modelProxyCountUpdated(m_modelId, d->startTimeData.count(), eventList.count() * 7);
}
qSort(d->startTimeData.begin(), d->startTimeData.end(), compareStartTimes);
m_modelManager->modelProxyCountUpdated(m_modelId, 2, 7);
// compute nestingLevel - nonexpanded
d->computeNestingContracted();
m_modelManager->modelProxyCountUpdated(m_modelId, 3, 7);
// compute nestingLevel - expanded
d->computeExpandedLevels();
m_modelManager->modelProxyCountUpdated(m_modelId, 4, 7);
// populate endtimelist
d->buildEndTimeList();
m_modelManager->modelProxyCountUpdated(m_modelId, 5, 7);
d->findBindingLoops();
m_modelManager->modelProxyCountUpdated(m_modelId, 6, 7);
d->computeRowStarts();
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
emit countChanged();
}

View File

@@ -69,6 +69,7 @@ void TimelineModelAggregator::setModelManager(QmlProfilerModelManager *modelMana
d->modelManager = modelManager;
connect(modelManager,SIGNAL(stateChanged()),this,SLOT(dataChanged()));
connect(modelManager,SIGNAL(countChanged()),this,SIGNAL(countChanged()));
connect(modelManager,SIGNAL(dataAvailable()),this,SIGNAL(dataAvailable()));
// external models pushed on top
foreach (AbstractTimelineModel *timelineModel, QmlProfilerPlugin::instance->getModels()) {
@@ -92,7 +93,6 @@ void TimelineModelAggregator::addModel(AbstractTimelineModel *m)
{
d->modelList << m;
connect(m,SIGNAL(countChanged()),this,SIGNAL(countChanged()));
connect(m,SIGNAL(dataAvailable()),this,SIGNAL(dataAvailable()));
connect(m,SIGNAL(emptyChanged()),this,SIGNAL(emptyChanged()));
connect(m,SIGNAL(expandedChanged()),this,SIGNAL(expandedChanged()));
connect(m,SIGNAL(stateChanged()),this,SIGNAL(stateChanged()));

View File

@@ -101,7 +101,7 @@ qint64 PixmapCacheModel::lastTimeMark() const
return d->eventList.last().startTime;
}
bool PixmapCacheModel::expanded(int category) const
bool PixmapCacheModel::expanded(int ) const
{
return d->isExpanded;
}
@@ -450,6 +450,8 @@ void PixmapCacheModel::loadData()
else
d->eventList[loadIndex].cacheSize = -1; // ... or failure
}
m_modelManager->modelProxyCountUpdated(m_modelId, d->eventList.count(), 2*simpleModel->getEvents().count());
}
if (lastCacheSizeEvent != -1) {
@@ -463,6 +465,8 @@ void PixmapCacheModel::loadData()
d->computeCacheSizes();
d->flattenLoads();
d->computeRowCounts();
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
}
void PixmapCacheModel::clear()
@@ -473,6 +477,8 @@ void PixmapCacheModel::clear()
d->collapsedRowCount = 1;
d->expandedRowCount = 1;
d->isExpanded = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
}
void PixmapCacheModel::dataChanged()

View File

@@ -109,7 +109,7 @@ qint64 SceneGraphTimelineModel::lastTimeMark() const
return d->eventList.last().startTime;
}
bool SceneGraphTimelineModel::expanded(int category) const
bool SceneGraphTimelineModel::expanded(int ) const
{
return d->isExpanded;
}
@@ -459,15 +459,19 @@ void SceneGraphTimelineModel::loadData()
default: break;
}
}
m_modelManager->modelProxyCountUpdated(m_modelId, d->eventList.count(), simpleModel->getEvents().count());
}
qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
}
void SceneGraphTimelineModel::clear()
{
d->eventList.clear();
d->isExpanded = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
}
void SceneGraphTimelineModel::dataChanged()