Merge branch '2.8'

Change-Id: I72da0b7942c0c98639e8d2f5397f2d95caf7f612
This commit is contained in:
Christiaan Janssen
2013-08-06 16:17:00 +02:00
35 changed files with 501 additions and 112 deletions

View File

@@ -43,11 +43,12 @@ class AbstractQmlProfilerRunner : public QObject
public: public:
explicit AbstractQmlProfilerRunner(QObject *parent = 0) : QObject(parent) { } explicit AbstractQmlProfilerRunner(QObject *parent = 0) : QObject(parent) { }
virtual quint16 debugPort() const = 0;
public slots:
virtual void start() = 0; virtual void start() = 0;
virtual void stop() = 0; virtual void stop() = 0;
virtual quint16 debugPort() const = 0;
signals: signals:
void started(); void started();
void stopped(); void stopped();

View File

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

View File

@@ -64,6 +64,7 @@ public:
Q_INVOKABLE qint64 traceDuration() const; Q_INVOKABLE qint64 traceDuration() const;
Q_INVOKABLE int getState() 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 void setExpanded(int category, bool expanded) = 0;
Q_INVOKABLE virtual int categoryDepth(int categoryIndex) const = 0; Q_INVOKABLE virtual int categoryDepth(int categoryIndex) const = 0;
Q_INVOKABLE virtual int categoryCount() const = 0; Q_INVOKABLE virtual int categoryCount() const = 0;
@@ -106,6 +107,7 @@ signals:
protected: protected:
QmlProfiler::Internal::QmlProfilerModelManager *m_modelManager; QmlProfiler::Internal::QmlProfilerModelManager *m_modelManager;
int m_modelId;
}; };

View File

