diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index c99254c5d63..1aa41fbe830 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -29,7 +29,8 @@ SOURCES += \ codaqmlprofilerrunner.cpp \ remotelinuxqmlprofilerrunner.cpp \ qmlprofilercalleeview.cpp \ - qmlprofilercallerview.cpp + qmlprofilercallerview.cpp \ + qmlprofilertraceclient.cpp HEADERS += \ qmlprofilerconstants.h \ @@ -47,7 +48,8 @@ HEADERS += \ codaqmlprofilerrunner.h \ remotelinuxqmlprofilerrunner.h \ qmlprofilercalleeview.h \ - qmlprofilercallerview.h + qmlprofilercallerview.h \ + qmlprofilertraceclient.h RESOURCES += \ qml/qml.qrc diff --git a/src/plugins/qmlprofiler/qmlprofilerengine.cpp b/src/plugins/qmlprofiler/qmlprofilerengine.cpp index b99661a2460..8d0f1ec981c 100644 --- a/src/plugins/qmlprofiler/qmlprofilerengine.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerengine.cpp @@ -33,35 +33,22 @@ #include "qmlprofilerengine.h" -#include "qmlprofilerplugin.h" -#include "qmlprofilertool.h" -#include "localqmlprofilerrunner.h" -#include "codaqmlprofilerrunner.h" -#include "remotelinuxqmlprofilerrunner.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "timelineview.h" -#include "tracewindow.h" - -#include -#include -#include - #include "canvas/qdeclarativecanvas_p.h" #include "canvas/qdeclarativecontext2d_p.h" #include "canvas/qdeclarativetiledcanvas_p.h" +#include "codaqmlprofilerrunner.h" +#include "localqmlprofilerrunner.h" +#include "remotelinuxqmlprofilerrunner.h" +#include "qmlprofilerplugin.h" +#include "qmlprofilertool.h" +#include +#include +#include +#include + +#include +#include namespace QmlProfiler { namespace Internal { diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 13f27f8b75d..3b582f3f399 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -82,6 +82,7 @@ using namespace Analyzer; using namespace QmlProfiler::Internal; +using namespace QmlJsDebugClient; class QmlProfilerTool::QmlProfilerToolPrivate { diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp new file mode 100644 index 00000000000..cfc69dad55e --- /dev/null +++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp @@ -0,0 +1,167 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** No Commercial Usage +** +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "qmlprofilertraceclient.h" + +using namespace QmlProfiler::Internal; +using namespace QmlJsDebugClient; + +static const int GAP_TIME = 150; + +QmlProfilerTraceClient::QmlProfilerTraceClient(QDeclarativeDebugConnection *client) + : QDeclarativeDebugClient(QLatin1String("CanvasFrameRate"), client), + m_inProgressRanges(0), m_maximumTime(0), m_recording(false), m_nestingLevel(0) +{ + ::memset(m_rangeCount, 0, MaximumRangeType * sizeof(int)); + ::memset(m_nestingInType, 0, MaximumRangeType * sizeof(int)); +} + +void QmlProfilerTraceClient::clearView() +{ + ::memset(m_rangeCount, 0, MaximumRangeType * sizeof(int)); + ::memset(m_nestingInType, 0, MaximumRangeType * sizeof(int)); + m_nestingLevel = 0; + emit clear(); +} + +void QmlProfilerTraceClient::setRecording(bool v) +{ + if (v == m_recording) + return; + + if (status() == Enabled) { + QByteArray ba; + QDataStream stream(&ba, QIODevice::WriteOnly); + stream << v; + sendMessage(ba); + } + + m_recording = v; + emit recordingChanged(v); +} + +void QmlProfilerTraceClient::statusChanged(Status status) +{ + if (status == Enabled) { + m_recording = !m_recording; + setRecording(!m_recording); + emit enabled(); + } +} + +void QmlProfilerTraceClient::messageReceived(const QByteArray &data) +{ + QByteArray rwData = data; + QDataStream stream(&rwData, QIODevice::ReadOnly); + + qint64 time; + int messageType; + + stream >> time >> messageType; + +// qDebug() << __FUNCTION__ << messageType; + + if (messageType >= MaximumMessage) + return; + + if (time > (m_maximumTime + GAP_TIME) && 0 == m_inProgressRanges) + emit gap(time); + + if (messageType == Event) { + int event; + stream >> event; + + if (event < MaximumEventType) { + emit this->event((EventType)event, time); + m_maximumTime = qMax(time, m_maximumTime); + } + } else if (messageType == Complete) { + emit complete(); + } else { + int range; + stream >> range; + + if (range >= MaximumRangeType) + return; + + if (messageType == RangeStart) { + m_rangeStartTimes[range].push(time); + m_inProgressRanges |= (static_cast(1) << range); + ++m_rangeCount[range]; + ++m_nestingLevel; + ++m_nestingInType[range]; + } else if (messageType == RangeData) { + QString data; + stream >> data; + + int count = m_rangeCount[range]; + if (count > 0) { + while (m_rangeDatas[range].count() < count) + m_rangeDatas[range].push(QStringList()); + m_rangeDatas[range][count-1] << data; + } + + } else if (messageType == RangeLocation) { + QString fileName; + int line; + stream >> fileName >> line; + + if (m_rangeCount[range] > 0) { + m_rangeLocations[range].push(Location(fileName, line)); + } + } else { + if (m_rangeCount[range] > 0) { + --m_rangeCount[range]; + if (m_inProgressRanges & (static_cast(1) << range)) + m_inProgressRanges &= ~(static_cast(1) << range); + + m_maximumTime = qMax(time, m_maximumTime); + QStringList data = m_rangeDatas[range].count() ? m_rangeDatas[range].pop() : QStringList(); + Location location = m_rangeLocations[range].count() ? m_rangeLocations[range].pop() : Location(); + + qint64 startTime = m_rangeStartTimes[range].pop(); + emit this->range((RangeType)range, m_nestingLevel, m_nestingInType[range], startTime, + time - startTime, data, location.fileName, location.line); + --m_nestingLevel; + --m_nestingInType[range]; + if (m_rangeCount[range] == 0) { + int count = m_rangeDatas[range].count() + + m_rangeStartTimes[range].count() + + m_rangeLocations[range].count(); + if (count != 0) + qWarning() << "incorrectly nested data"; + } + } + } + } +} diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.h b/src/plugins/qmlprofiler/qmlprofilertraceclient.h new file mode 100644 index 00000000000..207f63e9d6a --- /dev/null +++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.h @@ -0,0 +1,128 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** No Commercial Usage +** +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef QMLPROFILERTRACECLIENT_H +#define QMLPROFILERTRACECLIENT_H + +#include +#include +#include + +namespace QmlProfiler { +namespace Internal { + +struct Location +{ + Location() : line(-1) {} + Location(const QString &file, int lineNumber) : fileName(file), line(lineNumber) {} + QString fileName; + int line; +}; + +class QmlProfilerTraceClient : public QmlJsDebugClient::QDeclarativeDebugClient +{ + Q_OBJECT + Q_PROPERTY(bool recording READ isRecording WRITE setRecording NOTIFY recordingChanged) + +public: + QmlProfilerTraceClient(QmlJsDebugClient::QDeclarativeDebugConnection *client); + + enum EventType { + FramePaint, + Mouse, + Key, + + MaximumEventType + }; + + enum Message { + Event, + RangeStart, + RangeData, + RangeLocation, + RangeEnd, + Complete, + + MaximumMessage + }; + + enum RangeType { + Painting, + Compiling, + Creating, + Binding, + HandlingSignal, + + MaximumRangeType + }; + + bool isRecording() const { return m_recording; } + +public slots: + void setRecording(bool); + void clearView(); + +signals: + void complete(); + void gap(qint64); + void event(int event, qint64 time); + void range(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length, + const QStringList &data, const QString &fileName, int line); + + void sample(int, int, int, bool); + + void recordingChanged(bool arg); + + void enabled(); + void clear(); + +protected: + virtual void statusChanged(Status); + virtual void messageReceived(const QByteArray &); + +private: + qint64 m_inProgressRanges; + QStack m_rangeStartTimes[MaximumRangeType]; + QStack m_rangeDatas[MaximumRangeType]; + QStack m_rangeLocations[MaximumRangeType]; + int m_rangeCount[MaximumRangeType]; + qint64 m_maximumTime; + bool m_recording; + int m_nestingLevel; + int m_nestingInType[MaximumRangeType]; +}; + +} // namespace Internal +} // namespace QmlProfiler + +#endif // QMLPROFILERTRACECLIENT_H diff --git a/src/plugins/qmlprofiler/tracewindow.cpp b/src/plugins/qmlprofiler/tracewindow.cpp index 817f946ad9a..dda54f327b0 100644 --- a/src/plugins/qmlprofiler/tracewindow.cpp +++ b/src/plugins/qmlprofiler/tracewindow.cpp @@ -34,243 +34,24 @@ #include "tracewindow.h" #include "qmlprofilerplugin.h" +#include "qmlprofilertraceclient.h" + +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -static const int GAP_TIME = 150; - -using QmlJsDebugClient::QDeclarativeDebugClient; +#include +#include +#include +#include +#include namespace QmlProfiler { namespace Internal { -struct Location -{ - Location() : line(-1) {} - Location(const QString &file, int lineNumber) : fileName(file), line(lineNumber) {} - QString fileName; - int line; -}; - -class TracePlugin : public QDeclarativeDebugClient -{ - Q_OBJECT - Q_PROPERTY(bool recording READ isRecording WRITE setRecording NOTIFY recordingChanged) - -public: - TracePlugin(QDeclarativeDebugConnection *client); - - enum EventType { - FramePaint, - Mouse, - Key, - - MaximumEventType - }; - - enum Message { - Event, - RangeStart, - RangeData, - RangeLocation, - RangeEnd, - Complete, - - MaximumMessage - }; - - enum RangeType { - Painting, - Compiling, - Creating, - Binding, - HandlingSignal, - - MaximumRangeType - }; - - bool isRecording() const { return m_recording; } - -public slots: - void setRecording(bool); - void clearView(); - -signals: - void complete(); - void gap(qint64); - void event(int event, qint64 time); - void range(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length, const QStringList &data, const QString &fileName, int line); - - void sample(int, int, int, bool); - - void recordingChanged(bool arg); - - void enabled(); - void clear(); - -protected: - virtual void statusChanged(Status); - virtual void messageReceived(const QByteArray &); - -private: - qint64 m_inProgressRanges; - QStack m_rangeStartTimes[MaximumRangeType]; - QStack m_rangeDatas[MaximumRangeType]; - QStack m_rangeLocations[MaximumRangeType]; - int m_rangeCount[MaximumRangeType]; - qint64 m_maximumTime; - bool m_recording; - int m_nestingLevel; - int m_nestingInType[MaximumRangeType]; -}; - -TracePlugin::TracePlugin(QDeclarativeDebugConnection *client) - : QDeclarativeDebugClient(QLatin1String("CanvasFrameRate"), client), - m_inProgressRanges(0), m_maximumTime(0), m_recording(false), m_nestingLevel(0) -{ - ::memset(m_rangeCount, 0, MaximumRangeType * sizeof(int)); - ::memset(m_nestingInType, 0, MaximumRangeType * sizeof(int)); -} - -void TracePlugin::clearView() -{ - ::memset(m_rangeCount, 0, MaximumRangeType * sizeof(int)); - ::memset(m_nestingInType, 0, MaximumRangeType * sizeof(int)); - m_nestingLevel = 0; - emit clear(); -} - -void TracePlugin::setRecording(bool v) -{ - if (v == m_recording) - return; - - if (status() == Enabled) { - QByteArray ba; - QDataStream stream(&ba, QIODevice::WriteOnly); - stream << v; - sendMessage(ba); - } - - m_recording = v; - emit recordingChanged(v); -} - -void TracePlugin::statusChanged(Status status) -{ - if (status == Enabled) { - m_recording = !m_recording; - setRecording(!m_recording); - emit enabled(); - } -} - -void TracePlugin::messageReceived(const QByteArray &data) -{ - QByteArray rwData = data; - QDataStream stream(&rwData, QIODevice::ReadOnly); - - qint64 time; - int messageType; - - stream >> time >> messageType; - -// qDebug() << __FUNCTION__ << messageType; - - if (messageType >= MaximumMessage) - return; - - if (time > (m_maximumTime + GAP_TIME) && 0 == m_inProgressRanges) - emit gap(time); - - if (messageType == Event) { - int event; - stream >> event; - - if (event < MaximumEventType) { - emit this->event((EventType)event, time); - m_maximumTime = qMax(time, m_maximumTime); - } - } else if (messageType == Complete) { - emit complete(); - } else { - int range; - stream >> range; - - if (range >= MaximumRangeType) - return; - - if (messageType == RangeStart) { - m_rangeStartTimes[range].push(time); - m_inProgressRanges |= (static_cast(1) << range); - ++m_rangeCount[range]; - ++m_nestingLevel; - ++m_nestingInType[range]; - } else if (messageType == RangeData) { - QString data; - stream >> data; - - int count = m_rangeCount[range]; - if (count > 0) { - while (m_rangeDatas[range].count() < count) - m_rangeDatas[range].push(QStringList()); - m_rangeDatas[range][count-1] << data; - } - - } else if (messageType == RangeLocation) { - QString fileName; - int line; - stream >> fileName >> line; - - if (m_rangeCount[range] > 0) { - m_rangeLocations[range].push(Location(fileName, line)); - } - } else { - if (m_rangeCount[range] > 0) { - --m_rangeCount[range]; - if (m_inProgressRanges & (static_cast(1) << range)) - m_inProgressRanges &= ~(static_cast(1) << range); - - m_maximumTime = qMax(time, m_maximumTime); - QStringList data = m_rangeDatas[range].count() ? m_rangeDatas[range].pop() : QStringList(); - Location location = m_rangeLocations[range].count() ? m_rangeLocations[range].pop() : Location(); - - qint64 startTime = m_rangeStartTimes[range].pop(); - emit this->range((RangeType)range, m_nestingLevel, m_nestingInType[range], startTime, time - startTime, data, location.fileName, location.line); - --m_nestingLevel; - --m_nestingInType[range]; - if (m_rangeCount[range] == 0) { - int count = m_rangeDatas[range].count() + - m_rangeStartTimes[range].count() + - m_rangeLocations[range].count(); - if (count != 0) - qWarning() << "incorrectly nested data"; - } - } - } - } -} - TraceWindow::TraceWindow(QWidget *parent) : QWidget(parent) { - setObjectName(tr("QML Profiler")); + setObjectName("QML Profiler"); QVBoxLayout *groupLayout = new QVBoxLayout; groupLayout->setContentsMargins(0, 0, 0, 0); @@ -321,12 +102,12 @@ TraceWindow::~TraceWindow() delete m_plugin.data(); } -void TraceWindow::reset(QDeclarativeDebugConnection *conn) +void TraceWindow::reset(QmlJsDebugClient::QDeclarativeDebugConnection *conn) { if (m_plugin) disconnect(m_plugin.data(), SIGNAL(complete()), this, SIGNAL(viewUpdated())); delete m_plugin.data(); - m_plugin = new TracePlugin(conn); + m_plugin = new QmlProfilerTraceClient(conn); connect(m_plugin.data(), SIGNAL(complete()), this, SIGNAL(viewUpdated())); connect(m_plugin.data(), SIGNAL(range(int,int,int,qint64,qint64,QStringList,QString,int)), this, SIGNAL(range(int,int,int,qint64,qint64,QStringList,QString,int))); @@ -376,6 +157,3 @@ bool TraceWindow::isRecording() const } // namespace Internal } // namespace QmlProfiler - - -#include "tracewindow.moc" diff --git a/src/plugins/qmlprofiler/tracewindow.h b/src/plugins/qmlprofiler/tracewindow.h index 07e0f8606e2..f76fea15f7a 100644 --- a/src/plugins/qmlprofiler/tracewindow.h +++ b/src/plugins/qmlprofiler/tracewindow.h @@ -34,7 +34,7 @@ #ifndef TRACEWINDOW_H #define TRACEWINDOW_H -#include +#include "qmlprofilertraceclient.h" #include #include @@ -43,13 +43,9 @@ QT_BEGIN_NAMESPACE class QDeclarativeView; QT_END_NAMESPACE -using QmlJsDebugClient::QDeclarativeDebugConnection; - namespace QmlProfiler { namespace Internal { -class TracePlugin; - class TraceWindow : public QWidget { Q_OBJECT @@ -58,7 +54,7 @@ public: TraceWindow(QWidget *parent = 0); ~TraceWindow(); - void reset(QDeclarativeDebugConnection *conn); + void reset(QmlJsDebugClient::QDeclarativeDebugConnection *conn); void setRecording(bool recording); bool isRecording() const; @@ -82,7 +78,7 @@ signals: void zoomOut(); private: - QWeakPointer m_plugin; + QWeakPointer m_plugin; QSize m_sizeHint; QDeclarativeView *m_view;