diff --git a/src/libs/timeline/timeline.pro b/src/libs/timeline/timeline.pro index c40b9dc36ea..678f4e8ac3e 100644 --- a/src/libs/timeline/timeline.pro +++ b/src/libs/timeline/timeline.pro @@ -40,7 +40,9 @@ HEADERS += \ $$PWD/timelineoverviewrenderer_p.h \ $$PWD/timelineoverviewrenderer.h \ $$PWD/timelinetheme.h \ - $$PWD/timelineformattime.h + $$PWD/timelineformattime.h \ + $$PWD/traceevent.h \ + $$PWD/traceeventtype.h RESOURCES += \ $$PWD/qml/timeline.qrc diff --git a/src/libs/timeline/timeline.qbs b/src/libs/timeline/timeline.qbs index 1fc250a8a9d..8b000958dc0 100644 --- a/src/libs/timeline/timeline.qbs +++ b/src/libs/timeline/timeline.qbs @@ -30,7 +30,8 @@ Project { "timelinerenderstate.cpp", "timelinerenderstate.h", "timelinerenderstate_p.h", "timelineselectionrenderpass.cpp", "timelineselectionrenderpass.h", "timelinetheme.cpp", "timelinetheme.h", - "timelinezoomcontrol.cpp", "timelinezoomcontrol.h" + "timelinezoomcontrol.cpp", "timelinezoomcontrol.h", + "traceevent.h", "traceeventtype.h", ] } diff --git a/src/libs/timeline/traceevent.h b/src/libs/timeline/traceevent.h new file mode 100644 index 00000000000..c449d0d124c --- /dev/null +++ b/src/libs/timeline/traceevent.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** 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. +** +****************************************************************************/ + +#pragma once + +#include "timeline_global.h" + +#include +#include + +namespace Timeline { + +class TIMELINE_EXPORT TraceEvent +{ +public: + TraceEvent(qint64 timestamp = -1, qint32 typeIndex = -1) + : m_timestamp(timestamp), m_typeIndex(typeIndex) + {} + + qint64 timestamp() const { return m_timestamp; } + void setTimestamp(qint64 timestamp) { m_timestamp = timestamp; } + + qint32 typeIndex() const { return m_typeIndex; } + void setTypeIndex(qint32 typeIndex) { m_typeIndex = typeIndex; } + + bool isValid() const { return m_typeIndex != -1; } + +private: + qint64 m_timestamp; + qint32 m_typeIndex; +}; + +} // namespace Timeline + +Q_DECLARE_METATYPE(Timeline::TraceEvent) + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Timeline::TraceEvent, Q_MOVABLE_TYPE); +QT_END_NAMESPACE diff --git a/src/libs/timeline/traceeventtype.h b/src/libs/timeline/traceeventtype.h new file mode 100644 index 00000000000..d9c1434c592 --- /dev/null +++ b/src/libs/timeline/traceeventtype.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** 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 The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** 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. +** +****************************************************************************/ + +#pragma once + +#include "timeline_global.h" + +#include +#include +#include + +namespace Timeline { + +class TIMELINE_EXPORT TraceEventType +{ +public: + TraceEventType(quint8 feature = 255, const QString &displayName = QString()) + : m_displayName(displayName), m_feature(feature) + {} + + const QString &displayName() const { return m_displayName; } + void setDisplayName(const QString &displayName) { m_displayName = displayName; } + + quint8 feature() const { return m_feature; } + void setFeature(quint8 feature) { m_feature = feature; } + +private: + QString m_displayName; + quint8 m_feature; +}; + +} // namespace Timeline + +Q_DECLARE_METATYPE(Timeline::TraceEventType) + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(Timeline::TraceEventType, Q_MOVABLE_TYPE); +QT_END_NAMESPACE diff --git a/src/plugins/qmlprofiler/qmlevent.cpp b/src/plugins/qmlprofiler/qmlevent.cpp index 2d069337193..52028b7d455 100644 --- a/src/plugins/qmlprofiler/qmlevent.cpp +++ b/src/plugins/qmlprofiler/qmlevent.cpp @@ -29,20 +29,6 @@ namespace QmlProfiler { -bool operator==(const QmlEvent &event1, const QmlEvent &event2) -{ - if (event1.timestamp() != event2.timestamp() || event1.typeIndex() != event2.typeIndex()) - return false; - - // This is not particularly efficient, but we also don't need to do this very often. - return event1.numbers>() == event2.numbers>(); -} - -bool operator!=(const QmlEvent &event1, const QmlEvent &event2) -{ - return !(event1 == event2); -} - enum SerializationType { OneByte = 0, TwoByte = 1, @@ -100,8 +86,8 @@ QDataStream &operator>>(QDataStream &stream, QmlEvent &event) qint8 type; stream >> type; - event.m_timestamp = readNumber(stream, (type >> TimestampOffset) & TypeMask); - event.m_typeIndex = readNumber(stream, (type >> TypeIndexOffset) & TypeMask); + event.setTimestamp(readNumber(stream, (type >> TimestampOffset) & TypeMask)); + event.setTypeIndex(readNumber(stream, (type >> TypeIndexOffset) & TypeMask)); event.m_dataLength = readNumber(stream, (type >> DataLengthOffset) & TypeMask); quint8 bytesPerNumber = 1 << ((type >> DataOffset) & TypeMask); @@ -224,14 +210,14 @@ static inline void writeNumber(QDataStream &stream, Number number, qint8 type) QDataStream &operator<<(QDataStream &stream, const QmlEvent &event) { - qint8 type = minimumType(event.m_timestamp) << TimestampOffset; - type |= minimumType(event.m_typeIndex) << TypeIndexOffset; + qint8 type = minimumType(event.timestamp()) << TimestampOffset; + type |= minimumType(event.typeIndex()) << TypeIndexOffset; type |= minimumType(event.m_dataLength) << DataLengthOffset; type |= minimumType(event, event.m_dataLength, event.m_dataType) << DataOffset; stream << type; - writeNumber(stream, event.m_timestamp, (type >> TimestampOffset) & TypeMask); - writeNumber(stream, event.m_typeIndex, (type >> TypeIndexOffset) & TypeMask); + writeNumber(stream, event.timestamp(), (type >> TimestampOffset) & TypeMask); + writeNumber(stream, event.typeIndex(), (type >> TypeIndexOffset) & TypeMask); writeNumber(stream, event.m_dataLength, (type >> DataLengthOffset) & TypeMask); switch ((type >> DataOffset) & TypeMask) { diff --git a/src/plugins/qmlprofiler/qmlevent.h b/src/plugins/qmlprofiler/qmlevent.h index 5f17d202f4a..cd8c99c005a 100644 --- a/src/plugins/qmlprofiler/qmlevent.h +++ b/src/plugins/qmlprofiler/qmlevent.h @@ -26,6 +26,8 @@ #include "qmlprofilereventtypes.h" +#include + #include #include #include @@ -36,32 +38,31 @@ namespace QmlProfiler { -struct QmlEvent { - QmlEvent() : m_timestamp(-1), m_typeIndex(-1), m_dataType(Inline8Bit), m_dataLength(0) {} +struct QmlEvent : public Timeline::TraceEvent { + QmlEvent() : m_dataType(Inline8Bit), m_dataLength(0) {} template QmlEvent(qint64 timestamp, int typeIndex, std::initializer_list list) - : m_timestamp(timestamp), m_typeIndex(typeIndex) + : TraceEvent(timestamp, typeIndex) { assignNumbers, Number>(list); } QmlEvent(qint64 timestamp, int typeIndex, const QString &data) - : m_timestamp(timestamp), m_typeIndex(typeIndex) + : TraceEvent(timestamp, typeIndex) { assignNumbers(data.toUtf8()); } template QmlEvent(qint64 timestamp, int typeIndex, const QVector &data) - : m_timestamp(timestamp), m_typeIndex(typeIndex) + : TraceEvent(timestamp, typeIndex) { assignNumbers, Number>(data); } QmlEvent(const QmlEvent &other) - : m_timestamp(other.m_timestamp), m_typeIndex(other.m_typeIndex), - m_dataType(other.m_dataType), m_dataLength(other.m_dataLength) + : TraceEvent(other), m_dataType(other.m_dataType), m_dataLength(other.m_dataLength) { assignData(other); } @@ -76,8 +77,7 @@ struct QmlEvent { { if (this != &other) { clearPointer(); - m_timestamp = other.m_timestamp; - m_typeIndex = other.m_typeIndex; + TraceEvent::operator=(other); m_dataType = other.m_dataType; m_dataLength = other.m_dataLength; assignData(other); @@ -99,12 +99,6 @@ struct QmlEvent { clearPointer(); } - qint64 timestamp() const { return m_timestamp; } - void setTimestamp(qint64 timestamp) { m_timestamp = timestamp; } - - int typeIndex() const { return m_typeIndex; } - void setTypeIndex(int typeIndex) { m_typeIndex = typeIndex; } - template Number number(int i) const { @@ -203,11 +197,6 @@ struct QmlEvent { m_data.internal8bit[0] = stage; } - bool isValid() const - { - return m_timestamp != -1; - } - private: enum Type: quint16 { External = 1, @@ -221,7 +210,8 @@ private: External64Bit = Inline64Bit | External }; - qint64 m_timestamp; + Type m_dataType; + quint16 m_dataLength; static const int s_internalDataLength = 8; union { @@ -233,10 +223,6 @@ private: qint64 internal64bit[s_internalDataLength / 8]; } m_data; - qint32 m_typeIndex; - Type m_dataType; - quint16 m_dataLength; - void assignData(const QmlEvent &other) { if (m_dataType & External) { @@ -309,9 +295,6 @@ private: friend QDataStream &operator<<(QDataStream &stream, const QmlEvent &event); }; -bool operator==(const QmlEvent &event1, const QmlEvent &event2); -bool operator!=(const QmlEvent &event1, const QmlEvent &event2); - QDataStream &operator>>(QDataStream &stream, QmlEvent &event); QDataStream &operator<<(QDataStream &stream, const QmlEvent &event); diff --git a/src/plugins/qmlprofiler/qmleventtype.cpp b/src/plugins/qmlprofiler/qmleventtype.cpp index 0649379f857..c8cb6d2ae77 100644 --- a/src/plugins/qmlprofiler/qmleventtype.cpp +++ b/src/plugins/qmlprofiler/qmleventtype.cpp @@ -32,8 +32,10 @@ QDataStream &operator>>(QDataStream &stream, QmlEventType &type) { quint8 message; quint8 rangeType; - stream >> type.m_displayName >> type.m_data >> type.m_location >> message >> rangeType + QString displayName; + stream >> displayName >> type.m_data >> type.m_location >> message >> rangeType >> type.m_detailType; + type.setDisplayName(displayName); type.m_message = static_cast(message); type.m_rangeType = static_cast(rangeType); return stream; @@ -41,16 +43,16 @@ QDataStream &operator>>(QDataStream &stream, QmlEventType &type) QDataStream &operator<<(QDataStream &stream, const QmlEventType &type) { - return stream << type.m_displayName << type.m_data << type.m_location + return stream << type.displayName() << type.m_data << type.m_location << static_cast(type.m_message) << static_cast(type.m_rangeType) << type.m_detailType; } -ProfileFeature QmlEventType::feature() const +static ProfileFeature qmlFeatureFromType(Message message, RangeType rangeType, int detailType) { - switch (m_message) { + switch (message) { case Event: { - switch (m_detailType) { + switch (detailType) { case Mouse: case Key: return ProfileInputEvents; @@ -69,9 +71,18 @@ ProfileFeature QmlEventType::feature() const case DebugMessage: return ProfileDebugMessages; default: - return featureFromRangeType(m_rangeType); + return featureFromRangeType(rangeType); } } +QmlEventType::QmlEventType(Message message, RangeType rangeType, int detailType, + const QmlEventLocation &location, const QString &data, + const QString displayName) : + TraceEventType(qmlFeatureFromType(message, rangeType, detailType)), + m_data(data), m_location(location), m_message(message), + m_rangeType(rangeType), m_detailType(detailType) +{ + setDisplayName(displayName); +} } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmleventtype.h b/src/plugins/qmlprofiler/qmleventtype.h index 37a701a4e3c..20934ec6eb8 100644 --- a/src/plugins/qmlprofiler/qmleventtype.h +++ b/src/plugins/qmlprofiler/qmleventtype.h @@ -26,27 +26,24 @@ #include "qmleventlocation.h" #include "qmlprofilereventtypes.h" + +#include + #include #include #include namespace QmlProfiler { -class QmlEventType { +class QmlEventType : public Timeline::TraceEventType { public: QmlEventType(Message message = MaximumMessage, RangeType rangeType = MaximumRangeType, int detailType = -1, const QmlEventLocation &location = QmlEventLocation(), - const QString &data = QString(), const QString displayName = QString()) : - m_displayName(displayName), m_data(data), m_location(location), m_message(message), - m_rangeType(rangeType), m_detailType(detailType) - {} + const QString &data = QString(), const QString displayName = QString()); - void setDisplayName(const QString &displayName) { m_displayName = displayName; } void setData(const QString &data) { m_data = data; } void setLocation(const QmlEventLocation &location) { m_location = location; } - ProfileFeature feature() const; - QString displayName() const { return m_displayName; } QString data() const { return m_data; } QmlEventLocation location() const { return m_location; } Message message() const { return m_message; } @@ -57,7 +54,6 @@ private: friend QDataStream &operator>>(QDataStream &stream, QmlEventType &type); friend QDataStream &operator<<(QDataStream &stream, const QmlEventType &type); - QString m_displayName; QString m_data; QmlEventLocation m_location; Message m_message; @@ -68,25 +64,6 @@ private: QDataStream &operator>>(QDataStream &stream, QmlEventType &type); QDataStream &operator<<(QDataStream &stream, const QmlEventType &type); -inline uint qHash(const QmlEventType &type) -{ - return qHash(type.location()) - ^ (((type.message() << 12) & 0xf000) // 4 bits of message - | ((type.rangeType() << 24) & 0xf000000) // 4 bits of rangeType - | ((type.detailType() << 28) & 0xf0000000)); // 4 bits of detailType -} - -inline bool operator==(const QmlEventType &type1, const QmlEventType &type2) -{ - return type1.message() == type2.message() && type1.rangeType() == type2.rangeType() - && type1.detailType() == type2.detailType() && type1.location() == type2.location(); -} - -inline bool operator!=(const QmlEventType &type1, const QmlEventType &type2) -{ - return !(type1 == type2); -} - } // namespace QmlProfiler Q_DECLARE_METATYPE(QmlProfiler::QmlEventType) diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index 0a7bd0bf365..c6373f07c79 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -377,8 +377,10 @@ bool QmlProfilerModelManager::replayEvents(qint64 rangeStart, qint64 rangeEnd, void QmlProfilerModelManager::QmlProfilerModelManagerPrivate::dispatch(const QmlEvent &event, const QmlEventType &type) { - for (const EventLoader &loader : eventLoaders.value(type.feature())) + for (const EventLoader &loader : eventLoaders.value( + static_cast(type.feature()))) { loader(event, type); + } ++numLoadedEvents; } diff --git a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp index 15c6363ee16..ce81bd434e9 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceclient.cpp @@ -36,6 +36,25 @@ namespace QmlProfiler { +inline uint qHash(const QmlEventType &type) +{ + return qHash(type.location()) + ^ (((type.message() << 12) & 0xf000) // 4 bits of message + | ((type.rangeType() << 24) & 0xf000000) // 4 bits of rangeType + | ((type.detailType() << 28) & 0xf0000000)); // 4 bits of detailType +} + +inline bool operator==(const QmlEventType &type1, const QmlEventType &type2) +{ + return type1.message() == type2.message() && type1.rangeType() == type2.rangeType() + && type1.detailType() == type2.detailType() && type1.location() == type2.location(); +} + +inline bool operator!=(const QmlEventType &type1, const QmlEventType &type2) +{ + return !(type1 == type2); +} + class QmlProfilerTraceClientPrivate { public: QmlProfilerTraceClientPrivate(QmlProfilerTraceClient *q, @@ -53,7 +72,7 @@ public: } void sendRecordingStatus(int engineId); - bool updateFeatures(ProfileFeature feature); + bool updateFeatures(quint8 feature); int resolveType(const QmlTypedEvent &type); int resolveStackTop(); void forwardEvents(const QmlEvent &last); @@ -321,7 +340,7 @@ void QmlProfilerTraceClient::setFlushInterval(quint32 flushInterval) d->flushInterval = flushInterval; } -bool QmlProfilerTraceClientPrivate::updateFeatures(ProfileFeature feature) +bool QmlProfilerTraceClientPrivate::updateFeatures(quint8 feature) { quint64 flag = 1ULL << feature; if (!(requestedFeatures & flag)) diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp index 87f6e89e441..972b8c2f126 100644 --- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp @@ -400,7 +400,7 @@ void QmlProfilerFileReader::loadEventTypes(QXmlStreamReader &stream) QmlEventType type(messageAndRange.first, messageAndRange.second, detailType, QmlEventLocation(filename, line, column), data, displayName); m_eventTypes[typeIndex] = type; - ProfileFeature feature = type.feature(); + quint8 feature = type.feature(); if (feature != MaximumProfileFeature) m_loadedFeatures |= (1ULL << static_cast(feature)); } diff --git a/src/plugins/qmlprofiler/tests/qmlevent_test.cpp b/src/plugins/qmlprofiler/tests/qmlevent_test.cpp index f832c02f49a..78cd058521c 100644 --- a/src/plugins/qmlprofiler/tests/qmlevent_test.cpp +++ b/src/plugins/qmlprofiler/tests/qmlevent_test.cpp @@ -31,6 +31,21 @@ #include namespace QmlProfiler { + +static inline bool operator==(const QmlEvent &event1, const QmlEvent &event2) +{ + if (event1.timestamp() != event2.timestamp() || event1.typeIndex() != event2.typeIndex()) + return false; + + // This is not particularly efficient, but we also don't need to do this very often. + return event1.numbers>() == event2.numbers>(); +} + +static inline bool operator!=(const QmlEvent &event1, const QmlEvent &event2) +{ + return !(event1 == event2); +} + namespace Internal { QmlEventTest::QmlEventTest(QObject *parent) : QObject(parent) diff --git a/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp b/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp index 889a3445740..8beebaa3f89 100644 --- a/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp +++ b/src/plugins/qmlprofiler/tests/qmleventtype_test.cpp @@ -43,7 +43,7 @@ void QmlEventTypeTest::testAccessors() QVERIFY(!type.location().isValid()); QVERIFY(type.data().isEmpty()); QVERIFY(type.displayName().isEmpty()); - QCOMPARE(type.feature(), MaximumProfileFeature); + QCOMPARE(static_cast(type.feature()), MaximumProfileFeature); type.setLocation(QmlEventLocation("blah.js", 12, 13)); QCOMPARE(type.location().filename(), QString("blah.js")); @@ -64,12 +64,12 @@ void QmlEventTypeTest::testAccessors() QCOMPARE(type2.location(), QmlEventLocation("lala.js", 2, 3)); QCOMPARE(type2.data(), QString("nehhh")); QCOMPARE(type2.displayName(), QString("brbr")); - QCOMPARE(type2.feature(), ProfileJavaScript); + QCOMPARE(static_cast(type2.feature()), ProfileJavaScript); } void QmlEventTypeTest::testFeature() { - const ProfileFeature features[][MaximumEventType] = { + const quint8 features[][MaximumEventType] = { // Event {MaximumProfileFeature, ProfileInputEvents, ProfileInputEvents, ProfileAnimations, MaximumProfileFeature, MaximumProfileFeature}, @@ -111,7 +111,8 @@ void QmlEventTypeTest::testFeature() for (int i = 0; i < MaximumRangeType; ++i) { QmlEventType type(MaximumMessage, static_cast(i)); - QCOMPARE(type.feature(), featureFromRangeType(static_cast(i))); + QCOMPARE(static_cast(type.feature()), + featureFromRangeType(static_cast(i))); } } @@ -131,10 +132,14 @@ void QmlEventTypeTest::testStreamOps() QDataStream rstream(&rbuffer); QmlEventType type2; - QVERIFY(type != type2); + QVERIFY(type.rangeType() != type2.rangeType()); + rstream >> type2; - QCOMPARE(type2, type); + QCOMPARE(type.message(), type2.message()); + QCOMPARE(type.rangeType(), type2.rangeType()); + QCOMPARE(type.detailType(), type2.detailType()); + QCOMPARE(type.location(), type2.location()); } } // namespace Internal