@@ -29,13 +29,62 @@
#include "localqmlprofilerrunner.h" #include "localqmlprofilerrunner.h"
#include "qmlprofilerplugin.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;
using namespace QmlProfiler::Internal; using namespace QmlProfiler::Internal;
using namespace ProjectExplorer;
LocalQmlProfilerRunner::LocalQmlProfilerRunner(const Configuration &configuration, QObject *parent) : LocalQmlProfilerRunner *LocalQmlProfilerRunner::createLocalRunner(
AbstractQmlProfilerRunner(parent), RunConfiguration *runConfiguration,
m_configuration(configuration) 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;
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)), connect(&m_launcher, SIGNAL(appendMessage(QString,Utils::OutputFormat)),
this, SIGNAL(appendMessage(QString,Utils::OutputFormat))); this, SIGNAL(appendMessage(QString,Utils::OutputFormat)));
@@ -48,6 +97,9 @@ LocalQmlProfilerRunner::~LocalQmlProfilerRunner()
void LocalQmlProfilerRunner::start() void LocalQmlProfilerRunner::start()
{ {
if (m_engine->mode() != Analyzer::StartQml)
return;
QString arguments = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_configuration.port); QString arguments = QString::fromLatin1("-qmljsdebugger=port:%1,block").arg(m_configuration.port);
if (!m_configuration.executableArguments.isEmpty()) if (!m_configuration.executableArguments.isEmpty())
@@ -78,6 +130,9 @@ void LocalQmlProfilerRunner::spontaneousStop(int exitCode)
void LocalQmlProfilerRunner::stop() void LocalQmlProfilerRunner::stop()
{ {
if (m_engine->mode() != Analyzer::StartQml)
return;
if (QmlProfilerPlugin::debugOutput) if (QmlProfilerPlugin::debugOutput)
qWarning("QmlProfiler: Stopping application ..."); qWarning("QmlProfiler: Stopping application ...");

View File

@@ -35,9 +35,13 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <projectexplorer/applicationlauncher.h> #include <projectexplorer/applicationlauncher.h>
namespace ProjectExplorer { class RunConfiguration; }
namespace Analyzer { class AnalyzerStartParameters; }
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
class QmlProfilerEngine;
class LocalQmlProfilerRunner : public AbstractQmlProfilerRunner class LocalQmlProfilerRunner : public AbstractQmlProfilerRunner
{ {
Q_OBJECT Q_OBJECT
@@ -51,7 +55,11 @@ public:
Utils::Environment environment; 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(); ~LocalQmlProfilerRunner();
// AbstractQmlProfilerRunner // AbstractQmlProfilerRunner
@@ -59,14 +67,16 @@ public:
virtual void stop(); virtual void stop();
virtual quint16 debugPort() const; virtual quint16 debugPort() const;
bool hasExecutable() const { return !m_configuration.executable.isEmpty(); }
private slots: private slots:
void spontaneousStop(int exitCode); void spontaneousStop(int exitCode);
private:
LocalQmlProfilerRunner(const Configuration &configuration, QmlProfilerEngine *engine);
private: private:
Configuration m_configuration; Configuration m_configuration;
ProjectExplorer::ApplicationLauncher m_launcher; ProjectExplorer::ApplicationLauncher m_launcher;
QmlProfilerEngine *m_engine;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -57,6 +57,8 @@ Item {
} }
function updateHeight() { function updateHeight() {
if (expanded != qmlProfilerModelProxy.expanded(modelIndex, categoryIndex))
expanded = qmlProfilerModelProxy.expanded(modelIndex, categoryIndex);
height = root.singleRowHeight * qmlProfilerModelProxy.categoryDepth(modelIndex, categoryIndex); height = root.singleRowHeight * qmlProfilerModelProxy.categoryDepth(modelIndex, categoryIndex);
} }

View File

@@ -21,6 +21,7 @@ SOURCES += \
qmlprofilerclientmanager.cpp \ qmlprofilerclientmanager.cpp \
qmlprofilerviewmanager.cpp \ qmlprofilerviewmanager.cpp \
qmlprofilerstatewidget.cpp \ qmlprofilerstatewidget.cpp \
qmlprofilerruncontrolfactory.cpp \
qmlprofilermodelmanager.cpp \ qmlprofilermodelmanager.cpp \
qmlprofilersimplemodel.cpp \ qmlprofilersimplemodel.cpp \
qmlprofilerprocessedmodel.cpp \ qmlprofilerprocessedmodel.cpp \
@@ -51,6 +52,7 @@ HEADERS += \
qmlprofilerclientmanager.h \ qmlprofilerclientmanager.h \
qmlprofilerviewmanager.h \ qmlprofilerviewmanager.h \
qmlprofilerstatewidget.h \ qmlprofilerstatewidget.h \
qmlprofilerruncontrolfactory.h \
qmlprofilermodelmanager.h \ qmlprofilermodelmanager.h \
qmlprofilersimplemodel.h \ qmlprofilersimplemodel.h \
qmlprofilerprocessedmodel.h \ qmlprofilerprocessedmodel.h \

View File

@@ -46,6 +46,8 @@ QtcPlugin {
"qmlprofilermodelmanager.h", "qmlprofilermodelmanager.h",
"qmlprofilerplugin.cpp", "qmlprofilerplugin.cpp",
"qmlprofilerplugin.h", "qmlprofilerplugin.h",
"qmlprofilerruncontrolfactory.cpp",
"qmlprofilerruncontrolfactory.h",
"qmlprofilerprocessedmodel.cpp", "qmlprofilerprocessedmodel.cpp",
"qmlprofilerprocessedmodel.h", "qmlprofilerprocessedmodel.h",
"qmlprofilersimplemodel.cpp", "qmlprofilersimplemodel.cpp",

View File

@@ -40,6 +40,8 @@
#include <QTimer> #include <QTimer>
#include <QMessageBox> #include <QMessageBox>
#include "qmlprofilermodelmanager.h"
using namespace QmlDebug; using namespace QmlDebug;
using namespace Core; using namespace Core;
@@ -70,6 +72,8 @@ public:
bool v8DataReady; bool v8DataReady;
bool qmlDataReady; bool qmlDataReady;
QmlProfilerModelManager *modelManager;
}; };
QmlProfilerClientManager::QmlProfilerClientManager(QObject *parent) : QmlProfilerClientManager::QmlProfilerClientManager(QObject *parent) :
@@ -84,6 +88,8 @@ QmlProfilerClientManager::QmlProfilerClientManager(QObject *parent) :
d->v8DataReady = false; d->v8DataReady = false;
d->qmlDataReady = false; d->qmlDataReady = false;
d->modelManager = 0;
d->connectionTimer.setInterval(200); d->connectionTimer.setInterval(200);
connect(&d->connectionTimer, SIGNAL(timeout()), SLOT(tryToConnect())); connect(&d->connectionTimer, SIGNAL(timeout()), SLOT(tryToConnect()));
} }
@@ -97,6 +103,18 @@ QmlProfilerClientManager::~QmlProfilerClientManager()
delete d; 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 // Interface
void QmlProfilerClientManager::setTcpConnection(QString host, quint64 port) void QmlProfilerClientManager::setTcpConnection(QString host, quint64 port)
@@ -162,22 +180,22 @@ void QmlProfilerClientManager::connectClientSignals()
this, SLOT(qmlComplete())); this, SLOT(qmlComplete()));
connect(d->qmlclientplugin.data(), connect(d->qmlclientplugin.data(),
SIGNAL(range(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)), SIGNAL(range(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)),
this, d->modelManager,
SIGNAL(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)));
connect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)), connect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)),
this, SIGNAL(traceFinished(qint64))); d->modelManager->traceTime(), SLOT(setEndTime(qint64)));
connect(d->qmlclientplugin.data(), SIGNAL(traceStarted(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)), 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(), connect(d->qmlclientplugin.data(),
SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)), SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)),
this, d->modelManager,
SIGNAL(addPixmapCacheEvent(qint64,int,QString,int,int,int))); SLOT(addPixmapCacheEvent(qint64,int,QString,int,int,int)));
connect(d->qmlclientplugin.data(), connect(d->qmlclientplugin.data(),
SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64)), SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64)),
this, d->modelManager,
SIGNAL(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64))); SLOT(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64)));
connect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()), connect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()),
d->qmlclientplugin.data(), SLOT(sendRecordingStatus())); d->qmlclientplugin.data(), SLOT(sendRecordingStatus()));
// fixme: this should be unified for both clients // 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(complete()), this, SLOT(v8Complete()));
connect(d->v8clientplugin.data(), connect(d->v8clientplugin.data(),
SIGNAL(v8range(int,QString,QString,int,double,double)), SIGNAL(v8range(int,QString,QString,int,double,double)),
this, d->modelManager,
SIGNAL(addV8Event(int,QString,QString,int,double,double))); SLOT(addV8Event(int,QString,QString,int,double,double)));
connect(d->v8clientplugin.data(), SIGNAL(enabledChanged()), connect(d->v8clientplugin.data(), SIGNAL(enabledChanged()),
d->v8clientplugin.data(), SLOT(sendRecordingStatus())); d->v8clientplugin.data(), SLOT(sendRecordingStatus()));
} }
@@ -202,22 +220,22 @@ void QmlProfilerClientManager::disconnectClientSignals()
this, SLOT(qmlComplete())); this, SLOT(qmlComplete()));
disconnect(d->qmlclientplugin.data(), disconnect(d->qmlclientplugin.data(),
SIGNAL(range(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)), SIGNAL(range(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)),
this, d->modelManager,
SIGNAL(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation))); SLOT(addRangedEvent(int,int,qint64,qint64,QStringList,QmlDebug::QmlEventLocation)));
disconnect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)), disconnect(d->qmlclientplugin.data(), SIGNAL(traceFinished(qint64)),
this, SIGNAL(traceFinished(qint64))); d->modelManager->traceTime(), SLOT(setEndTime(qint64)));
disconnect(d->qmlclientplugin.data(), SIGNAL(traceStarted(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)), 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(), disconnect(d->qmlclientplugin.data(),
SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)), SIGNAL(pixmapCacheEvent(qint64,int,QString,int,int,int)),
this, d->modelManager,
SIGNAL(addPixmapCacheEvent(qint64,int,QString,int,int,int))); SLOT(addPixmapCacheEvent(qint64,int,QString,int,int,int)));
disconnect(d->qmlclientplugin.data(), disconnect(d->qmlclientplugin.data(),
SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64)), SIGNAL(sceneGraphFrame(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64)),
this, d->modelManager,
SIGNAL(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64))); SLOT(addSceneGraphEvent(int,int,qint64,qint64,qint64,qint64,qint64,qint64,qint64)));
disconnect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()), disconnect(d->qmlclientplugin.data(), SIGNAL(enabledChanged()),
d->qmlclientplugin.data(), SLOT(sendRecordingStatus())); d->qmlclientplugin.data(), SLOT(sendRecordingStatus()));
// fixme: this should be unified for both clients // 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(complete()), this, SLOT(v8Complete()));
disconnect(d->v8clientplugin.data(), disconnect(d->v8clientplugin.data(),
SIGNAL(v8range(int,QString,QString,int,double,double)), SIGNAL(v8range(int,QString,QString,int,double,double)),
this, d->modelManager,
SIGNAL(addV8Event(int,QString,QString,int,double,double))); SLOT(addV8Event(int,QString,QString,int,double,double)));
disconnect(d->v8clientplugin.data(), SIGNAL(enabledChanged()), disconnect(d->v8clientplugin.data(), SIGNAL(enabledChanged()),
d->v8clientplugin.data(), SLOT(sendRecordingStatus())); d->v8clientplugin.data(), SLOT(sendRecordingStatus()));
} }

