Commit 72c06cb6 authored by Christiaan Janssen's avatar Christiaan Janssen
Browse files

QmlProfiler: timers for all profiler activities



Change-Id: I2ecbf4d1d90e353506e7c164560b69b81fcc6c66
Reviewed-by: default avatarAurindam Jana <aurindam.jana@nokia.com>
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent fd4e21b6
......@@ -164,6 +164,8 @@ public:
qint64 m_traceEndTime;
qint64 m_traceStartTime;
qint64 m_qmlMeasuredTime;
qint64 m_v8MeasuredTime;
// file to load
QString m_filename;
......@@ -180,6 +182,8 @@ QmlProfilerEventList::QmlProfilerEventList(QObject *parent) :
d->m_traceEndTime = 0;
d->m_traceStartTime = -1;
d->m_qmlMeasuredTime = 0;
d->m_v8MeasuredTime = 0;
}
QmlProfilerEventList::~QmlProfilerEventList()
......@@ -206,6 +210,9 @@ void QmlProfilerEventList::clear()
d->m_traceEndTime = 0;
d->m_traceStartTime = -1;
d->m_qmlMeasuredTime = 0;
d->m_v8MeasuredTime = 0;
emit countChanged();
emit dataClear();
}
......@@ -339,6 +346,8 @@ void QmlProfilerEventList::addV8Event(int depth, const QString &function, const
if (!parentEvent->childrenList.contains(newData))
parentEvent->childrenList << newData;
}
} else {
d->m_v8MeasuredTime += totalTime;
}
}
......@@ -381,6 +390,7 @@ void QmlProfilerEventList::setTraceStartTime( qint64 time )
void QmlProfilerEventList::complete()
{
emit postProcessing();
d->collectV8Statistics();
postProcess();
}
......@@ -615,6 +625,10 @@ void QmlProfilerEventList::computeNestingLevels()
d->m_startTimeSortedList[i].level = level;
d->m_startTimeSortedList[i].nestingLevel = nestingLevels[type];
if (level == MIN_LEVEL) {
d->m_qmlMeasuredTime += d->m_startTimeSortedList[i].length;
}
}
}
......@@ -792,6 +806,15 @@ qint64 QmlProfilerEventList::traceDuration() const
return traceEndTime() - traceStartTime();
}
qint64 QmlProfilerEventList::qmlMeasuredTime() const
{
return d->m_qmlMeasuredTime;
}
qint64 QmlProfilerEventList::v8MeasuredTime() const
{
return d->m_v8MeasuredTime;
}
int QmlProfilerEventList::count() const
{
return d->m_startTimeSortedList.count();
......@@ -1137,6 +1160,7 @@ void QmlProfilerEventList::load()
descriptionBuffer.clear();
emit postProcessing();
d->collectV8Statistics();
postProcess();
}
......
......@@ -124,6 +124,8 @@ public:
Q_INVOKABLE qint64 traceStartTime() const;
Q_INVOKABLE qint64 traceEndTime() const;
Q_INVOKABLE qint64 traceDuration() const;
Q_INVOKABLE qint64 qmlMeasuredTime() const;
Q_INVOKABLE qint64 v8MeasuredTime() const;
void showErrorDialog(const QString &st ) const;
void compileStatistics(qint64 startTime, qint64 endTime);
......@@ -133,6 +135,7 @@ signals:
void error(const QString &error);
void dataClear();
void processingData();
void postProcessing();
public slots:
void clear();
......
......@@ -116,8 +116,8 @@ void QmlProfilerTraceClient::statusChanged(Status status)
{
if (status == Enabled) {
d->sendRecordingStatus();
emit enabled();
}
emit enabledChanged();
}
void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
......
......@@ -53,7 +53,7 @@ struct QMLJSDEBUGCLIENT_EXPORT Location
class QMLJSDEBUGCLIENT_EXPORT QmlProfilerTraceClient : public QmlJsDebugClient::QDeclarativeDebugClient
{
Q_OBJECT
Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabled)
Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool recording READ isRecording WRITE setRecording NOTIFY recordingChanged)
// don't hide by signal
......@@ -103,7 +103,7 @@ signals:
void recordingChanged(bool arg);
void enabled();
void enabledChanged();
void cleared();
protected:
......
......@@ -85,6 +85,11 @@ void QV8ProfilerClient::clearData()
emit cleared();
}
bool QV8ProfilerClient::isEnabled() const
{
return status() == Enabled;
}
bool QV8ProfilerClient::isRecording() const
{
return d->recording;
......@@ -108,8 +113,8 @@ void QV8ProfilerClient::statusChanged(Status status)
{
if (status == Enabled) {
d->sendRecordingStatus();
emit enabled();
}
emit enabledChanged();
}
void QV8ProfilerClient::messageReceived(const QByteArray &data)
......
......@@ -45,6 +45,7 @@ namespace QmlJsDebugClient {
class QMLJSDEBUGCLIENT_EXPORT QV8ProfilerClient : public QDeclarativeDebugClient
{
Q_OBJECT
Q_PROPERTY(bool enabled READ isEnabled NOTIFY enabledChanged)
Q_PROPERTY(bool recording READ isRecording WRITE setRecording NOTIFY recordingChanged)
public:
......@@ -58,6 +59,7 @@ public:
QV8ProfilerClient(QDeclarativeDebugConnection *client);
~QV8ProfilerClient();
bool isEnabled() const;
bool isRecording() const;
public slots:
......@@ -71,7 +73,7 @@ signals:
void recordingChanged(bool arg);
void enabled();
void enabledChanged();
void cleared();
protected:
......
......@@ -102,7 +102,7 @@ Rectangle {
root.clearAll();
if (eventCount > 1) {
root.progress = Math.min(1.0,
(qmlEventList.lastTimeMark() - qmlEventList.traceStartTime()) / root.elapsedTime * 1e-9 ) * 0.5;
(qmlEventList.lastTimeMark() - qmlEventList.traceStartTime()) / root.elapsedTime * 1e-9 );
} else {
root.progress = 0;
}
......@@ -112,6 +112,10 @@ Rectangle {
root.dataAvailable = false;
}
onPostProcessing: {
root.progress = 0.9; // jump to 90%
}
onDataReady: {
if (eventCount > 0) {
view.clearData();
......
import QtQuick 1.0
Rectangle {
Item {
id: statusDisplay
property real percentage : root.progress
......@@ -10,10 +10,29 @@ Rectangle {
visible: false;
color: "#CCD0CC"
border.width: 1
border.color: "#AAAEAA"
radius: 4
// shadow
BorderImage {
property int px: 4
source: "dialog_shadow.png"
border {
left: px; top: px
right: px; bottom: px
}
width: parent.width + 2*px - 1
height: parent.height
x: -px + 1
y: px + 1
}
// background
Rectangle {
color: "#E0E0E0"
border.width: 1
border.color: "#666666"
radius: 4
anchors.fill: parent
}
Column {
id: displayColumn
......
......@@ -84,6 +84,7 @@ public:
bool m_delayedDelete;
QTimer m_noDebugOutputTimer;
QmlJsDebugClient::QDeclarativeOutputParser m_outputParser;
QTimer m_runningTimer;
};
AbstractQmlProfilerRunner *
......@@ -153,6 +154,9 @@ QmlProfilerEngine::QmlProfilerEngine(IAnalyzerTool *tool,
this, SLOT(processIsRunning()));
connect(&d->m_outputParser, SIGNAL(errorMessage(QString)),
this, SLOT(wrongSetupMessageBox(QString)));
d->m_runningTimer.setInterval(100); // ten times per second
connect(&d->m_runningTimer, SIGNAL(timeout()), this, SIGNAL(timeUpdate()));
}
QmlProfilerEngine::~QmlProfilerEngine()
......@@ -201,6 +205,7 @@ bool QmlProfilerEngine::start()
d->m_running = true;
d->m_delayedDelete = false;
d->m_runningTimer.start();
if (d->m_fetchDataFromStart) {
d->m_fetchingData = true;
......@@ -236,6 +241,7 @@ void QmlProfilerEngine::stopped()
}
d->m_running = false;
d->m_runningTimer.stop();
AnalyzerManager::stopTool(); // FIXME: Needed?
emit finished();
}
......@@ -259,6 +265,7 @@ void QmlProfilerEngine::finishProcess()
// user stop?
if (d->m_running) {
d->m_running = false;
d->m_runningTimer.stop();
if (d->m_runner)
d->m_runner->stop();
emit finished();
......@@ -290,6 +297,7 @@ void QmlProfilerEngine::wrongSetupMessageBox(const QString &errorMessage)
infoBox->show();
d->m_running = false;
d->m_runningTimer.stop();
AnalyzerManager::stopTool();
emit finished();
}
......
......@@ -53,6 +53,7 @@ public:
signals:
void processRunning(int port);
void stopRecording();
void timeUpdate();
public slots:
bool start();
......
......@@ -117,6 +117,10 @@ public:
QToolButton *m_clearButton;
bool m_recordingEnabled;
bool m_appIsRunning;
bool m_qmlActive;
bool m_v8Active;
QTime m_appTimer;
qint64 m_appRunningTime;
enum ConnectMode {
TcpConnection, OstConnection
......@@ -141,6 +145,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_isAttached = false;
d->m_recordingEnabled = true;
d->m_appIsRunning = false;
d->m_appTimer.start();
d->m_appRunningTime = 0;
d->m_connectionTimer.setInterval(200);
connect(&d->m_connectionTimer, SIGNAL(timeout()), SLOT(tryToConnect()));
......@@ -337,8 +343,9 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp
connect(engine, SIGNAL(processRunning(int)), this, SLOT(connectClient(int)));
connect(engine, SIGNAL(finished()), this, SLOT(disconnectClient()));
connect(engine, SIGNAL(finished()), this, SLOT(correctTimer()));
connect(engine, SIGNAL(finished()), this, SLOT(updateTimers()));
connect(engine, SIGNAL(stopRecording()), this, SLOT(stopRecording()));
connect(engine, SIGNAL(timeUpdate()), this, SLOT(updateTimers()));
connect(d->m_traceWindow, SIGNAL(viewUpdated()), engine, SLOT(dataReceived()));
connect(this, SIGNAL(connectionFailed()), engine, SLOT(finishProcess()));
connect(this, SIGNAL(fetchingData(bool)), engine, SLOT(setFetchingData(bool)));
......@@ -364,10 +371,11 @@ QWidget *QmlProfilerTool::createWidgets()
d->m_traceWindow->reset(d->m_client);
connect(d->m_traceWindow, SIGNAL(gotoSourceLocation(QString,int)),this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_traceWindow, SIGNAL(timeChanged(qreal)), this, SLOT(updateTimer(qreal)));
connect(d->m_traceWindow, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
connect(d->m_traceWindow->getEventList(), SIGNAL(error(QString)), this, SLOT(showErrorDialog(QString)));
connect(d->m_traceWindow->getEventList(), SIGNAL(dataReady()), this, SLOT(showSaveOption()));
connect(d->m_traceWindow->getEventList(), SIGNAL(dataReady()), this, SLOT(updateTimers()));
connect(d->m_traceWindow, SIGNAL(profilerStateChanged(bool,bool)), this, SLOT(profilerStateChanged(bool,bool)));
d->m_eventsView = new QmlProfilerEventsWidget(d->m_traceWindow->getEventList(), mw);
connect(d->m_eventsView, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int)));
......@@ -419,14 +427,14 @@ QWidget *QmlProfilerTool::createWidgets()
connect(d->m_clearButton,SIGNAL(clicked()), this, SLOT(clearDisplay()));
layout->addWidget(d->m_clearButton);
QLabel *timeLabel = new QLabel(tr("Elapsed: 0 s"));
QLabel *timeLabel = new QLabel();
QPalette palette = timeLabel->palette();
palette.setColor(QPalette::WindowText, Qt::white);
timeLabel->setPalette(palette);
timeLabel->setIndent(10);
connect(d->m_traceWindow, SIGNAL(viewUpdated()), this, SLOT(correctTimer()));
connect(d->m_traceWindow, SIGNAL(viewUpdated()), this, SLOT(updateTimers()));
connect(this, SIGNAL(setTimeLabel(QString)), timeLabel, SLOT(setText(QString)));
correctTimer();
updateTimers();
layout->addWidget(timeLabel);
toolbarWidget->setLayout(layout);
......@@ -442,6 +450,7 @@ void QmlProfilerTool::connectClient(int port)
connect(d->m_client, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this, SLOT(connectionStateChanged()));
d->m_connectionTimer.start();
d->m_appTimer.start();
d->m_tcpPort = port;
}
......@@ -501,16 +510,20 @@ void QmlProfilerTool::setRecording(bool recording)
startRecording();
else
stopRecording();
updateTimers();
}
void QmlProfilerTool::setAppIsRunning()
{
d->m_appIsRunning = true;
updateTimers();
}
void QmlProfilerTool::setAppIsStopped()
{
d->m_appIsRunning = false;
updateTimers();
}
void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber)
......@@ -535,23 +548,33 @@ void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber)
}
}
void QmlProfilerTool::correctTimer() {
if (d->m_traceWindow->getEventList()->count() == 0)
updateTimer(0);
inline QString stringifyTime(double seconds)
{
QString timeString = QString::number(seconds,'f',1);
return QmlProfilerTool::tr("%1 s").arg(timeString, 6);
}
void QmlProfilerTool::updateTimers()
{
// prof time
QString profilerTimeStr = stringifyTime(d->m_traceWindow->profiledTime());
emit setTimeLabel(tr("Elapsed: %1").arg(profilerTimeStr));
}
void QmlProfilerTool::updateTimer(qreal elapsedSeconds)
void QmlProfilerTool::profilerStateChanged(bool qmlActive, bool v8active)
{
QString timeString = QString::number(elapsedSeconds,'f',1);
timeString = QString(" ").left(6-timeString.length()) + timeString;
emit setTimeLabel(tr("Elapsed: %1 s").arg(timeString));
d->m_v8Active = v8active;
d->m_qmlActive = qmlActive;
updateTimers();
}
void QmlProfilerTool::clearDisplay()
{
d->m_appRunningTime = 0;
d->m_traceWindow->clearDisplay();
d->m_eventsView->clear();
d->m_v8profilerView->clear();
updateTimers();
}
static void startRemoteTool(IAnalyzerTool *tool, StartMode mode)
......@@ -675,6 +698,8 @@ void QmlProfilerTool::updateRecordingState()
if (d->m_traceWindow->isRecording())
clearDisplay();
updateTimers();
}
void QmlProfilerTool::startTool(StartMode mode)
......
......@@ -76,8 +76,8 @@ public slots:
void setAppIsStopped();
void gotoSourceLocation(const QString &fileUrl, int lineNumber);
void updateTimer(qreal elapsedSeconds);
void correctTimer();
void updateTimers();
void profilerStateChanged(bool qmlActive, bool v8active);
void clearDisplay();
......@@ -85,6 +85,7 @@ public slots:
signals:
void setTimeLabel(const QString &);
void setStatusLabel(const QString &);
void fetchingData(bool);
void connectionFailed();
void cancelRun();
......
......@@ -146,10 +146,12 @@ TraceWindow::TraceWindow(QWidget *parent)
// Minimum height: 5 rows of 20 pixels + scrollbar of 50 pixels + 20 pixels margin
setMinimumHeight(170);
m_currentZoomLevel = 0;
m_profiledTime = 0;
}
TraceWindow::~TraceWindow()
{
disconnectClientSignals();
delete m_plugin.data();
delete m_v8plugin.data();
}
......@@ -258,24 +260,14 @@ QWidget *TraceWindow::createZoomToolbar()
void TraceWindow::reset(QDeclarativeDebugConnection *conn)
{
if (m_plugin)
disconnect(m_plugin.data(), SIGNAL(complete()), this, SLOT(qmlComplete()));
disconnectClientSignals();
delete m_plugin.data();
m_plugin = new QmlProfilerTraceClient(conn);
connect(m_plugin.data(), SIGNAL(complete()), this, SLOT(qmlComplete()));
connect(m_plugin.data(), SIGNAL(range(int,qint64,qint64,QStringList,QString,int)),
this, SIGNAL(range(int,qint64,qint64,QStringList,QString,int)));
if (m_v8plugin) {
disconnect(m_v8plugin.data(), SIGNAL(complete()), this, SLOT(v8Complete()));
disconnect(m_v8plugin.data(), SIGNAL(v8range(int,QString,QString,int,double,double)), this, SIGNAL(v8range(int,QString,QString,int,double,double)));
}
delete m_v8plugin.data();
m_v8plugin = new QV8ProfilerClient(conn);
connect(m_v8plugin.data(), SIGNAL(complete()), this, SLOT(v8Complete()));
connect(m_v8plugin.data(), SIGNAL(v8range(int,QString,QString,int,double,double)), this, SIGNAL(v8range(int,QString,QString,int,double,double)));
connect(m_plugin.data(), SIGNAL(traceFinished(qint64)), this, SIGNAL(traceFinished(qint64)));
connect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SIGNAL(traceStarted(qint64)));
connectClientSignals();
m_mainView->rootContext()->setContextProperty("connection", m_plugin.data());
m_mainView->rootContext()->setContextProperty("zoomControl", m_zoomControl.data());
......@@ -311,6 +303,40 @@ void TraceWindow::reset(QDeclarativeDebugConnection *conn)
m_qmlDataReady = false;
}
void TraceWindow::connectClientSignals()
{
if (m_plugin) {
connect(m_plugin.data(), SIGNAL(complete()), this, SLOT(qmlComplete()));
connect(m_plugin.data(), SIGNAL(range(int,qint64,qint64,QStringList,QString,int)),
this, SIGNAL(range(int,qint64,qint64,QStringList,QString,int)));
connect(m_plugin.data(), SIGNAL(traceFinished(qint64)), this, SIGNAL(traceFinished(qint64)));
connect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SIGNAL(traceStarted(qint64)));
connect(m_plugin.data(), SIGNAL(enabledChanged()), this, SLOT(updateProfilerState()));
}
if (m_v8plugin) {
connect(m_v8plugin.data(), SIGNAL(complete()), this, SLOT(v8Complete()));
connect(m_v8plugin.data(), SIGNAL(v8range(int,QString,QString,int,double,double)), this, SIGNAL(v8range(int,QString,QString,int,double,double)));
connect(m_v8plugin.data(), SIGNAL(enabledChanged()), this, SLOT(updateProfilerState()));
}
}
void TraceWindow::disconnectClientSignals()
{
if (m_plugin) {
disconnect(m_plugin.data(), SIGNAL(complete()), this, SLOT(qmlComplete()));
disconnect(m_plugin.data(), SIGNAL(range(int,qint64,qint64,QStringList,QString,int)),
this, SIGNAL(range(int,qint64,qint64,QStringList,QString,int)));
disconnect(m_plugin.data(), SIGNAL(traceFinished(qint64)), this, SIGNAL(traceFinished(qint64)));
disconnect(m_plugin.data(), SIGNAL(traceStarted(qint64)), this, SIGNAL(traceStarted(qint64)));
disconnect(m_plugin.data(), SIGNAL(enabledChanged()), this, SLOT(updateProfilerState()));
}
if (m_v8plugin) {
disconnect(m_v8plugin.data(), SIGNAL(complete()), this, SLOT(v8Complete()));
disconnect(m_v8plugin.data(), SIGNAL(v8range(int,QString,QString,int,double,double)), this, SIGNAL(v8range(int,QString,QString,int,double,double)));
disconnect(m_v8plugin.data(), SIGNAL(enabledChanged()), this, SLOT(updateProfilerState()));
}
}
QmlProfilerEventList *TraceWindow::getEventList() const
{
return m_eventList;
......@@ -334,7 +360,12 @@ void TraceWindow::updateCursorPosition()
void TraceWindow::updateTimer()
{
emit timeChanged(m_mainView->rootObject()->property("elapsedTime").toDouble());
m_profiledTime = m_mainView->rootObject()->property("elapsedTime").toDouble();
}
double TraceWindow::profiledTime() const
{
return m_profiledTime;
}
void TraceWindow::clearDisplay()
......@@ -347,6 +378,7 @@ void TraceWindow::clearDisplay()
m_v8plugin.data()->clearData();
m_zoomControl.data()->setRange(0,0);
m_profiledTime = 0;
emit internalClearDisplay();
}
......@@ -513,5 +545,17 @@ void TraceWindow::selectNextEvent(int eventId)
emit selectNextEventInDisplay(QVariant(eventId));
}
void TraceWindow::updateProfilerState()
{
bool qmlActive = false;
bool v8Active = false;
if (m_plugin)
qmlActive = m_plugin.data()->isEnabled();
if (m_v8plugin)
v8Active = m_v8plugin.data()->isEnabled();
emit profilerStateChanged(qmlActive, v8Active);
}
} // namespace Internal
} // namespace QmlProfiler
......@@ -107,6 +107,7 @@ public:
bool hasValidSelection() const;
qint64 selectionStart() const;
qint64 selectionEnd() const;
double profiledTime() const;
public slots:
void updateCursorPosition();
......@@ -124,11 +125,12 @@ public slots:
void qmlComplete();
void v8Complete();
void selectNextEvent(int eventId);
void updateProfilerState();
signals:
void viewUpdated();
void profilerStateChanged(bool qmlActive, bool v8active);
void gotoSourceLocation(const QString &fileUrl, int lineNumber);
void timeChanged(qreal newTime);
void range(int type, qint64 startTime, qint64 length, const QStringList &data, const QString &fileName, int line);
void v8range(int depth,const QString &function,const QString &filename,
int lineNumber, double totalTime, double selfTime);
......@@ -154,6 +156,8 @@ private:
void contextMenuEvent(QContextMenuEvent *);
QWidget *createToolbar();
QWidget *createZoomToolbar();
void connectClientSignals();
void disconnectClientSignals();
protected: