diff options
author | Christiaan Janssen <christiaan.janssen@digia.com> | 2013-08-06 16:17:00 +0200 |
---|---|---|
committer | Christiaan Janssen <christiaan.janssen@digia.com> | 2013-08-06 16:47:12 +0200 |
commit | cf287b5e2872fcdef3fe14bca8113907aea89e02 (patch) | |
tree | 3f70ceed886106d996ded815078f5e35dffa8f7a | |
parent | bbaa5efb6c08bd60999a1eeb7bcde11826829c79 (diff) | |
parent | bfb419717c3488065b8c032f72fea9c0694ae12d (diff) | |
download | qt-creator-cf287b5e2872fcdef3fe14bca8113907aea89e02.tar.gz |
Merge branch '2.8'
Change-Id: I72da0b7942c0c98639e8d2f5397f2d95caf7f612
35 files changed, 501 insertions, 112 deletions
diff --git a/plugins/qmlprofiler/abstractqmlprofilerrunner.h b/plugins/qmlprofiler/abstractqmlprofilerrunner.h index 233941ed96..6c2f1e7931 100644 --- a/plugins/qmlprofiler/abstractqmlprofilerrunner.h +++ b/plugins/qmlprofiler/abstractqmlprofilerrunner.h @@ -43,11 +43,12 @@ class AbstractQmlProfilerRunner : public QObject public: explicit AbstractQmlProfilerRunner(QObject *parent = 0) : QObject(parent) { } + virtual quint16 debugPort() const = 0; + +public slots: virtual void start() = 0; virtual void stop() = 0; - virtual quint16 debugPort() const = 0; - signals: void started(); void stopped(); diff --git a/plugins/qmlprofiler/abstracttimelinemodel.cpp b/plugins/qmlprofiler/abstracttimelinemodel.cpp index d462e8a915..5c33d1afca 100644 --- a/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -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 diff --git a/plugins/qmlprofiler/abstracttimelinemodel.h b/plugins/qmlprofiler/abstracttimelinemodel.h index 2eecdeef54..5f4b950365 100644 --- a/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/plugins/qmlprofiler/abstracttimelinemodel.h @@ -64,6 +64,7 @@ public: Q_INVOKABLE qint64 traceDuration() const; Q_INVOKABLE int getState() const; + Q_INVOKABLE virtual bool expanded(int category) const = 0; Q_INVOKABLE virtual void setExpanded(int category, bool expanded) = 0; Q_INVOKABLE virtual int categoryDepth(int categoryIndex) const = 0; Q_INVOKABLE virtual int categoryCount() const = 0; @@ -106,6 +107,7 @@ signals: protected: QmlProfiler::Internal::QmlProfilerModelManager *m_modelManager; + int m_modelId; }; diff --git a/plugins/qmlprofiler/localqmlprofilerrunner.cpp b/plugins/qmlprofiler/localqmlprofilerrunner.cpp index 529514c390..6eb06223be 100644 --- a/plugins/qmlprofiler/localqmlprofilerrunner.cpp +++ b/plugins/qmlprofiler/localqmlprofilerrunner.cpp @@ -29,13 +29,62 @@ #include "localqmlprofilerrunner.h" #include "qmlprofilerplugin.h" +#include "qmlprofilerengine.h" + +#include <analyzerbase/analyzerstartparameters.h> +#include <projectexplorer/runconfiguration.h> +#include <qmlprojectmanager/qmlprojectrunconfiguration.h> +#include <projectexplorer/localapplicationrunconfiguration.h> +#include <projectexplorer/environmentaspect.h> using namespace QmlProfiler; using namespace QmlProfiler::Internal; +using namespace ProjectExplorer; + +LocalQmlProfilerRunner *LocalQmlProfilerRunner::createLocalRunner( + RunConfiguration *runConfiguration, + const Analyzer::AnalyzerStartParameters &sp, + QString *errorMessage, + QmlProfilerEngine *engine) +{ + QmlProjectManager::QmlProjectRunConfiguration *rc1 = + qobject_cast<QmlProjectManager::QmlProjectRunConfiguration *>(runConfiguration); + LocalApplicationRunConfiguration *rc2 = + qobject_cast<LocalApplicationRunConfiguration *>(runConfiguration); + QTC_ASSERT(rc1 || rc2, return 0); + ProjectExplorer::EnvironmentAspect *environment + = runConfiguration->extraAspect<ProjectExplorer::EnvironmentAspect>(); + QTC_ASSERT(environment, return 0); + Configuration conf; + if (rc1) { + // This is a "plain" .qmlproject. + conf.executable = rc1->observerPath(); + conf.executableArguments = rc1->viewerArguments(); + conf.workingDirectory = rc1->workingDirectory(); + conf.environment = environment->environment(); + } else { + // FIXME: Check. + conf.executable = rc2->executable(); + conf.executableArguments = rc2->commandLineArguments(); + conf.workingDirectory = rc2->workingDirectory(); + conf.environment = environment->environment(); + } + + conf.port = sp.analyzerPort; -LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent) : - AbstractQmlProfilerRunner(parent), - m_configuration(configuration) + if (conf.executable.isEmpty()) { + if (errorMessage) + *errorMessage = tr("No executable file to launch."); + return 0; + } + return new LocalQmlProfilerRunner(conf, engine); +} + +LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, + QmlProfilerEngine *engine) : + AbstractQmlProfilerRunner(engine), + m_configuration(configuration), + m_engine(engine) { connect(&m_launcher, SIGNAL(appendMessage(QString,Utils::OutputFormat)), this, SIGNAL(appendMessage(QString,Utils::OutputFormat))); @@ -48,6 +97,9 @@ LocalQmlProfilerRunner::~LocalQmlProfilerRunner() void LocalQmlProfilerRunner::start() { + if (m_engine->mode() != Analyzer::StartQml) + return; + QString arguments = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_configuration.port); if (!m_configuration.executableArguments.isEmpty()) @@ -78,6 +130,9 @@ void LocalQmlProfilerRunner::spontaneousStop(int exitCode) void LocalQmlProfilerRunner::stop() { + if (m_engine->mode() != Analyzer::StartQml) + return; + if (QmlProfilerPlugin::debugOutput) qWarning("QmlProfiler: Stopping application ..."); diff --git a/plugins/qmlprofiler/localqmlprofilerrunner.h b/plugins/qmlprofiler/localqmlprofilerrunner.h index 26a9b45161..37591917da 100644 --- a/plugins/qmlprofiler/localqmlprofilerrunner.h +++ b/plugins/qmlprofiler/localqmlprofilerrunner.h @@ -35,9 +35,13 @@ #include <utils/environment.h> #include <projectexplorer/applicationlauncher.h> +namespace ProjectExplorer { class RunConfiguration; } +namespace Analyzer { class AnalyzerStartParameters; } + namespace QmlProfiler { namespace Internal { +class QmlProfilerEngine; class LocalQmlProfilerRunner : public AbstractQmlProfilerRunner { Q_OBJECT @@ -51,7 +55,11 @@ public: Utils::Environment environment; }; - explicit LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent = 0); + static LocalQmlProfilerRunner *createLocalRunner(ProjectExplorer::RunConfiguration *runConfiguration, + const Analyzer::AnalyzerStartParameters &sp, + QString *errorMessage, + QmlProfilerEngine *engine); + ~LocalQmlProfilerRunner(); // AbstractQmlProfilerRunner @@ -59,14 +67,16 @@ public: virtual void stop(); virtual quint16 debugPort() const; - bool hasExecutable() const { return !m_configuration.executable.isEmpty(); } - private slots: void spontaneousStop(int exitCode); private: + LocalQmlProfilerRunner(const Configuration &configuration, QmlProfilerEngine *engine); + +private: Configuration m_configuration; ProjectExplorer::ApplicationLauncher m_launcher; + QmlProfilerEngine *m_engine; }; } // namespace Internal diff --git a/plugins/qmlprofiler/qml/Label.qml b/plugins/qmlprofiler/qml/Label.qml index 5c0ac3ca60..afc96b92f1 100644 --- a/plugins/qmlprofiler/qml/Label.qml +++ b/plugins/qmlprofiler/qml/Label.qml @@ -57,6 +57,8 @@ Item { } function updateHeight() { + if (expanded != qmlProfilerModelProxy.expanded(modelIndex, categoryIndex)) + expanded = qmlProfilerModelProxy.expanded(modelIndex, categoryIndex); height = root.singleRowHeight * qmlProfilerModelProxy.categoryDepth(modelIndex, categoryIndex); } diff --git a/plugins/qmlprofiler/qmlprofiler.pro b/plugins/qmlprofiler/qmlprofiler.pro index 322326b995..c9f7ba7ed7 100644 --- a/plugins/qmlprofiler/qmlprofiler.pro +++ b/plugins/qmlprofiler/qmlprofiler.pro @@ -21,6 +21,7 @@ SOURCES += \ qmlprofilerclientmanager.cpp \ qmlprofilerviewmanager.cpp \ qmlprofilerstatewidget.cpp \ + qmlprofilerruncontrolfactory.cpp \ qmlprofilermodelmanager.cpp \ qmlprofilersimplemodel.cpp \ qmlprofilerprocessedmodel.cpp \ @@ -51,6 +52,7 @@ HEADERS += \ qmlprofilerclientmanager.h \ qmlprofilerviewmanager.h \ qmlprofilerstatewidget.h \ + qmlprofilerruncontrolfactory.h \ qmlprofilermodelmanager.h \ qmlprofilersimplemodel.h \ qmlprofilerprocessedmodel.h \ diff --git a/plugins/qmlprofiler/qmlprofiler.qbs b/plugins/qmlprofiler/qmlprofiler.qbs index 8fca811be9..72288c3f26 100644 --- a/plugins/qmlprofiler/qmlprofiler.qbs +++ b/plugins/qmlprofiler/qmlprofiler.qbs @@ -46,6 +46,8 @@ QtcPlugin { "qmlprofilermodelmanager.h", "qmlprofilerplugin.cpp", "qmlprofilerplugin.h", + "qmlprofilerruncontrolfactory.cpp", + "qmlprofilerruncontrolfactory.h", "qmlprofilerprocessedmodel.cpp", "qmlprofilerprocessedmodel.h", "qmlprofilersimplemodel.cpp", diff --git a/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/plugins/qmlprofiler/qmlprofilerclientmanager.cpp index b29344699e..e733daf86a 100644 --- a/plugins/qmlprofiler/qmlprofilerclientmanager.cpp +++ b/plugins/qmlprofiler/qmlprofilerclientmanager.cpp @@ -40,6 +40,8 @@ #include <QTimer> #include <QMessageBox> +#include "qmlprofilermodelmanager.h" + using namespace QmlDebug; using namespace Core; @@ -70,6 +72,8 @@ public: bool v8DataReady; bool qmlDataReady; + + QmlProfilerModelManager *modelManager; }; QmlProfilerClientManager::QmlProfilerClientManager(QObject *parent) : @@ -84,6 +88,8 @@ QmlProfilerClientManager::QmlProfilerClientManager(QObject *parent) : d->v8DataReady = false; d->qmlDataReady = false; + d->modelManager = 0; + d->connectionTimer.setInterval(200); connect(&d->connectionTimer, SIGNAL(timeout()), SLOT(tryToConnect())); } @@ -97,6 +103,18 @@ QmlProfilerClientManager::~QmlProfilerClientManager() delete d; } + +void QmlProfilerClientManager::setModelManager(QmlProfilerModelManager *m) +{ + if (d->modelManager) { + disconnect(this,SIGNAL(dataReadyForProcessing()), d->modelManager, SLOT(complete())); + } + d->modelManager = m; + if (d->modelManager) { + connect(this,SIGNAL(dataReadyForProcessing()), d->modelManager, SLOT(complete())); + } +} + //////////////////////////////////////////////////////////////// // Interface void QmlProfilerClientManager::setTcpConnection(QString host, quint64 port) @@ -162,22 +180,22 @@ void QmlProfilerClientManager::connectClientSignals() this, SLOT(qmlComplete())); connect(d->qmlclientplugin.data(), SIGNAL(range(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)), - this, - SIGNAL(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); + d->modelManager, + SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); connect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)), - this, SIGNAL(traceFinished(qint64))); + d->modelManager->traceTime(), SLOT(setEndTime(qint64))); connect(d->qmlclientplugin.data(), SIGNAL(traceStarted(qint64)), - this, SIGNAL(traceStarted(qint64))); + d->modelManager->traceTime(), SLOT(setStartTime(qint64))); connect(d->qmlclientplugin.data(), SIGNAL(frame(qint64,int,int)), - this, SIGNAL(addFrameEvent(qint64,int,int))); + d->modelManager, SLOT(addFrameEvent(qint64,int,int))); connect(d->qmlclientplugin.data(), SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)), - this, - SIGNAL(addPixmapCacheEvent(qint64,int,QString,int,int,int))); + d->modelManager, + SLOT(addPixmapCacheEvent(qint64,int,QString,int,int,int))); connect(d->qmlclientplugin.data(), SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64)), - this, - SIGNAL(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64))); + d->modelManager, + SLOT(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64))); connect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()), d->qmlclientplugin.data(), SLOT(sendRecordingStatus())); // fixme: this should be unified for both clients @@ -188,8 +206,8 @@ void QmlProfilerClientManager::connectClientSignals() connect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); connect(d->v8clientplugin.data(), SIGNAL(v8range(int,QString,QString,int,double,double)), - this, - SIGNAL(addV8Event(int,QString,QString,int,double,double))); + d->modelManager, + SLOT(addV8Event(int,QString,QString,int,double,double))); connect(d->v8clientplugin.data(), SIGNAL(enabledChanged()), d->v8clientplugin.data(), SLOT(sendRecordingStatus())); } @@ -202,22 +220,22 @@ void QmlProfilerClientManager::disconnectClientSignals() this, SLOT(qmlComplete())); disconnect(d->qmlclientplugin.data(), SIGNAL(range(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)), - this, - SIGNAL(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); + d->modelManager, + SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); disconnect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)), - this, SIGNAL(traceFinished(qint64))); + d->modelManager->traceTime(), SLOT(setEndTime(qint64))); disconnect(d->qmlclientplugin.data(), SIGNAL(traceStarted(qint64)), - this, SIGNAL(traceStarted(qint64))); + d->modelManager->traceTime(), SLOT(setStartTime(qint64))); disconnect(d->qmlclientplugin.data(), SIGNAL(frame(qint64,int,int)), - this, SIGNAL(addFrameEvent(qint64,int,int))); + d->modelManager, SLOT(addFrameEvent(qint64,int,int))); disconnect(d->qmlclientplugin.data(), SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)), - this, - SIGNAL(addPixmapCacheEvent(qint64,int,QString,int,int,int))); + d->modelManager, + SLOT(addPixmapCacheEvent(qint64,int,QString,int,int,int))); disconnect(d->qmlclientplugin.data(), SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64)), - this, - SIGNAL(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64))); + d->modelManager, + SLOT(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64))); disconnect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()), d->qmlclientplugin.data(), SLOT(sendRecordingStatus())); // fixme: this should be unified for both clients @@ -228,8 +246,8 @@ void QmlProfilerClientManager::disconnectClientSignals() disconnect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); disconnect(d->v8clientplugin.data(), SIGNAL(v8range(int,QString,QString,int,double,double)), - this, - SIGNAL(addV8Event(int,QString,QString,int,double,double))); + d->modelManager, + SLOT(addV8Event(int,QString,QString,int,double,double))); disconnect(d->v8clientplugin.data(), SIGNAL(enabledChanged()), d->v8clientplugin.data(), SLOT(sendRecordingStatus())); } diff --git a/plugins/qmlprofiler/qmlprofilerclientmanager.h b/plugins/qmlprofiler/qmlprofilerclientmanager.h index 9401b554f0..f6e0fa7828 100644 --- a/plugins/qmlprofiler/qmlprofilerclientmanager.h +++ b/plugins/qmlprofiler/qmlprofilerclientmanager.h @@ -39,6 +39,8 @@ namespace QmlProfiler { namespace Internal { +class QmlProfilerModelManager; + class QmlProfilerClientManager : public QObject { Q_OBJECT @@ -55,19 +57,11 @@ public: void discardPendingData(); bool isConnected() const; + void setModelManager(QmlProfilerModelManager *m); signals: void connectionFailed(); void connectionClosed(); - - // data - void addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation); - void addV8Event(int,QString,QString,int,double,double); - void addFrameEvent(qint64,int,int); - void traceStarted(qint64); - void traceFinished(qint64); void dataReadyForProcessing(); - void addSceneGraphEvent(int, int, qint64, qint64, qint64, qint64, qint64, qint64); - void addPixmapCacheEvent(qint64,int,QString,int,int,int); public slots: void connectClient(quint16 port); diff --git a/plugins/qmlprofiler/qmlprofilerengine.cpp b/plugins/qmlprofiler/qmlprofilerengine.cpp index 18308d3178..1127eb0d14 100644 --- a/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -68,14 +68,11 @@ public: ~QmlProfilerEnginePrivate() { delete m_runner; } bool attach(const QString &address, uint port); - AbstractQmlProfilerRunner *createRunner(ProjectExplorer::RunConfiguration *runConfiguration, - QObject *parent); QmlProfilerEngine *q; QmlProfilerStateManager *m_profilerState; - AbstractQmlProfilerRunner *m_runner; QTimer m_noDebugOutputTimer; QmlDebug::QmlOutputParser m_outputParser; }; @@ -160,11 +157,6 @@ bool QmlProfilerEngine::start() { QTC_ASSERT(d->m_profilerState, return false); - if (d->m_runner) { - delete d->m_runner; - d->m_runner = 0; - } - d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStarting); if (QmlProjectManager::QmlProjectRunConfiguration *rc = @@ -201,7 +193,7 @@ bool QmlProfilerEngine::start() } d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); - emit starting(this); + engineStarted(); return true; } @@ -242,7 +234,7 @@ void QmlProfilerEngine::notifyRemoteFinished(bool success) d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppKilled); AnalyzerManager::stopTool(); - emit finished(); + engineFinished(); break; } case QmlProfilerStateManager::AppStopped : @@ -262,10 +254,6 @@ void QmlProfilerEngine::cancelProcess() { QTC_ASSERT(d->m_profilerState, return); - // no process to be canceled? (there might be multiple engines, but only one runs a process) - if (!d->m_runner) - return; - switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppReadyToStop : { d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStopped); @@ -282,10 +270,7 @@ void QmlProfilerEngine::cancelProcess() return; } } - - if (d->m_runner) - d->m_runner->stop(); - emit finished(); + engineFinished(); } void QmlProfilerEngine::logApplicationMessage(const QString &msg, Utils::OutputFormat format) @@ -348,10 +333,20 @@ void QmlProfilerEngine::processIsRunning(quint16 port) { d->m_noDebugOutputTimer.stop(); - if (port > 0) + if (port > 0 && mode() != StartQmlRemote) emit processRunning(port); - else if (d->m_runner) - emit processRunning(d->m_runner->debugPort()); +} + +void QmlProfilerEngine::engineStarted() +{ + d->m_running = true; + emit starting(this); +} + +void QmlProfilerEngine::engineFinished() +{ + d->m_running = false; + emit finished(); } //////////////////////////////////////////////////////////////// @@ -373,17 +368,12 @@ void QmlProfilerEngine::profilerStateChanged() { switch (d->m_profilerState->currentState()) { case QmlProfilerStateManager::AppReadyToStop : { - cancelProcess(); + if (d->m_running) + cancelProcess(); break; } case QmlProfilerStateManager::Idle : { - // When all the profiling is done, delete the profiler runner - // (a new one will be created at start) d->m_noDebugOutputTimer.stop(); - if (d->m_runner) { - delete d->m_runner; - d->m_runner = 0; - } break; } default: diff --git a/plugins/qmlprofiler/qmlprofilerengine.h b/plugins/qmlprofiler/qmlprofilerengine.h index bf40b37c2f..d4d28c93bd 100644 --- a/plugins/qmlprofiler/qmlprofilerengine.h +++ b/plugins/qmlprofiler/qmlprofilerengine.h @@ -68,6 +68,8 @@ private slots: void wrongSetupMessageBox(const QString &errorMessage); void wrongSetupMessageBoxFinished(int); void processIsRunning(quint16 port = 0); + void engineStarted(); + void engineFinished(); private slots: void profilerStateChanged(); diff --git a/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp b/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp index d7c325c25f..d1be7cfdb3 100644 --- a/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp +++ b/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp @@ -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::ProcessingData) + 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(); } diff --git a/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index a06f59b1ab..078bdb5174 100644 --- a/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -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(); diff --git a/plugins/qmlprofiler/qmlprofilermodelmanager.h b/plugins/qmlprofiler/qmlprofilermodelmanager.h index df033ff122..fb44cf1937 100644 --- a/plugins/qmlprofiler/qmlprofilermodelmanager.h +++ b/plugins/qmlprofiler/qmlprofilermodelmanager.h @@ -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); diff --git a/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp index 7457e33dc8..9db131f771 100644 --- a/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp +++ b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp @@ -61,6 +61,7 @@ public: QVector <PaintEventsModelProxy::QmlPaintEventData> eventList; int minAnimationCount; int maxAnimationCount; + bool expanded; PaintEventsModelProxy *q; }; @@ -113,11 +114,13 @@ void PaintEventsModelProxy::clear() d->eventList.clear(); d->minAnimationCount = 1; d->maxAnimationCount = 1; + d->expanded = false; + m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1); } void PaintEventsModelProxy::dataChanged() { - if (m_modelManager->state() == QmlProfilerDataState::Done) + if (m_modelManager->state() == QmlProfilerDataState::ProcessingData) loadData(); if (m_modelManager->state() == QmlProfilerDataState::Empty) @@ -126,6 +129,7 @@ void PaintEventsModelProxy::dataChanged() emit stateChanged(); emit dataAvailable(); emit emptyChanged(); + emit expandedChanged(); } bool compareStartTimes(const PaintEventsModelProxy::QmlPaintEventData &t1, const PaintEventsModelProxy::QmlPaintEventData &t2) @@ -173,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(); } @@ -199,10 +207,15 @@ qint64 PaintEventsModelProxy::lastTimeMark() const return d->eventList.last().startTime + d->eventList.last().duration; } +bool PaintEventsModelProxy::expanded(int ) const +{ + return d->expanded; +} + void PaintEventsModelProxy::setExpanded(int category, bool expanded) { Q_UNUSED(category); - Q_UNUSED(expanded); + d->expanded = expanded; emit expandedChanged(); } @@ -324,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); } diff --git a/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h index 677c5e5c17..eaf8e96664 100644 --- a/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h +++ b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h @@ -80,6 +80,7 @@ public: Q_INVOKABLE qint64 lastTimeMark() const; + Q_INVOKABLE bool expanded(int category) const; Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryCount() const; diff --git a/plugins/qmlprofiler/qmlprofilerplugin.cpp b/plugins/qmlprofiler/qmlprofilerplugin.cpp index 24a99772e3..9cd725b39c 100644 --- a/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -28,6 +28,7 @@ ****************************************************************************/ #include "qmlprofilerplugin.h" +#include "qmlprofilerruncontrolfactory.h" #include "qmlprofilertool.h" #include "abstracttimelinemodel.h" @@ -55,6 +56,8 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS modes.append(StartMode(StartLocal)); modes.append(StartMode(StartRemote)); AnalyzerManager::addTool(new QmlProfilerTool(this), modes); + + addAutoReleasedObject(new QmlProfilerRunControlFactory()); QmlProfilerPlugin::instance = this; return true; diff --git a/plugins/qmlprofiler/qmlprofilerprocessedmodel.cpp b/plugins/qmlprofiler/qmlprofilerprocessedmodel.cpp index b917020414..2e4331f735 100644 --- a/plugins/qmlprofiler/qmlprofilerprocessedmodel.cpp +++ b/plugins/qmlprofiler/qmlprofilerprocessedmodel.cpp @@ -28,7 +28,6 @@ ****************************************************************************/ #include "qmlprofilerprocessedmodel.h" - #include <qmldebug/qmlprofilereventtypes.h> #include <utils/qtcassert.h> #include <QUrl> @@ -44,7 +43,8 @@ QString getInitialDetails(const QmlProfilerSimpleModel::QmlEventData &event); QmlDebug::QmlEventLocation getLocation(const QmlProfilerSimpleModel::QmlEventData &event) { QmlDebug::QmlEventLocation eventLocation = event.location; - if (event.eventType == QmlDebug::Compiling && eventLocation.filename.isEmpty()) { + if ((event.eventType == QmlDebug::Creating || event.eventType == QmlDebug::Compiling) + && eventLocation.filename.isEmpty()) { eventLocation.filename = getInitialDetails(event); eventLocation.line = 1; eventLocation.column = 1; @@ -155,6 +155,7 @@ void QmlProfilerProcessedModel::complete() m_detailsRewriter->reloadDocuments(); + QmlProfilerSimpleModel::complete(); emit changed(); m_emitChanged = false; } diff --git a/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp b/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp new file mode 100644 index 0000000000..6e3ab3ff6a --- /dev/null +++ b/plugins/qmlprofiler/qmlprofilerruncontrolfactory.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Kläralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "qmlprofilerruncontrolfactory.h" +#include "localqmlprofilerrunner.h" +#include "qmlprofilerengine.h" + +#include <analyzerbase/ianalyzertool.h> +#include <analyzerbase/analyzermanager.h> +#include <analyzerbase/analyzerstartparameters.h> +#include <analyzerbase/analyzerruncontrol.h> +#include <analyzerbase/analyzersettings.h> + +#include <projectexplorer/kitinformation.h> +#include <projectexplorer/target.h> + +#include <utils/qtcassert.h> + +using namespace Analyzer; +using namespace ProjectExplorer; + +namespace QmlProfiler { +namespace Internal { + +QmlProfilerRunControlFactory::QmlProfilerRunControlFactory(QObject *parent) : + IRunControlFactory(parent) +{ +} + +bool QmlProfilerRunControlFactory::canRun(RunConfiguration *runConfiguration, RunMode mode) const +{ + if (mode != QmlProfilerRunMode) + return false; + IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); + if (tool) + return tool->canRun(runConfiguration, mode); + return false; +} + +RunControl *QmlProfilerRunControlFactory::create(RunConfiguration *runConfiguration, RunMode mode, QString *errorMessage) +{ + IAnalyzerTool *tool = AnalyzerManager::toolFromRunMode(mode); + if (!tool) { + if (errorMessage) + *errorMessage = tr("No analyzer tool selected"); // never happens + return 0; + } + + QTC_ASSERT(canRun(runConfiguration, mode), return 0); + + AnalyzerStartParameters sp = tool->createStartParameters(runConfiguration, mode); + sp.toolId = tool->id(); + + // only desktop device is supported + const ProjectExplorer::IDevice::ConstPtr device = + ProjectExplorer::DeviceKitInformation::device(runConfiguration->target()->kit()); + QTC_ASSERT(device->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE, return 0); + + AnalyzerRunControl *rc = new AnalyzerRunControl(tool, sp, runConfiguration); + QmlProfilerEngine *engine = qobject_cast<QmlProfilerEngine *>(rc->engine()); + if (!engine) { + delete rc; + return 0; + } + LocalQmlProfilerRunner *runner = LocalQmlProfilerRunner::createLocalRunner(runConfiguration, sp, errorMessage, engine); + if (!runner) + return 0; + connect(runner, SIGNAL(stopped()), engine, SLOT(notifyRemoteFinished())); + connect(runner, SIGNAL(appendMessage(QString,Utils::OutputFormat)), + engine, SLOT(logApplicationMessage(QString,Utils::OutputFormat))); + connect(engine, SIGNAL(starting(const Analyzer::IAnalyzerEngine*)), runner, + SLOT(start())); + connect(rc, SIGNAL(finished()), runner, SLOT(stop())); + return rc; +} + +} // namespace Internal +} // namespace QmlProfiler diff --git a/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h b/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h new file mode 100644 index 0000000000..3973411d93 --- /dev/null +++ b/plugins/qmlprofiler/qmlprofilerruncontrolfactory.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Kläralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QMLPROFILERRUNCONTROLFACTORY_H +#define QMLPROFILERRUNCONTROLFACTORY_H + +#include <projectexplorer/runconfiguration.h> + +namespace QmlProfiler { +namespace Internal { + +class QmlProfilerRunControlFactory : public ProjectExplorer::IRunControlFactory +{ + Q_OBJECT +public: + typedef ProjectExplorer::RunConfiguration RunConfiguration; + + explicit QmlProfilerRunControlFactory(QObject *parent = 0); + + // IRunControlFactory implementation + bool canRun(RunConfiguration *runConfiguration, ProjectExplorer::RunMode mode) const; + + ProjectExplorer::RunControl *create(RunConfiguration *runConfiguration, + ProjectExplorer::RunMode mode, + QString *errorMessage); +}; + +} // namespace Internal +} // namespace QmlProfiler + +#endif // QMLPROFILERRUNCONTROLFACTORY_H diff --git a/plugins/qmlprofiler/qmlprofilersimplemodel.cpp b/plugins/qmlprofiler/qmlprofilersimplemodel.cpp index 1777094c09..c2fc59892a 100644 --- a/plugins/qmlprofiler/qmlprofilersimplemodel.cpp +++ b/plugins/qmlprofiler/qmlprofilersimplemodel.cpp @@ -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(); } diff --git a/plugins/qmlprofiler/qmlprofilersimplemodel.h b/plugins/qmlprofiler/qmlprofilersimplemodel.h index e556a7a5d3..26f27db5f0 100644 --- a/plugins/qmlprofiler/qmlprofilersimplemodel.h +++ b/plugins/qmlprofiler/qmlprofilersimplemodel.h @@ -82,6 +82,8 @@ signals: protected: QVector<QmlEventData> eventList; + QmlProfilerModelManager *m_modelManager; + int m_modelId; }; } diff --git a/plugins/qmlprofiler/qmlprofilerstatewidget.cpp b/plugins/qmlprofiler/qmlprofilerstatewidget.cpp index 7887dec61e..193f4f7569 100644 --- a/plugins/qmlprofiler/qmlprofilerstatewidget.cpp +++ b/plugins/qmlprofiler/qmlprofilerstatewidget.cpp @@ -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(); } diff --git a/plugins/qmlprofiler/qmlprofilerstatewidget.h b/plugins/qmlprofiler/qmlprofilerstatewidget.h index 85ff96798a..bf32aa2b47 100644 --- a/plugins/qmlprofiler/qmlprofilerstatewidget.h +++ b/plugins/qmlprofiler/qmlprofilerstatewidget.h @@ -52,6 +52,9 @@ private slots: void profilerStateChanged(); void reposition(); +signals: + void newTimeEstimation(qint64); + protected: void paintEvent(QPaintEvent *event); diff --git a/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp b/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp index 3984b25c44..e6a280aadd 100644 --- a/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp +++ b/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp @@ -126,15 +126,22 @@ 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::ProcessingData) + loadData(); + + if (m_modelManager->state() == QmlProfilerDataState::Empty) + clear(); emit stateChanged(); emit dataAvailable(); emit emptyChanged(); + emit expandedChanged(); } void BasicTimelineModel::BasicTimelineModelPrivate::prepare() @@ -208,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(); } @@ -393,6 +414,13 @@ qint64 BasicTimelineModel::lastTimeMark() const return d->startTimeData.last().startTime + d->startTimeData.last().duration; } +bool BasicTimelineModel::expanded(int category) const +{ + if (d->categorySpan.count() <= category) + return false; + return d->categorySpan[category].expanded; +} + void BasicTimelineModel::setExpanded(int category, bool expanded) { if (d->categorySpan.count() <= category) diff --git a/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h b/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h index a8e6f08aa2..0a57541f8f 100644 --- a/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h +++ b/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h @@ -101,6 +101,7 @@ public: Q_INVOKABLE qint64 lastTimeMark() const; + Q_INVOKABLE bool expanded(int category) const; Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryCount() const; diff --git a/plugins/qmlprofiler/qmlprofilertool.cpp b/plugins/qmlprofiler/qmlprofilertool.cpp index 7337708daa..1ad954d51f 100644 --- a/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/plugins/qmlprofiler/qmlprofilertool.cpp @@ -149,27 +149,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this); connect(d->m_profilerModelManager, SIGNAL(stateChanged()), this, SLOT(profilerDataModelStateChanged())); connect(d->m_profilerModelManager, SIGNAL(error(QString)), this, SLOT(showErrorDialog(QString))); - connect(d->m_profilerConnections, - SIGNAL(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)), - d->m_profilerModelManager, - SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); - connect(d->m_profilerConnections, - SIGNAL(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64)), - d->m_profilerModelManager, - SLOT(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64))); - connect(d->m_profilerConnections, - SIGNAL(addPixmapCacheEvent(qint64,int,QString,int,int,int)), - d->m_profilerModelManager, - SLOT(addPixmapCacheEvent(qint64,int,QString,int,int,int))); - connect(d->m_profilerConnections, - SIGNAL(addV8Event(int,QString,QString,int,double,double)), - d->m_profilerModelManager, - SLOT(addV8Event(int,QString,QString,int,double,double))); - connect(d->m_profilerConnections, SIGNAL(addFrameEvent(qint64,int,int)), d->m_profilerModelManager, SLOT(addFrameEvent(qint64,int,int))); - connect(d->m_profilerConnections, SIGNAL(traceStarted(qint64)), d->m_profilerModelManager->traceTime(), SLOT(setStartTime(qint64))); - connect(d->m_profilerConnections, SIGNAL(traceFinished(qint64)), d->m_profilerModelManager->traceTime(), SLOT(setEndTime(qint64))); - connect(d->m_profilerConnections, SIGNAL(dataReadyForProcessing()), d->m_profilerModelManager, SLOT(complete())); + d->m_profilerConnections->setModelManager(d->m_profilerModelManager); Command *command = 0; const Context globalContext(C_GLOBAL); @@ -733,8 +714,13 @@ void QmlProfilerTool::serverRecordingChanged() setRecording(d->m_profilerState->serverRecording()); // clear the old data each time we start a new profiling session if (d->m_profilerState->serverRecording()) { + d->m_clearButton->setEnabled(false); clearData(); d->m_profilerModelManager->prepareForWriting(); + } else { + d->m_clearButton->setEnabled(true); } + } else { + d->m_clearButton->setEnabled(true); } } diff --git a/plugins/qmlprofiler/qv8profilerdatamodel.cpp b/plugins/qmlprofiler/qv8profilerdatamodel.cpp index ab4c7b8fa8..406d010e80 100644 --- a/plugins/qmlprofiler/qv8profilerdatamodel.cpp +++ b/plugins/qmlprofiler/qv8profilerdatamodel.cpp @@ -274,12 +274,6 @@ void QV8ProfilerDataModel::QV8ProfilerDataModelPrivate::collectV8Statistics() } else { // On empty data, still add a fake root event clearV8RootEvent(); - v8RootEvent.totalPercent = 100; - QString rootEventHash = getHashStringForV8Event( - tr("<program>"), - tr("Main Program")); - v8EventHash[rootEventHash] = new QV8EventData; - *v8EventHash[rootEventHash] = v8RootEvent; } } diff --git a/plugins/qmlprofiler/timelinemodelaggregator.cpp b/plugins/qmlprofiler/timelinemodelaggregator.cpp index 89f04d8daa..6e3f4c2c35 100644 --- a/plugins/qmlprofiler/timelinemodelaggregator.cpp +++ b/plugins/qmlprofiler/timelinemodelaggregator.cpp @@ -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())); @@ -176,6 +176,11 @@ qint64 TimelineModelAggregator::lastTimeMark() const return mark; } +bool TimelineModelAggregator::expanded(int modelIndex, int category) const +{ + return d->modelList[modelIndex]->expanded(category); +} + void TimelineModelAggregator::setExpanded(int modelIndex, int category, bool expanded) { // int modelIndex = modelIndexForCategory(category); diff --git a/plugins/qmlprofiler/timelinemodelaggregator.h b/plugins/qmlprofiler/timelinemodelaggregator.h index 9c15f362b3..65dd3496c6 100644 --- a/plugins/qmlprofiler/timelinemodelaggregator.h +++ b/plugins/qmlprofiler/timelinemodelaggregator.h @@ -68,6 +68,7 @@ public: Q_INVOKABLE qint64 lastTimeMark() const; + Q_INVOKABLE bool expanded(int modelIndex, int category) const; Q_INVOKABLE void setExpanded(int modelIndex, int category, bool expanded); Q_INVOKABLE int categoryDepth(int modelIndex, int categoryIndex) const; Q_INVOKABLE int categoryCount(int modelIndex) const; diff --git a/plugins/qmlprofilerextension/pixmapcachemodel.cpp b/plugins/qmlprofilerextension/pixmapcachemodel.cpp index db8cd938be..033865969a 100644 --- a/plugins/qmlprofilerextension/pixmapcachemodel.cpp +++ b/plugins/qmlprofilerextension/pixmapcachemodel.cpp @@ -101,6 +101,11 @@ qint64 PixmapCacheModel::lastTimeMark() const return d->eventList.last().startTime; } +bool PixmapCacheModel::expanded(int ) const +{ + return d->isExpanded; +} + void PixmapCacheModel::setExpanded(int category, bool expanded) { Q_UNUSED(category); @@ -445,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) { @@ -458,6 +465,8 @@ void PixmapCacheModel::loadData() d->computeCacheSizes(); d->flattenLoads(); d->computeRowCounts(); + + m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1); } void PixmapCacheModel::clear() @@ -467,11 +476,14 @@ void PixmapCacheModel::clear() d->pixmapSizes.clear(); d->collapsedRowCount = 1; d->expandedRowCount = 1; + d->isExpanded = false; + + m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1); } void PixmapCacheModel::dataChanged() { - if (m_modelManager->state() == QmlProfilerDataState::Done) + if (m_modelManager->state() == QmlProfilerDataState::ProcessingData) loadData(); if (m_modelManager->state() == QmlProfilerDataState::Empty) @@ -480,7 +492,7 @@ void PixmapCacheModel::dataChanged() emit stateChanged(); emit dataAvailable(); emit emptyChanged(); - return; + emit expandedChanged(); } void PixmapCacheModel::PixmapCacheModelPrivate::computeCacheSizes() diff --git a/plugins/qmlprofilerextension/pixmapcachemodel.h b/plugins/qmlprofilerextension/pixmapcachemodel.h index 8fd38bb378..9b006e49ce 100644 --- a/plugins/qmlprofilerextension/pixmapcachemodel.h +++ b/plugins/qmlprofilerextension/pixmapcachemodel.h @@ -73,6 +73,7 @@ public: Q_INVOKABLE qint64 lastTimeMark() const; + Q_INVOKABLE bool expanded(int category) const; Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryCount() const; diff --git a/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp b/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp index bcca3987e7..129419e16b 100644 --- a/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp +++ b/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp @@ -109,6 +109,11 @@ qint64 SceneGraphTimelineModel::lastTimeMark() const return d->eventList.last().startTime; } +bool SceneGraphTimelineModel::expanded(int ) const +{ + return d->isExpanded; +} + void SceneGraphTimelineModel::setExpanded(int category, bool expanded) { Q_UNUSED(category); @@ -454,19 +459,24 @@ 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() { - if (m_modelManager->state() == QmlProfilerDataState::Done) + if (m_modelManager->state() == QmlProfilerDataState::ProcessingData) loadData(); if (m_modelManager->state() == QmlProfilerDataState::Empty) @@ -475,7 +485,7 @@ void SceneGraphTimelineModel::dataChanged() emit stateChanged(); emit dataAvailable(); emit emptyChanged(); - return; + emit expandedChanged(); } diff --git a/plugins/qmlprofilerextension/scenegraphtimelinemodel.h b/plugins/qmlprofilerextension/scenegraphtimelinemodel.h index 83812643a3..ae8d14eb11 100644 --- a/plugins/qmlprofilerextension/scenegraphtimelinemodel.h +++ b/plugins/qmlprofilerextension/scenegraphtimelinemodel.h @@ -61,6 +61,7 @@ public: Q_INVOKABLE qint64 lastTimeMark() const; + Q_INVOKABLE bool expanded(int category) const; Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryCount() const; |