View File

@@ -39,6 +39,8 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
class QmlProfilerModelManager;
class QmlProfilerClientManager : public QObject class QmlProfilerClientManager : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -55,19 +57,11 @@ public:
void discardPendingData(); void discardPendingData();
bool isConnected() const; bool isConnected() const;
void setModelManager(QmlProfilerModelManager *m);
signals: signals:
void connectionFailed(); void connectionFailed();
void connectionClosed(); 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 dataReadyForProcessing();
void addSceneGraphEvent(int, int, qint64, qint64, qint64, qint64, qint64, qint64);
void addPixmapCacheEvent(qint64,int,QString,int,int,int);
public slots: public slots:
void connectClient(quint16 port); void connectClient(quint16 port);

View File

@@ -68,14 +68,11 @@ public:
~QmlProfilerEnginePrivate() { delete m_runner; } ~QmlProfilerEnginePrivate() { delete m_runner; }
bool attach(const QString &address, uint port); bool attach(const QString &address, uint port);
AbstractQmlProfilerRunner *createRunner(ProjectExplorer::RunConfiguration *runConfiguration,
QObject *parent);
QmlProfilerEngine *q; QmlProfilerEngine *q;
QmlProfilerStateManager *m_profilerState; QmlProfilerStateManager *m_profilerState;
AbstractQmlProfilerRunner *m_runner;
QTimer m_noDebugOutputTimer; QTimer m_noDebugOutputTimer;
QmlDebug::QmlOutputParser m_outputParser; QmlDebug::QmlOutputParser m_outputParser;
}; };
@@ -160,11 +157,6 @@ bool QmlProfilerEngine::start()
{ {
QTC_ASSERT(d->m_profilerState, return false); 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); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStarting);
if (QmlProjectManager::QmlProjectRunConfiguration *rc = if (QmlProjectManager::QmlProjectRunConfiguration *rc =
@@ -201,7 +193,7 @@ bool QmlProfilerEngine::start()
} }
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppRunning);
emit starting(this); engineStarted();
return true; return true;
} }
@@ -242,7 +234,7 @@ void QmlProfilerEngine::notifyRemoteFinished(bool success)
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppKilled); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppKilled);
AnalyzerManager::stopTool(); AnalyzerManager::stopTool();
emit finished(); engineFinished();
break; break;
} }
case QmlProfilerStateManager::AppStopped : case QmlProfilerStateManager::AppStopped :
@@ -262,10 +254,6 @@ void QmlProfilerEngine::cancelProcess()
{ {
QTC_ASSERT(d->m_profilerState, return); 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()) { switch (d->m_profilerState->currentState()) {
case QmlProfilerStateManager::AppReadyToStop : { case QmlProfilerStateManager::AppReadyToStop : {
d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStopped); d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppStopped);
@@ -282,10 +270,7 @@ void QmlProfilerEngine::cancelProcess()
return; return;
} }
} }
engineFinished();
if (d->m_runner)
d->m_runner->stop();
emit finished();
} }
void QmlProfilerEngine::logApplicationMessage(const QString &msg, Utils::OutputFormat format) void QmlProfilerEngine::logApplicationMessage(const QString &msg, Utils::OutputFormat format)
@@ -348,10 +333,20 @@ void QmlProfilerEngine::processIsRunning(quint16 port)
{ {
d->m_noDebugOutputTimer.stop(); d->m_noDebugOutputTimer.stop();
if (port > 0) if (port > 0 && mode() != StartQmlRemote)
emit processRunning(port); 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()) { switch (d->m_profilerState->currentState()) {
case QmlProfilerStateManager::AppReadyToStop : { case QmlProfilerStateManager::AppReadyToStop : {
if (d->m_running)
cancelProcess(); cancelProcess();
break; break;
} }
case QmlProfilerStateManager::Idle : { 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(); d->m_noDebugOutputTimer.stop();
if (d->m_runner) {
delete d->m_runner;
d->m_runner = 0;
}
break; break;
} }
default: default:

View File

@@ -68,6 +68,8 @@ private slots:
void wrongSetupMessageBox(const QString &errorMessage); void wrongSetupMessageBox(const QString &errorMessage);
void wrongSetupMessageBoxFinished(int); void wrongSetupMessageBoxFinished(int);
void processIsRunning(quint16 port = 0); void processIsRunning(quint16 port = 0);
void engineStarted();
void engineFinished();
private slots: private slots:
void profilerStateChanged(); void profilerStateChanged();

View File

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

View File

@@ -139,6 +139,10 @@ public:
QmlProfilerDataState *dataState; QmlProfilerDataState *dataState;
QmlProfilerTraceTime *traceTime; QmlProfilerTraceTime *traceTime;
QVector <double> partialCounts;
double progress;
qint64 estimatedTime;
// file to load // file to load
QString fileName; QString fileName;
}; };
@@ -184,6 +188,43 @@ int QmlProfilerModelManager::count() const
return d->model->count(); 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) 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 // If trace start time was not explicitly set, use the first event
@@ -313,6 +354,7 @@ void QmlProfilerModelManager::load()
complete(); complete();
} }
void QmlProfilerModelManager::setState(QmlProfilerDataState::State state) void QmlProfilerModelManager::setState(QmlProfilerDataState::State state)
{ {
d->dataState->setState(state); d->dataState->setState(state);
@@ -325,6 +367,9 @@ QmlProfilerDataState::State QmlProfilerModelManager::state() const
void QmlProfilerModelManager::clear() void QmlProfilerModelManager::clear()
{ {
for (int i = 0; i < d->partialCounts.count(); i++)
d->partialCounts[i] = 0;
d->progress = 0;
d->model->clear(); d->model->clear();
d->v8Model->clear(); d->v8Model->clear();
d->traceTime->clear(); d->traceTime->clear();

View File

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

View File

@@ -61,6 +61,7 @@ public:
QVector <PaintEventsModelProxy::QmlPaintEventData> eventList; QVector <PaintEventsModelProxy::QmlPaintEventData> eventList;
int minAnimationCount; int minAnimationCount;
int maxAnimationCount; int maxAnimationCount;
bool expanded;
PaintEventsModelProxy *q; PaintEventsModelProxy *q;
}; };
@@ -113,11 +114,13 @@ void PaintEventsModelProxy::clear()
d->eventList.clear(); d->eventList.clear();
d->minAnimationCount = 1; d->minAnimationCount = 1;
d->maxAnimationCount = 1; d->maxAnimationCount = 1;
d->expanded = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
} }
void PaintEventsModelProxy::dataChanged() void PaintEventsModelProxy::dataChanged()
{ {
if (m_modelManager->state() == QmlProfilerDataState::Done) if (m_modelManager->state() == QmlProfilerDataState::ProcessingData)
loadData(); loadData();
if (m_modelManager->state() == QmlProfilerDataState::Empty) if (m_modelManager->state() == QmlProfilerDataState::Empty)
@@ -126,6 +129,7 @@ void PaintEventsModelProxy::dataChanged()
emit stateChanged(); emit stateChanged();
emit dataAvailable(); emit dataAvailable();
emit emptyChanged(); emit emptyChanged();
emit expandedChanged();
} }
bool compareStartTimes(const PaintEventsModelProxy::QmlPaintEventData &t1, const PaintEventsModelProxy::QmlPaintEventData &t2) bool compareStartTimes(const PaintEventsModelProxy::QmlPaintEventData &t1, const PaintEventsModelProxy::QmlPaintEventData &t2)
@@ -173,12 +177,16 @@ void PaintEventsModelProxy::loadData()
}; };
d->eventList.append(newEvent); d->eventList.append(newEvent);
m_modelManager->modelProxyCountUpdated(m_modelId, d->eventList.count(), referenceList.count());
} }
d->computeAnimationCountLimit(); d->computeAnimationCountLimit();
qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes); qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
emit countChanged(); emit countChanged();
} }
@@ -199,10 +207,15 @@ qint64 PaintEventsModelProxy::lastTimeMark() const
return d->eventList.last().startTime + d->eventList.last().duration; return d->eventList.last().startTime + d->eventList.last().duration;
} }
bool PaintEventsModelProxy::expanded(int ) const
{
return d->expanded;
}
void PaintEventsModelProxy::setExpanded(int category, bool expanded) void PaintEventsModelProxy::setExpanded(int category, bool expanded)
{ {
Q_UNUSED(category); Q_UNUSED(category);
Q_UNUSED(expanded); d->expanded = expanded;
emit expandedChanged(); emit expandedChanged();
} }
@@ -324,6 +337,8 @@ QColor PaintEventsModelProxy::getColor(int index) const
double fpsFraction = d->eventList[index].framerate / 60.0; double fpsFraction = d->eventList[index].framerate / 60.0;
if (fpsFraction > 1.0) if (fpsFraction > 1.0)
fpsFraction = 1.0; fpsFraction = 1.0;
if (fpsFraction < 0.0)
fpsFraction = 0.0;
return QColor::fromHsl((fpsFraction*96)+10, 76, 166); return QColor::fromHsl((fpsFraction*96)+10, 76, 166);
} }

