aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qmlprofiler/qmlprofilerclient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmlprofiler/qmlprofilerclient.cpp')
-rw-r--r--tools/qmlprofiler/qmlprofilerclient.cpp400
1 files changed, 126 insertions, 274 deletions
diff --git a/tools/qmlprofiler/qmlprofilerclient.cpp b/tools/qmlprofiler/qmlprofilerclient.cpp
index b4768e6934..217942244f 100644
--- a/tools/qmlprofiler/qmlprofilerclient.cpp
+++ b/tools/qmlprofiler/qmlprofilerclient.cpp
@@ -1,348 +1,200 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmlprofilerclient.h"
+#include "qmlprofilerdata.h"
+
+#include <private/qqmlprofilerclient_p_p.h>
#include <QtCore/QStack>
#include <QtCore/QStringList>
-#include <QtCore/QDataStream>
#include <limits>
-ProfilerClient::ProfilerClient(const QString &clientName,
- QQmlDebugConnection *client)
- : QQmlDebugClient(clientName, client),
- m_enabled(false)
-{
-}
-
-ProfilerClient::~ProfilerClient()
-{
-}
-
-void ProfilerClient::clearData()
-{
- emit cleared();
-}
-
-bool ProfilerClient::isEnabled() const
-{
- return m_enabled;
-}
-
-void ProfilerClient::stateChanged(State status)
-{
- if ((m_enabled && status != Enabled) ||
- (!m_enabled && status == Enabled))
- emit enabledChanged();
-
- m_enabled = status == Enabled;
-
-}
-
-class QmlProfilerClientPrivate
+class QmlProfilerClientPrivate : public QQmlProfilerClientPrivate
{
+ Q_DECLARE_PUBLIC(QmlProfilerClient)
public:
- QmlProfilerClientPrivate()
- : inProgressRanges(0) , features(std::numeric_limits<quint64>::max())
- {
- ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
- }
+ QmlProfilerClientPrivate(QQmlDebugConnection *connection, QmlProfilerData *data);
+
+ QmlProfilerData *data;
qint64 inProgressRanges;
QStack<qint64> rangeStartTimes[QQmlProfilerDefinitions::MaximumRangeType];
QStack<QStringList> rangeDatas[QQmlProfilerDefinitions::MaximumRangeType];
- QStack<QmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType];
- QStack<QQmlProfilerDefinitions::BindingType> bindingTypes;
+ QStack<QQmlEventLocation> rangeLocations[QQmlProfilerDefinitions::MaximumRangeType];
int rangeCount[QQmlProfilerDefinitions::MaximumRangeType];
- quint64 features;
+ bool enabled;
};
-QmlProfilerClient::QmlProfilerClient(
- QQmlDebugConnection *client)
- : ProfilerClient(QStringLiteral("CanvasFrameRate"), client),
- d(new QmlProfilerClientPrivate)
+QmlProfilerClientPrivate::QmlProfilerClientPrivate(QQmlDebugConnection *connection,
+ QmlProfilerData *data) :
+ QQmlProfilerClientPrivate(connection), data(data), inProgressRanges(0), enabled(false)
{
+ ::memset(rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
}
-QmlProfilerClient::~QmlProfilerClient()
+QmlProfilerClient::QmlProfilerClient(QQmlDebugConnection *connection, QmlProfilerData *data) :
+ QQmlProfilerClient(*(new QmlProfilerClientPrivate(connection, data)))
{
- delete d;
}
-void QmlProfilerClient::setFeatures(quint64 features)
+void QmlProfilerClient::clearPendingData()
{
- d->features = features;
+ Q_D(QmlProfilerClient);
+ for (int i = 0; i < QQmlProfilerDefinitions::MaximumRangeType; ++i) {
+ d->rangeCount[i] = 0;
+ d->rangeDatas[i].clear();
+ d->rangeLocations[i].clear();
+ }
}
-void QmlProfilerClient::clearData()
+void QmlProfilerClient::stateChanged(State state)
{
- ::memset(d->rangeCount, 0, QQmlProfilerDefinitions::MaximumRangeType * sizeof(int));
- d->bindingTypes.clear();
- ProfilerClient::clearData();
+ Q_D(QmlProfilerClient);
+ if ((d->enabled && state != Enabled) || (!d->enabled && state == Enabled)) {
+ d->enabled = (state == Enabled);
+ emit enabledChanged(d->enabled);
+ }
}
-void QmlProfilerClient::sendRecordingStatus(bool record)
+void QmlProfilerClient::traceStarted(qint64 time, int engineId)
{
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- stream.setVersion(QDataStream::Qt_4_7);
- stream << record << -1 << d->features;
- sendMessage(ba);
+ Q_UNUSED(engineId);
+ Q_D(QmlProfilerClient);
+ d->data->setTraceStartTime(time);
+ emit recordingStarted();
}
-inline QQmlProfilerDefinitions::ProfileFeature featureFromRangeType(
- QQmlProfilerDefinitions::RangeType range)
+void QmlProfilerClient::traceFinished(qint64 time, int engineId)
{
- switch (range) {
- case QQmlProfilerDefinitions::Painting:
- return QQmlProfilerDefinitions::ProfilePainting;
- case QQmlProfilerDefinitions::Compiling:
- return QQmlProfilerDefinitions::ProfileCompiling;
- case QQmlProfilerDefinitions::Creating:
- return QQmlProfilerDefinitions::ProfileCreating;
- case QQmlProfilerDefinitions::Binding:
- return QQmlProfilerDefinitions::ProfileBinding;
- case QQmlProfilerDefinitions::HandlingSignal:
- return QQmlProfilerDefinitions::ProfileHandlingSignal;
- case QQmlProfilerDefinitions::Javascript:
- return QQmlProfilerDefinitions::ProfileJavaScript;
- default:
- return QQmlProfilerDefinitions::MaximumProfileFeature;
- }
+ Q_UNUSED(engineId);
+ Q_D(QmlProfilerClient);
+ d->data->setTraceEndTime(time);
}
-void QmlProfilerClient::messageReceived(const QByteArray &data)
+void QmlProfilerClient::rangeStart(QQmlProfilerDefinitions::RangeType type, qint64 startTime)
{
- QByteArray rwData = data;
- QDataStream stream(&rwData, QIODevice::ReadOnly);
- stream.setVersion(QDataStream::Qt_4_7);
+ Q_D(QmlProfilerClient);
+ d->rangeStartTimes[type].push(startTime);
+ d->inProgressRanges |= (static_cast<qint64>(1) << type);
+ ++d->rangeCount[type];
+}
- // Force all the 1 << <FLAG> expressions to be done in 64 bit, to silence some warnings
- const quint64 one = static_cast<quint64>(1);
+void QmlProfilerClient::rangeData(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QString &data)
+{
+ Q_UNUSED(time);
+ Q_D(QmlProfilerClient);
+ int count = d->rangeCount[type];
+ if (count > 0) {
+ while (d->rangeDatas[type].count() < count)
+ d->rangeDatas[type].push(QStringList());
+ d->rangeDatas[type][count - 1] << data;
+ }
+}
- qint64 time;
- int messageType;
+void QmlProfilerClient::rangeLocation(QQmlProfilerDefinitions::RangeType type, qint64 time,
+ const QQmlEventLocation &location)
+{
+ Q_UNUSED(time);
+ Q_D(QmlProfilerClient);
+ if (d->rangeCount[type] > 0)
+ d->rangeLocations[type].push(location);
+}
- stream >> time >> messageType;
+void QmlProfilerClient::rangeEnd(QQmlProfilerDefinitions::RangeType type, qint64 endTime)
+{
+ Q_D(QmlProfilerClient);
- if (messageType >= QQmlProfilerDefinitions::MaximumMessage)
+ if (d->rangeCount[type] == 0) {
+ emit error(tr("Spurious range end detected."));
return;
+ }
- if (messageType == QQmlProfilerDefinitions::Event) {
- int event;
- stream >> event;
-
- if (event == QQmlProfilerDefinitions::EndTrace) {
- emit this->traceFinished(time);
- } else if (event == QQmlProfilerDefinitions::AnimationFrame) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileAnimations))
- return;
- int frameRate, animationCount;
- int threadId = 0;
- stream >> frameRate >> animationCount;
- if (!stream.atEnd())
- stream >> threadId;
- emit this->frame(time, frameRate, animationCount, threadId);
- } else if (event == QQmlProfilerDefinitions::StartTrace) {
- emit this->traceStarted(time);
- } else if (event == QQmlProfilerDefinitions::Key ||
- event == QQmlProfilerDefinitions::Mouse) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileInputEvents))
- return;
- emit this->inputEvent((QQmlProfilerDefinitions::EventType)event, time);
- }
- } else if (messageType == QQmlProfilerDefinitions::Complete) {
- emit complete();
- } else if (messageType == QQmlProfilerDefinitions::SceneGraphFrame) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileSceneGraph))
- return;
- int sgEventType;
- int count = 0;
- qint64 params[5];
-
- stream >> sgEventType;
- while (!stream.atEnd()) {
- stream >> params[count++];
- }
- while (count<5)
- params[count++] = 0;
- emit sceneGraphFrame((QQmlProfilerDefinitions::SceneGraphFrameType)sgEventType, time,
- params[0], params[1], params[2], params[3], params[4]);
- } else if (messageType == QQmlProfilerDefinitions::PixmapCacheEvent) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfilePixmapCache))
- return;
- int pixEvTy, width = 0, height = 0, refcount = 0;
- QString pixUrl;
- stream >> pixEvTy >> pixUrl;
- if (pixEvTy == (int)QQmlProfilerDefinitions::PixmapReferenceCountChanged ||
- pixEvTy == (int)QQmlProfilerDefinitions::PixmapCacheCountChanged) {
- stream >> refcount;
- } else if (pixEvTy == (int)QQmlProfilerDefinitions::PixmapSizeKnown) {
- stream >> width >> height;
- refcount = 1;
- }
- emit pixmapCache((QQmlProfilerDefinitions::PixmapEventType)pixEvTy, time,
- QmlEventLocation(pixUrl,0,0), width, height, refcount);
- } else if (messageType == QQmlProfilerDefinitions::MemoryAllocation) {
- if (!(d->features & one << QQmlProfilerDefinitions::ProfileMemory))
- return;
- int type;
- qint64 delta;
- stream >> type >> delta;
- emit memoryAllocation((QQmlProfilerDefinitions::MemoryType)type, time, delta);
- } else {
- int range;
- stream >> range;
-
- if (range >= QQmlProfilerDefinitions::MaximumRangeType)
- return;
-
- if (!(d->features & one << featureFromRangeType(
- static_cast<QQmlProfilerDefinitions::RangeType>(range))))
- return;
-
- if (messageType == QQmlProfilerDefinitions::RangeStart) {
- d->rangeStartTimes[range].push(time);
- d->inProgressRanges |= (static_cast<qint64>(1) << range);
- ++d->rangeCount[range];
-
- // read binding type
- if (range == (int)QQmlProfilerDefinitions::Binding) {
- int bindingType = (int)QQmlProfilerDefinitions::QmlBinding;
- if (!stream.atEnd())
- stream >> bindingType;
- d->bindingTypes.push((QQmlProfilerDefinitions::BindingType)bindingType);
- }
- } else if (messageType == QQmlProfilerDefinitions::RangeData) {
- QString data;
- stream >> data;
-
- int count = d->rangeCount[range];
- if (count > 0) {
- while (d->rangeDatas[range].count() < count)
- d->rangeDatas[range].push(QStringList());
- d->rangeDatas[range][count-1] << data;
- }
-
- } else if (messageType == QQmlProfilerDefinitions::RangeLocation) {
- QString fileName;
- int line;
- int column = -1;
- stream >> fileName >> line;
-
- if (!stream.atEnd())
- stream >> column;
-
- if (d->rangeCount[range] > 0) {
- d->rangeLocations[range].push(QmlEventLocation(fileName, line,
- column));
- }
- } else {
- if (d->rangeCount[range] > 0) {
- --d->rangeCount[range];
- if (d->inProgressRanges & (static_cast<qint64>(1) << range))
- d->inProgressRanges &= ~(static_cast<qint64>(1) << range);
-
- QStringList data = d->rangeDatas[range].count() ?
- d->rangeDatas[range].pop() : QStringList();
- QmlEventLocation location = d->rangeLocations[range].count() ?
- d->rangeLocations[range].pop() : QmlEventLocation();
-
- qint64 startTime = d->rangeStartTimes[range].pop();
- QQmlProfilerDefinitions::BindingType bindingType =
- QQmlProfilerDefinitions::QmlBinding;
- if (range == (int)QQmlProfilerDefinitions::Binding)
- bindingType = d->bindingTypes.pop();
- emit this->range((QQmlProfilerDefinitions::RangeType)range,
- bindingType, startTime, time - startTime, data, location);
- if (d->rangeCount[range] == 0) {
- int count = d->rangeDatas[range].count() +
- d->rangeStartTimes[range].count() +
- d->rangeLocations[range].count();
- if (count != 0)
- qWarning() << "incorrectly nested data";
- }
- }
- }
+ --d->rangeCount[type];
+ if (d->inProgressRanges & (static_cast<qint64>(1) << type))
+ d->inProgressRanges &= ~(static_cast<qint64>(1) << type);
+ QStringList data = d->rangeDatas[type].count() ? d->rangeDatas[type].pop() : QStringList();
+ QQmlEventLocation location = d->rangeLocations[type].count() ? d->rangeLocations[type].pop() :
+ QQmlEventLocation();
+ qint64 startTime = d->rangeStartTimes[type].pop();
+
+ if (d->rangeCount[type] == 0 && d->rangeDatas[type].count() + d->rangeStartTimes[type].count()
+ + d->rangeLocations[type].count() != 0) {
+ emit error(tr("Incorrectly nested range data"));
+ return;
}
+
+ d->data->addQmlEvent(type, QQmlProfilerDefinitions::QmlBinding, startTime, endTime - startTime,
+ data, location);
}
-V8ProfilerClient::V8ProfilerClient(QQmlDebugConnection *client)
- : ProfilerClient(QStringLiteral("V8Profiler"), client)
+void QmlProfilerClient::animationFrame(qint64 time, int frameRate, int animationCount, int threadId)
{
+ Q_D(QmlProfilerClient);
+ d->data->addFrameEvent(time, frameRate, animationCount, threadId);
}
-V8ProfilerClient::~V8ProfilerClient()
+void QmlProfilerClient::sceneGraphEvent(QQmlProfilerDefinitions::SceneGraphFrameType type,
+ qint64 time, qint64 numericData1, qint64 numericData2,
+ qint64 numericData3, qint64 numericData4,
+ qint64 numericData5)
{
+ Q_D(QmlProfilerClient);
+ d->data->addSceneGraphFrameEvent(type, time, numericData1, numericData2, numericData3,
+ numericData4, numericData5);
}
-void V8ProfilerClient::sendRecordingStatus(bool record)
+void QmlProfilerClient::pixmapCacheEvent(QQmlProfilerDefinitions::PixmapEventType type, qint64 time,
+ const QString &url, int numericData1, int numericData2)
{
- QByteArray ba;
- QDataStream stream(&ba, QIODevice::WriteOnly);
- QByteArray cmd("V8PROFILER");
- QByteArray option(record ? "start" : "stop");
- QByteArray title("");
-
- stream << cmd << option << title;
- sendMessage(ba);
+ Q_D(QmlProfilerClient);
+ d->data->addPixmapCacheEvent(type, time, url, numericData1, numericData2);
}
-void V8ProfilerClient::messageReceived(const QByteArray &data)
+void QmlProfilerClient::memoryAllocation(QQmlProfilerDefinitions::MemoryType type, qint64 time,
+ qint64 amount)
{
- QByteArray rwData = data;
- QDataStream stream(&rwData, QIODevice::ReadOnly);
-
- int messageType;
-
- stream >> messageType;
-
- if (messageType == V8Complete) {
- emit complete();
- } else if (messageType == V8Entry) {
- QString filename;
- QString function;
- int lineNumber;
- double totalTime;
- double selfTime;
- int depth;
+ Q_D(QmlProfilerClient);
+ d->data->addMemoryEvent(type, time, amount);
+}
- stream >> filename >> function >> lineNumber >> totalTime >>
- selfTime >> depth;
- emit this->range(depth, function, filename, lineNumber, totalTime,
- selfTime);
- }
+void QmlProfilerClient::inputEvent(QQmlProfilerDefinitions::InputEventType type, qint64 time,
+ int a, int b)
+{
+ Q_D(QmlProfilerClient);
+ d->data->addInputEvent(type, time, a, b);
}
+void QmlProfilerClient::complete()
+{
+ Q_D(QmlProfilerClient);
+ d->data->complete();
+}