View File

@@ -80,6 +80,7 @@ public:
Q_INVOKABLE qint64 lastTimeMark() const; Q_INVOKABLE qint64 lastTimeMark() const;
Q_INVOKABLE bool expanded(int category) const;
Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE void setExpanded(int category, bool expanded);
Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryDepth(int categoryIndex) const;
Q_INVOKABLE int categoryCount() const; Q_INVOKABLE int categoryCount() const;

View File

@@ -28,6 +28,7 @@
****************************************************************************/ ****************************************************************************/
#include "qmlprofilerplugin.h" #include "qmlprofilerplugin.h"
#include "qmlprofilerruncontrolfactory.h"
#include "qmlprofilertool.h" #include "qmlprofilertool.h"
#include "abstracttimelinemodel.h" #include "abstracttimelinemodel.h"
@@ -55,6 +56,8 @@ bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorS
modes.append(StartMode(StartLocal)); modes.append(StartMode(StartLocal));
modes.append(StartMode(StartRemote)); modes.append(StartMode(StartRemote));
AnalyzerManager::addTool(new QmlProfilerTool(this), modes); AnalyzerManager::addTool(new QmlProfilerTool(this), modes);
addAutoReleasedObject(new QmlProfilerRunControlFactory());
QmlProfilerPlugin::instance = this; QmlProfilerPlugin::instance = this;
return true; return true;

View File

@@ -28,7 +28,6 @@
****************************************************************************/ ****************************************************************************/
#include "qmlprofilerprocessedmodel.h" #include "qmlprofilerprocessedmodel.h"
#include <qmldebug/qmlprofilereventtypes.h> #include <qmldebug/qmlprofilereventtypes.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QUrl> #include <QUrl>
@@ -44,7 +43,8 @@ QString getInitialDetails(const QmlProfilerSimpleModel::QmlEventData &event);
QmlDebug::QmlEventLocation getLocation(const QmlProfilerSimpleModel::QmlEventData &event) QmlDebug::QmlEventLocation getLocation(const QmlProfilerSimpleModel::QmlEventData &event)
{ {
QmlDebug::QmlEventLocation eventLocation = event.location; 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.filename = getInitialDetails(event);
eventLocation.line = 1; eventLocation.line = 1;
eventLocation.column = 1; eventLocation.column = 1;
@@ -155,6 +155,7 @@ void QmlProfilerProcessedModel::complete()
m_detailsRewriter->reloadDocuments(); m_detailsRewriter->reloadDocuments();
QmlProfilerSimpleModel::complete();
emit changed(); emit changed();
m_emitChanged = false; m_emitChanged = false;
} }

View File

@@ -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

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

@@ -126,15 +126,22 @@ void BasicTimelineModel::clear()
d->startTimeData.clear(); d->startTimeData.clear();
d->endTimeData.clear(); d->endTimeData.clear();
d->categorySpan.clear(); d->categorySpan.clear();
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
} }
void BasicTimelineModel::dataChanged() void BasicTimelineModel::dataChanged()
{ {
if (m_modelManager->state() == QmlProfilerDataState::ProcessingData)
loadData(); loadData();
if (m_modelManager->state() == QmlProfilerDataState::Empty)
clear();
emit stateChanged(); emit stateChanged();
emit dataAvailable(); emit dataAvailable();
emit emptyChanged(); emit emptyChanged();
emit expandedChanged();
} }
void BasicTimelineModel::BasicTimelineModelPrivate::prepare() void BasicTimelineModel::BasicTimelineModelPrivate::prepare()
@@ -208,23 +215,37 @@ void BasicTimelineModel::loadData()
-1 // bindingLoopHead -1 // bindingLoopHead
}; };
d->startTimeData.append(eventStartInstance); d->startTimeData.append(eventStartInstance);
m_modelManager->modelProxyCountUpdated(m_modelId, d->startTimeData.count(), eventList.count() * 7);
} }
qSort(d->startTimeData.begin(), d->startTimeData.end(), compareStartTimes); qSort(d->startTimeData.begin(), d->startTimeData.end(), compareStartTimes);
m_modelManager->modelProxyCountUpdated(m_modelId, 2, 7);
// compute nestingLevel - nonexpanded // compute nestingLevel - nonexpanded
d->computeNestingContracted(); d->computeNestingContracted();
m_modelManager->modelProxyCountUpdated(m_modelId, 3, 7);
// compute nestingLevel - expanded // compute nestingLevel - expanded
d->computeExpandedLevels(); d->computeExpandedLevels();
m_modelManager->modelProxyCountUpdated(m_modelId, 4, 7);
// populate endtimelist // populate endtimelist
d->buildEndTimeList(); d->buildEndTimeList();
m_modelManager->modelProxyCountUpdated(m_modelId, 5, 7);
d->findBindingLoops(); d->findBindingLoops();
m_modelManager->modelProxyCountUpdated(m_modelId, 6, 7);
d->computeRowStarts(); d->computeRowStarts();
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
emit countChanged(); emit countChanged();
} }
@@ -393,6 +414,13 @@ qint64 BasicTimelineModel::lastTimeMark() const
return d->startTimeData.last().startTime + d->startTimeData.last().duration; 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) void BasicTimelineModel::setExpanded(int category, bool expanded)
{ {
if (d->categorySpan.count() <= category) if (d->categorySpan.count() <= category)

View File

@@ -101,6 +101,7 @@ public:
Q_INVOKABLE qint64 lastTimeMark() const; Q_INVOKABLE qint64 lastTimeMark() const;
Q_INVOKABLE bool expanded(int category) const;
Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE void setExpanded(int category, bool expanded);
Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryDepth(int categoryIndex) const;
Q_INVOKABLE int categoryCount() const; Q_INVOKABLE int categoryCount() const;

View File

@@ -149,27 +149,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this); d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this);
connect(d->m_profilerModelManager, SIGNAL(stateChanged()), this, SLOT(profilerDataModelStateChanged())); connect(d->m_profilerModelManager, SIGNAL(stateChanged()), this, SLOT(profilerDataModelStateChanged()));
connect(d->m_profilerModelManager, SIGNAL(error(QString)), this, SLOT(showErrorDialog(QString))); 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; Command *command = 0;
const Context globalContext(C_GLOBAL); const Context globalContext(C_GLOBAL);
@@ -733,8 +714,13 @@ void QmlProfilerTool::serverRecordingChanged()
setRecording(d->m_profilerState->serverRecording()); setRecording(d->m_profilerState->serverRecording());
// clear the old data each time we start a new profiling session // clear the old data each time we start a new profiling session
if (d->m_profilerState->serverRecording()) { if (d->m_profilerState->serverRecording()) {
d->m_clearButton->setEnabled(false);
clearData(); clearData();
d->m_profilerModelManager->prepareForWriting(); d->m_profilerModelManager->prepareForWriting();
} else {
d->m_clearButton->setEnabled(true);
} }
} else {
d->m_clearButton->setEnabled(true);
} }
} }

View File

@@ -274,12 +274,6 @@ void QV8ProfilerDataModel::QV8ProfilerDataModelPrivate::collectV8Statistics()
} else { } else {
// On empty data, still add a fake root event // On empty data, still add a fake root event
clearV8RootEvent(); clearV8RootEvent();
v8RootEvent.totalPercent = 100;
QString rootEventHash = getHashStringForV8Event(
tr("<program>"),
tr("Main Program"));
v8EventHash[rootEventHash] = new QV8EventData;
*v8EventHash[rootEventHash] = v8RootEvent;
} }
} }

View File

@@ -69,6 +69,7 @@ void TimelineModelAggregator::setModelManager(QmlProfilerModelManager *modelMana
d->modelManager = modelManager; d->modelManager = modelManager;
connect(modelManager,SIGNAL(stateChanged()),this,SLOT(dataChanged())); connect(modelManager,SIGNAL(stateChanged()),this,SLOT(dataChanged()));
connect(modelManager,SIGNAL(countChanged()),this,SIGNAL(countChanged())); connect(modelManager,SIGNAL(countChanged()),this,SIGNAL(countChanged()));
connect(modelManager,SIGNAL(dataAvailable()),this,SIGNAL(dataAvailable()));
// external models pushed on top // external models pushed on top
foreach (AbstractTimelineModel *timelineModel, QmlProfilerPlugin::instance->getModels()) { foreach (AbstractTimelineModel *timelineModel, QmlProfilerPlugin::instance->getModels()) {
@@ -92,7 +93,6 @@ void TimelineModelAggregator::addModel(AbstractTimelineModel *m)
{ {
d->modelList << m; d->modelList << m;
connect(m,SIGNAL(countChanged()),this,SIGNAL(countChanged())); connect(m,SIGNAL(countChanged()),this,SIGNAL(countChanged()));
connect(m,SIGNAL(dataAvailable()),this,SIGNAL(dataAvailable()));
connect(m,SIGNAL(emptyChanged()),this,SIGNAL(emptyChanged())); connect(m,SIGNAL(emptyChanged()),this,SIGNAL(emptyChanged()));
connect(m,SIGNAL(expandedChanged()),this,SIGNAL(expandedChanged())); connect(m,SIGNAL(expandedChanged()),this,SIGNAL(expandedChanged()));
connect(m,SIGNAL(stateChanged()),this,SIGNAL(stateChanged())); connect(m,SIGNAL(stateChanged()),this,SIGNAL(stateChanged()));
@@ -176,6 +176,11 @@ qint64 TimelineModelAggregator::lastTimeMark() const
return mark; 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) void TimelineModelAggregator::setExpanded(int modelIndex, int category, bool expanded)
{ {
// int modelIndex = modelIndexForCategory(category); // int modelIndex = modelIndexForCategory(category);

View File

@@ -68,6 +68,7 @@ public:
Q_INVOKABLE qint64 lastTimeMark() const; 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 void setExpanded(int modelIndex, int category, bool expanded);
Q_INVOKABLE int categoryDepth(int modelIndex, int categoryIndex) const; Q_INVOKABLE int categoryDepth(int modelIndex, int categoryIndex) const;
Q_INVOKABLE int categoryCount(int modelIndex) const; Q_INVOKABLE int categoryCount(int modelIndex) const;

View File

@@ -101,6 +101,11 @@ qint64 PixmapCacheModel::lastTimeMark() const
return d->eventList.last().startTime; return d->eventList.last().startTime;
} }
bool PixmapCacheModel::expanded(int ) const
{
return d->isExpanded;
}
void PixmapCacheModel::setExpanded(int category, bool expanded) void PixmapCacheModel::setExpanded(int category, bool expanded)
{ {
Q_UNUSED(category); Q_UNUSED(category);
@@ -445,6 +450,8 @@ void PixmapCacheModel::loadData()
else else
d->eventList[loadIndex].cacheSize = -1; // ... or failure d->eventList[loadIndex].cacheSize = -1; // ... or failure
} }
m_modelManager->modelProxyCountUpdated(m_modelId, d->eventList.count(), 2*simpleModel->getEvents().count());
} }
if (lastCacheSizeEvent != -1) { if (lastCacheSizeEvent != -1) {
@@ -458,6 +465,8 @@ void PixmapCacheModel::loadData()
d->computeCacheSizes(); d->computeCacheSizes();
d->flattenLoads(); d->flattenLoads();
d->computeRowCounts(); d->computeRowCounts();
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
} }
void PixmapCacheModel::clear() void PixmapCacheModel::clear()
@@ -467,11 +476,14 @@ void PixmapCacheModel::clear()
d->pixmapSizes.clear(); d->pixmapSizes.clear();
d->collapsedRowCount = 1; d->collapsedRowCount = 1;
d->expandedRowCount = 1; d->expandedRowCount = 1;
d->isExpanded = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
} }
void PixmapCacheModel::dataChanged() void PixmapCacheModel::dataChanged()
{ {
if (m_modelManager->state() == QmlProfilerDataState::Done) if (m_modelManager->state() == QmlProfilerDataState::ProcessingData)
loadData(); loadData();
if (m_modelManager->state() == QmlProfilerDataState::Empty) if (m_modelManager->state() == QmlProfilerDataState::Empty)
@@ -480,7 +492,7 @@ void PixmapCacheModel::dataChanged()
emit stateChanged(); emit stateChanged();
emit dataAvailable(); emit dataAvailable();
emit emptyChanged(); emit emptyChanged();
return; emit expandedChanged();
} }
void PixmapCacheModel::PixmapCacheModelPrivate::computeCacheSizes() void PixmapCacheModel::PixmapCacheModelPrivate::computeCacheSizes()

View File

@@ -73,6 +73,7 @@ public:
Q_INVOKABLE qint64 lastTimeMark() const; Q_INVOKABLE qint64 lastTimeMark() const;
Q_INVOKABLE bool expanded(int category) const;
Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE void setExpanded(int category, bool expanded);
Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryDepth(int categoryIndex) const;
Q_INVOKABLE int categoryCount() const; Q_INVOKABLE int categoryCount() const;

View File

@@ -109,6 +109,11 @@ qint64 SceneGraphTimelineModel::lastTimeMark() const
return d->eventList.last().startTime; return d->eventList.last().startTime;
} }
bool SceneGraphTimelineModel::expanded(int ) const
{
return d->isExpanded;
}
void SceneGraphTimelineModel::setExpanded(int category, bool expanded) void SceneGraphTimelineModel::setExpanded(int category, bool expanded)
{ {
Q_UNUSED(category); Q_UNUSED(category);
@@ -454,19 +459,24 @@ void SceneGraphTimelineModel::loadData()
default: break; default: break;
} }
} }
m_modelManager->modelProxyCountUpdated(m_modelId, d->eventList.count(), simpleModel->getEvents().count());
} }
qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes); qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
m_modelManager->modelProxyCountUpdated(m_modelId, 1, 1);
} }
void SceneGraphTimelineModel::clear() void SceneGraphTimelineModel::clear()
{ {
d->eventList.clear(); d->eventList.clear();
d->isExpanded = false;
m_modelManager->modelProxyCountUpdated(m_modelId, 0, 1);
} }
void SceneGraphTimelineModel::dataChanged() void SceneGraphTimelineModel::dataChanged()
{ {
if (m_modelManager->state() == QmlProfilerDataState::Done) if (m_modelManager->state() == QmlProfilerDataState::ProcessingData)
loadData(); loadData();
if (m_modelManager->state() == QmlProfilerDataState::Empty) if (m_modelManager->state() == QmlProfilerDataState::Empty)
@@ -475,7 +485,7 @@ void SceneGraphTimelineModel::dataChanged()
emit stateChanged(); emit stateChanged();
emit dataAvailable(); emit dataAvailable();
emit emptyChanged(); emit emptyChanged();
return; emit expandedChanged();
} }

View File

@@ -61,6 +61,7 @@ public:
Q_INVOKABLE qint64 lastTimeMark() const; Q_INVOKABLE qint64 lastTimeMark() const;
Q_INVOKABLE bool expanded(int category) const;
Q_INVOKABLE void setExpanded(int category, bool expanded); Q_INVOKABLE void setExpanded(int category, bool expanded);
Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int categoryDepth(int categoryIndex) const;
Q_INVOKABLE int categoryCount() const; Q_INVOKABLE int categoryCount() const;