diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-06-30 15:55:33 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2015-07-08 13:59:49 +0000 |
commit | 054f03e1652e5ed77beec0c4d0d182c632a3bea6 (patch) | |
tree | 57ebdd3403e828b373b0bec0557a01868abe2c9f | |
parent | 3e5b797c53063d894697ccfc318d87840adfd7c0 (diff) | |
download | qt-creator-054f03e1652e5ed77beec0c4d0d182c632a3bea6.tar.gz |
QmlProfiler: Track requested, recorded, and displayed features
This way we can have a central filter menu to hide and show features
in any connected views.
Change-Id: I8142da0062a23f8166555016de6c7cb38060f725
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
-rw-r--r-- | src/libs/qmldebug/qmlprofilertraceclient.cpp | 54 | ||||
-rw-r--r-- | src/libs/qmldebug/qmlprofilertraceclient.h | 4 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp | 15 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp | 51 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilermodelmanager.h | 9 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp | 31 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerstatemanager.h | 9 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilertimelinemodel.cpp | 2 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilertool.cpp | 121 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilertool.h | 7 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilertracefile.cpp | 37 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilertracefile.h | 2 |
12 files changed, 272 insertions, 70 deletions
diff --git a/src/libs/qmldebug/qmlprofilertraceclient.cpp b/src/libs/qmldebug/qmlprofilertraceclient.cpp index daecd97fc9..aa9592e290 100644 --- a/src/libs/qmldebug/qmlprofilertraceclient.cpp +++ b/src/libs/qmldebug/qmlprofilertraceclient.cpp @@ -41,12 +41,14 @@ public: , inProgressRanges(0) , maximumTime(0) , recording(false) - , features(0) + , requestedFeatures(0) + , recordedFeatures(0) { ::memset(rangeCount, 0, MaximumRangeType * sizeof(int)); } void sendRecordingStatus(int engineId); + bool updateFeatures(QmlDebug::ProfileFeature feature); QmlProfilerTraceClient *q; QmlEngineControlClient engineControl; @@ -58,7 +60,8 @@ public: int rangeCount[MaximumRangeType]; qint64 maximumTime; bool recording; - quint64 features; + quint64 requestedFeatures; + quint64 recordedFeatures; }; } // namespace QmlDebug @@ -73,7 +76,7 @@ void QmlProfilerTraceClientPrivate::sendRecordingStatus(int engineId) QDataStream stream(&ba, QIODevice::WriteOnly); stream << recording << engineId; // engineId -1 is OK. It means "all of them" if (recording) - stream << features; + stream << requestedFeatures; q->sendMessage(ba); } @@ -81,7 +84,7 @@ QmlProfilerTraceClient::QmlProfilerTraceClient(QmlDebugConnection *client, quint : QmlDebugClient(QLatin1String("CanvasFrameRate"), client) , d(new QmlProfilerTraceClientPrivate(this, client)) { - d->features = features; + d->requestedFeatures = features; connect(&d->engineControl, SIGNAL(engineAboutToBeAdded(int,QString)), this, SLOT(sendRecordingStatus(int))); } @@ -104,6 +107,10 @@ void QmlProfilerTraceClient::clearData() d->rangeStartTimes[eventType].clear(); } d->bindingTypes.clear(); + if (d->recordedFeatures != 0) { + d->recordedFeatures = 0; + emit recordedFeaturesChanged(0); + } emit cleared(); } @@ -135,9 +142,14 @@ void QmlProfilerTraceClient::setRecording(bool v) emit recordingChanged(v); } -void QmlProfilerTraceClient::setFeatures(quint64 features) +quint64 QmlProfilerTraceClient::recordedFeatures() const +{ + return d->recordedFeatures; +} + +void QmlProfilerTraceClient::setRequestedFeatures(quint64 features) { - d->features = features; + d->requestedFeatures = features; } void QmlProfilerTraceClient::setRecordingFromServer(bool v) @@ -148,6 +160,18 @@ void QmlProfilerTraceClient::setRecordingFromServer(bool v) emit recordingChanged(v); } +bool QmlProfilerTraceClientPrivate::updateFeatures(ProfileFeature feature) +{ + quint64 flag = 1ULL << feature; + if (!(requestedFeatures & flag)) + return false; + if (!(recordedFeatures & flag)) { + recordedFeatures |= flag; + emit q->recordedFeaturesChanged(recordedFeatures); + } + return true; +} + void QmlProfilerTraceClient::stateChanged(State /*status*/) { emit enabledChanged(); @@ -200,7 +224,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case AnimationFrame: { - if (!(d->features & (1 << ProfileAnimations))) + if (!d->updateFeatures(ProfileAnimations)) break; int frameRate, animationCount; int threadId; @@ -218,7 +242,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) } case Key: case Mouse: - if (!(d->features & (1 << ProfileInputEvents))) + if (!d->updateFeatures(ProfileInputEvents)) break; emit this->rangedEvent(Event, MaximumRangeType, subtype, time, 0, QString(), @@ -233,7 +257,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) emit complete(d->maximumTime); break; case SceneGraphFrame: { - if (!(d->features & (1 << ProfileSceneGraph))) + if (!d->updateFeatures(ProfileSceneGraph)) break; int count = 0; @@ -250,7 +274,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case PixmapCacheEvent: { - if (!(d->features & (1 << ProfilePixmapCache))) + if (!d->updateFeatures(ProfilePixmapCache)) break; int width = 0, height = 0, refcount = 0; QString pixUrl; @@ -268,7 +292,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case MemoryAllocation: { - if (!(d->features & (1 << ProfileMemory))) + if (!d->updateFeatures(ProfileMemory)) break; qint64 delta; @@ -279,7 +303,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case RangeStart: { - if (!(d->features & (1ULL << featureFromRangeType(static_cast<RangeType>(subtype))))) + if (!d->updateFeatures(featureFromRangeType(static_cast<RangeType>(subtype)))) break; d->rangeStartTimes[subtype].push(time); d->inProgressRanges |= (static_cast<qint64>(1) << subtype); @@ -295,7 +319,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case RangeData: { - if (!(d->features & (1ULL << featureFromRangeType(static_cast<RangeType>(subtype))))) + if (!d->updateFeatures(featureFromRangeType(static_cast<RangeType>(subtype)))) break; QString data; stream >> data; @@ -309,7 +333,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case RangeLocation: { - if (!(d->features & (1ULL << featureFromRangeType(static_cast<RangeType>(subtype))))) + if (!d->updateFeatures(featureFromRangeType(static_cast<RangeType>(subtype)))) break; QString fileName; int line; @@ -324,7 +348,7 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data) break; } case RangeEnd: { - if (!(d->features & (1ULL << featureFromRangeType(static_cast<RangeType>(subtype))))) + if (!d->updateFeatures(featureFromRangeType(static_cast<RangeType>(subtype)))) break; if (d->rangeCount[subtype] == 0) break; diff --git a/src/libs/qmldebug/qmlprofilertraceclient.h b/src/libs/qmldebug/qmlprofilertraceclient.h index 628ca7641e..cc83653569 100644 --- a/src/libs/qmldebug/qmlprofilertraceclient.h +++ b/src/libs/qmldebug/qmlprofilertraceclient.h @@ -57,11 +57,12 @@ public: bool isEnabled() const; bool isRecording() const; void setRecording(bool); + quint64 recordedFeatures() const; public slots: void clearData(); void sendRecordingStatus(int engineId = -1); - void setFeatures(quint64 features); + void setRequestedFeatures(quint64 features); signals: void complete(qint64 maximumTime); @@ -73,6 +74,7 @@ signals: const QmlDebug::QmlEventLocation &location, qint64 param1, qint64 param2, qint64 param3, qint64 param4, qint64 param5); void recordingChanged(bool arg); + void recordedFeaturesChanged(quint64 features); void enabledChanged(); void cleared(); diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp index 8d5fc76768..72a73214a4 100644 --- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp @@ -151,8 +151,9 @@ void QmlProfilerClientManager::enableServices() disconnectClientSignals(); d->profilerState->setServerRecording(false); // false by default (will be set to true when connected) delete d->qmlclientplugin.data(); + d->profilerState->setRecordedFeatures(0); d->qmlclientplugin = new QmlProfilerTraceClient(d->connection, - d->profilerState->recordingFeatures()); + d->profilerState->requestedFeatures()); connectClientSignals(); } @@ -178,8 +179,10 @@ void QmlProfilerClientManager::connectClientSignals() d->qmlclientplugin.data(), SLOT(sendRecordingStatus())); connect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)), d->profilerState, SLOT(setServerRecording(bool))); - connect(d->profilerState, SIGNAL(recordingFeaturesChanged(quint64)), - d->qmlclientplugin.data(), SLOT(setFeatures(quint64))); + connect(d->profilerState, &QmlProfilerStateManager::requestedFeaturesChanged, + d->qmlclientplugin.data(), &QmlProfilerTraceClient::setRequestedFeatures); + connect(d->qmlclientplugin.data(), &QmlProfilerTraceClient::recordedFeaturesChanged, + d->profilerState, &QmlProfilerStateManager::setRecordedFeatures); } } @@ -203,8 +206,10 @@ void QmlProfilerClientManager::disconnectClientSignals() // fixme: this should be unified for both clients disconnect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)), d->profilerState, SLOT(setServerRecording(bool))); - disconnect(d->profilerState, SIGNAL(recordingFeaturesChanged(quint64)), - d->qmlclientplugin.data(), SLOT(setFeatures(quint64))); + disconnect(d->profilerState, &QmlProfilerStateManager::requestedFeaturesChanged, + d->qmlclientplugin.data(), &QmlProfilerTraceClient::setRequestedFeatures); + disconnect(d->qmlclientplugin.data(), &QmlProfilerTraceClient::recordedFeaturesChanged, + d->profilerState, &QmlProfilerStateManager::setRecordedFeatures); } } diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index 3082f5911f..40b4d22c5f 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -178,7 +178,9 @@ public: QVector <double> partialCounts; QVector <int> partialCountWeights; - quint64 features; + quint64 availableFeatures; + quint64 visibleFeatures; + quint64 recordedFeatures; int totalWeight; double progress; @@ -193,7 +195,9 @@ QmlProfilerModelManager::QmlProfilerModelManager(Utils::FileInProjectFinder *fin QObject(parent), d(new QmlProfilerModelManagerPrivate(this)) { d->totalWeight = 0; - d->features = 0; + d->availableFeatures = 0; + d->visibleFeatures = 0; + d->recordedFeatures = 0; d->model = new QmlProfilerDataModel(finder, this); d->dataState = new QmlProfilerDataState(this, this); d->traceTime = new QmlProfilerTraceTime(this); @@ -272,15 +276,45 @@ void QmlProfilerModelManager::modelProxyCountUpdated(int proxyId, qint64 count, void QmlProfilerModelManager::announceFeatures(int proxyId, quint64 features) { Q_UNUSED(proxyId); // Will use that later to optimize the event dispatching on loading. - if ((features & d->features) != features) { - d->features |= features; - emit availableFeaturesChanged(d->features); + if ((features & d->availableFeatures) != features) { + d->availableFeatures |= features; + emit availableFeaturesChanged(d->availableFeatures); } + if ((features & d->visibleFeatures) != features) { + d->visibleFeatures |= features; + emit visibleFeaturesChanged(d->visibleFeatures); + } +} + +quint64 QmlProfilerModelManager::availableFeatures() const +{ + return d->availableFeatures; } -quint64 QmlProfilerModelManager::availableFeatures() +quint64 QmlProfilerModelManager::visibleFeatures() const { - return d->features; + return d->visibleFeatures; +} + +void QmlProfilerModelManager::setVisibleFeatures(quint64 features) +{ + if (d->visibleFeatures != features) { + d->visibleFeatures = features; + emit visibleFeaturesChanged(d->visibleFeatures); + } +} + +quint64 QmlProfilerModelManager::recordedFeatures() const +{ + return d->recordedFeatures; +} + +void QmlProfilerModelManager::setRecordedFeatures(quint64 features) +{ + if (d->recordedFeatures != features) { + d->recordedFeatures = features; + emit recordedFeaturesChanged(d->recordedFeatures); + } } const char *QmlProfilerModelManager::featureName(QmlDebug::ProfileFeature feature) @@ -398,6 +432,7 @@ void QmlProfilerModelManager::load() connect(&reader, &QmlProfilerFileReader::error, this, &QmlProfilerModelManager::error); reader.setQmlDataModel(d->model); reader.load(file); + setRecordedFeatures(reader.loadedFeatures()); file->close(); file->deleteLater(); @@ -430,6 +465,8 @@ void QmlProfilerModelManager::clear() d->model->clear(); d->traceTime->clear(); d->notesModel->clear(); + setVisibleFeatures(0); + setRecordedFeatures(0); setState(QmlProfilerDataState::Empty); } diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h index 5e4649273e..2ef8bd1e32 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h @@ -127,7 +127,12 @@ public: void setProxyCountWeight(int proxyId, int weight); void modelProxyCountUpdated(int proxyId, qint64 count, qint64 max); void announceFeatures(int proxyId, quint64 features); - quint64 availableFeatures(); + quint64 availableFeatures() const; + quint64 visibleFeatures() const; + void setVisibleFeatures(quint64 features); + quint64 recordedFeatures() const; + void setRecordedFeatures(quint64 features); + static const char *featureName(QmlDebug::ProfileFeature feature); signals: @@ -139,6 +144,8 @@ signals: void requestDetailsForLocation(int eventType, const QmlDebug::QmlEventLocation &location); void availableFeaturesChanged(quint64 features); + void visibleFeaturesChanged(quint64 features); + void recordedFeaturesChanged(quint64 features); public slots: void clear(); diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp b/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp index ba4757cee3..09e0e6b8d6 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp @@ -64,7 +64,8 @@ public: QmlProfilerStateManager::QmlProfilerState m_currentState; bool m_clientRecording; bool m_serverRecording; - quint64 m_recordingFeatures; + quint64 m_requestedFeatures; + quint64 m_recordedFeatures; }; QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) : QObject(parent),d(new QmlProfilerStateManagerPrivate(this)) @@ -72,7 +73,8 @@ QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) : d->m_currentState = Idle; d->m_clientRecording = true; d->m_serverRecording = false; - d->m_recordingFeatures = 0; + d->m_requestedFeatures = 0; + d->m_recordedFeatures = 0; } QmlProfilerStateManager::~QmlProfilerStateManager() @@ -95,9 +97,14 @@ bool QmlProfilerStateManager::serverRecording() return d->m_serverRecording; } -quint64 QmlProfilerStateManager::recordingFeatures() const +quint64 QmlProfilerStateManager::requestedFeatures() const { - return d->m_recordingFeatures; + return d->m_requestedFeatures; +} + +quint64 QmlProfilerStateManager::recordedFeatures() const +{ + return d->m_recordedFeatures; } QString QmlProfilerStateManager::currentStateAsString() @@ -180,11 +187,19 @@ void QmlProfilerStateManager::setServerRecording(bool recording) } } -void QmlProfilerStateManager::setRecordingFeatures(quint64 features) +void QmlProfilerStateManager::setRequestedFeatures(quint64 features) +{ + if (d->m_requestedFeatures != features) { + d->m_requestedFeatures = features; + emit requestedFeaturesChanged(features); + } +} + +void QmlProfilerStateManager::setRecordedFeatures(quint64 features) { - if (d->m_recordingFeatures != features) { - d->m_recordingFeatures = features; - emit recordingFeaturesChanged(features); + if (d->m_recordedFeatures != features) { + d->m_recordedFeatures = features; + emit recordedFeaturesChanged(features); } } diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h index 444ea12d03..da6fa14974 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h @@ -56,7 +56,8 @@ public: QmlProfilerState currentState(); bool clientRecording(); bool serverRecording(); - quint64 recordingFeatures() const; + quint64 requestedFeatures() const; + quint64 recordedFeatures() const; QString currentStateAsString(); @@ -64,13 +65,15 @@ signals: void stateChanged(); void clientRecordingChanged(); void serverRecordingChanged(); - void recordingFeaturesChanged(quint64); + void requestedFeaturesChanged(quint64); + void recordedFeaturesChanged(quint64); public slots: void setCurrentState(QmlProfilerState newState); void setClientRecording(bool recording); void setServerRecording(bool recording); - void setRecordingFeatures(quint64 features); + void setRequestedFeatures(quint64 features); + void setRecordedFeatures(quint64 features); private: class QmlProfilerStateManagerPrivate; diff --git a/src/plugins/qmlprofiler/qmlprofilertimelinemodel.cpp b/src/plugins/qmlprofiler/qmlprofilertimelinemodel.cpp index ec90364db5..dd8ddf15a9 100644 --- a/src/plugins/qmlprofiler/qmlprofilertimelinemodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertimelinemodel.cpp @@ -44,6 +44,8 @@ QmlProfilerTimelineModel::QmlProfilerTimelineModel(QmlProfilerModelManager *mode { connect(modelManager, &QmlProfilerModelManager::stateChanged, this, &QmlProfilerTimelineModel::dataChanged); + connect(modelManager, &QmlProfilerModelManager::visibleFeaturesChanged, + this, &QmlProfilerTimelineModel::onVisibleFeaturesChanged); announceFeatures(1ULL << m_mainFeature); } diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 82d08e9d75..e05a7350b9 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -101,7 +101,7 @@ public: QmlProfilerViewManager *m_viewContainer; Utils::FileInProjectFinder m_projectFinder; QToolButton *m_recordButton; - QMenu *m_featuresMenu; + QMenu *m_recordFeaturesMenu; QToolButton *m_clearButton; @@ -113,6 +113,10 @@ public: // open search QToolButton *m_searchButton; + // hide and show categories + QToolButton *m_displayFeaturesButton; + QMenu *m_displayFeaturesMenu; + // save and load actions QAction *m_saveQmlTrace; QAction *m_loadQmlTrace; @@ -126,15 +130,19 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) d->m_profilerState = 0; d->m_viewContainer = 0; d->m_recordButton = 0; - d->m_featuresMenu = 0; + d->m_recordFeaturesMenu = 0; d->m_clearButton = 0; d->m_timeLabel = 0; d->m_searchButton = 0; + d->m_displayFeaturesButton = 0; + d->m_displayFeaturesMenu = 0; d->m_profilerState = new QmlProfilerStateManager(this); connect(d->m_profilerState, SIGNAL(stateChanged()), this, SLOT(profilerStateChanged())); connect(d->m_profilerState, SIGNAL(clientRecordingChanged()), this, SLOT(clientRecordingChanged())); connect(d->m_profilerState, SIGNAL(serverRecordingChanged()), this, SLOT(serverRecordingChanged())); + connect(d->m_profilerState, &QmlProfilerStateManager::recordedFeaturesChanged, + this, &QmlProfilerTool::setRecordedFeatures); d->m_profilerConnections = new QmlProfilerClientManager(this); d->m_profilerConnections->registerProfilerStateManager(d->m_profilerState); @@ -143,8 +151,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this); 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(availableFeaturesChanged(quint64)), - this, SLOT(setAvailableFeatures(quint64))); + connect(d->m_profilerModelManager, &QmlProfilerModelManager::availableFeaturesChanged, + this, &QmlProfilerTool::setAvailableFeatures); connect(d->m_profilerModelManager, &QmlProfilerModelManager::saveFinished, this, &QmlProfilerTool::onLoadSaveFinished); connect(d->m_profilerModelManager, &QmlProfilerModelManager::loadFinished, @@ -246,12 +254,11 @@ QWidget *QmlProfilerTool::createWidgets() connect(d->m_recordButton,SIGNAL(clicked(bool)), this, SLOT(recordingButtonChanged(bool))); d->m_recordButton->setChecked(true); - d->m_featuresMenu = new QMenu(d->m_recordButton); - d->m_recordButton->setMenu(d->m_featuresMenu); + d->m_recordFeaturesMenu = new QMenu(d->m_recordButton); + d->m_recordButton->setMenu(d->m_recordFeaturesMenu); d->m_recordButton->setPopupMode(QToolButton::MenuButtonPopup); - setAvailableFeatures(d->m_profilerModelManager->availableFeatures()); - connect(d->m_featuresMenu, SIGNAL(triggered(QAction*)), - this, SLOT(toggleRecordingFeature(QAction*))); + connect(d->m_recordFeaturesMenu, SIGNAL(triggered(QAction*)), + this, SLOT(toggleRequestedFeature(QAction*))); setRecording(d->m_profilerState->clientRecording()); layout->addWidget(d->m_recordButton); @@ -282,8 +289,21 @@ QWidget *QmlProfilerTool::createWidgets() connect(d->m_searchButton, &QToolButton::clicked, this, &QmlProfilerTool::showTimeLineSearch); + d->m_displayFeaturesButton = new QToolButton; + d->m_displayFeaturesButton->setIcon(QIcon(QLatin1String(ICON_FILTER))); + d->m_displayFeaturesButton->setToolTip(tr("Hide or show event categories.")); + d->m_displayFeaturesButton->setPopupMode(QToolButton::InstantPopup); + d->m_displayFeaturesMenu = new QMenu(d->m_displayFeaturesButton); + d->m_displayFeaturesButton->setMenu(d->m_displayFeaturesMenu); + connect(d->m_displayFeaturesMenu, &QMenu::triggered, + this, &QmlProfilerTool::toggleVisibleFeature); + layout->addWidget(d->m_displayFeaturesButton); + layout->addStretch(); + toolbarWidget->setLayout(layout); + setAvailableFeatures(d->m_profilerModelManager->availableFeatures()); + setRecordedFeatures(0); // When the widgets are requested we assume that the session data // is available, then we can populate the file finder @@ -407,6 +427,7 @@ void QmlProfilerTool::clearData() { d->m_profilerModelManager->clear(); d->m_profilerConnections->discardPendingData(); + setRecordedFeatures(0); } void QmlProfilerTool::clearDisplay() @@ -531,12 +552,16 @@ void QmlProfilerTool::showLoadDialog() if (!filename.isEmpty()) { AnalyzerManager::mainWindow()->setEnabled(false); + connect(d->m_profilerModelManager, &QmlProfilerModelManager::recordedFeaturesChanged, + this, &QmlProfilerTool::setRecordedFeatures); d->m_profilerModelManager->load(filename); } } void QmlProfilerTool::onLoadSaveFinished() { + disconnect(d->m_profilerModelManager, &QmlProfilerModelManager::recordedFeaturesChanged, + this, &QmlProfilerTool::setRecordedFeatures); AnalyzerManager::mainWindow()->setEnabled(true); } @@ -556,6 +581,18 @@ bool QmlProfilerTool::checkForUnsavedNotes() QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes; } +void QmlProfilerTool::restoreFeatureVisibility() +{ + // Restore the shown/hidden state of features to what the user selected. When clearing data the + // the model manager sets its features to 0, and models get automatically shown, for the mockup. + quint64 features = 0; + foreach (const QAction *action, d->m_displayFeaturesMenu->actions()) { + if (action->isChecked()) + features |= (1ULL << action->data().toUInt()); + } + d->m_profilerModelManager->setVisibleFeatures(features); +} + void QmlProfilerTool::clientsDisconnected() { // If the application stopped by itself, check if we have all the data @@ -571,21 +608,29 @@ void QmlProfilerTool::clientsDisconnected() // If the connection is closed while the app is still running, no special action is needed } +void addFeatureToMenu(QMenu *menu, ProfileFeature feature, quint64 enabledFeatures) +{ + QAction *action = + menu->addAction(QmlProfilerTool::tr(QmlProfilerModelManager::featureName(feature))); + action->setCheckable(true); + action->setData(static_cast<uint>(feature)); + action->setChecked(enabledFeatures & (1ULL << (feature))); +} + template<ProfileFeature feature> -void QmlProfilerTool::updateFeaturesMenu(quint64 features) +void QmlProfilerTool::updateFeatures(quint64 features) { if (features & (1ULL << (feature))) { - QAction *action = d->m_featuresMenu->addAction(tr(QmlProfilerModelManager::featureName( - static_cast<ProfileFeature>(feature)))); - action->setCheckable(true); - action->setData(static_cast<uint>(feature)); - action->setChecked(d->m_profilerState->recordingFeatures() & (1ULL << (feature))); + addFeatureToMenu(d->m_recordFeaturesMenu, feature, + d->m_profilerState->requestedFeatures()); + addFeatureToMenu(d->m_displayFeaturesMenu, feature, + d->m_profilerModelManager->visibleFeatures()); } - updateFeaturesMenu<static_cast<ProfileFeature>(feature + 1)>(features); + updateFeatures<static_cast<ProfileFeature>(feature + 1)>(features); } template<> -void QmlProfilerTool::updateFeaturesMenu<MaximumProfileFeature>(quint64 features) +void QmlProfilerTool::updateFeatures<MaximumProfileFeature>(quint64 features) { Q_UNUSED(features); return; @@ -593,14 +638,21 @@ void QmlProfilerTool::updateFeaturesMenu<MaximumProfileFeature>(quint64 features void QmlProfilerTool::setAvailableFeatures(quint64 features) { - if (features != d->m_profilerState->recordingFeatures()) - d->m_profilerState->setRecordingFeatures(features); // by default, enable them all. - if (d->m_featuresMenu) { - d->m_featuresMenu->clear(); - updateFeaturesMenu<static_cast<ProfileFeature>(0)>(features); + if (features != d->m_profilerState->requestedFeatures()) + d->m_profilerState->setRequestedFeatures(features); // by default, enable them all. + if (d->m_recordFeaturesMenu && d->m_displayFeaturesMenu) { + d->m_recordFeaturesMenu->clear(); + d->m_displayFeaturesMenu->clear(); + updateFeatures<static_cast<ProfileFeature>(0)>(features); } } +void QmlProfilerTool::setRecordedFeatures(quint64 features) +{ + foreach (QAction *action, d->m_displayFeaturesMenu->actions()) + action->setEnabled(features & (1ULL << action->data().toUInt())); +} + void QmlProfilerTool::profilerDataModelStateChanged() { switch (d->m_profilerModelManager->state()) { @@ -618,6 +670,7 @@ void QmlProfilerTool::profilerDataModelStateChanged() d->m_profilerState->setCurrentState(QmlProfilerStateManager::AppReadyToStop); showSaveOption(); updateTimeDisplay(); + restoreFeatureVisibility(); break; default: break; @@ -715,19 +768,33 @@ void QmlProfilerTool::serverRecordingChanged() } } -void QmlProfilerTool::toggleRecordingFeature(QAction *action) +void QmlProfilerTool::toggleRequestedFeature(QAction *action) { uint feature = action->data().toUInt(); if (action->isChecked()) - d->m_profilerState->setRecordingFeatures( - d->m_profilerState->recordingFeatures() | (1ULL << feature)); + d->m_profilerState->setRequestedFeatures( + d->m_profilerState->requestedFeatures() | (1ULL << feature)); else - d->m_profilerState->setRecordingFeatures( - d->m_profilerState->recordingFeatures() & (~(1ULL << feature))); + d->m_profilerState->setRequestedFeatures( + d->m_profilerState->requestedFeatures() & (~(1ULL << feature))); // Keep the menu open to allow for more features to be toggled d->m_recordButton->showMenu(); } +void QmlProfilerTool::toggleVisibleFeature(QAction *action) +{ + uint feature = action->data().toUInt(); + if (action->isChecked()) + d->m_profilerModelManager->setVisibleFeatures( + d->m_profilerModelManager->visibleFeatures() | (1ULL << feature)); + else + d->m_profilerModelManager->setVisibleFeatures( + d->m_profilerModelManager->visibleFeatures() & (~(1ULL << feature))); + + // Keep the menu open to allow for more features to be toggled + d->m_displayFeaturesButton->showMenu(); +} + } } diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index ce59a8fc79..5aa9fc75b0 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -76,6 +76,7 @@ public slots: void serverRecordingChanged(); void clientsDisconnected(); void setAvailableFeatures(quint64 features); + void setRecordedFeatures(quint64 features); void recordingButtonChanged(bool recording); void setRecording(bool recording); @@ -95,14 +96,16 @@ private slots: void showLoadDialog(); void onLoadSaveFinished(); - void toggleRecordingFeature(QAction *action); + void toggleRequestedFeature(QAction *action); + void toggleVisibleFeature(QAction *action); private: void clearDisplay(); void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString()); template<QmlDebug::ProfileFeature feature> - void updateFeaturesMenu(quint64 features); + void updateFeatures(quint64 features); bool checkForUnsavedNotes(); + void restoreFeatureVisibility(); class QmlProfilerToolPrivate; QmlProfilerToolPrivate *d; diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp index e3649b65ae..c4cd31cf40 100644 --- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp @@ -121,7 +121,8 @@ static QString qmlTypeAsString(Message message, RangeType rangeType) QmlProfilerFileReader::QmlProfilerFileReader(QObject *parent) : QObject(parent), - m_future(0) + m_future(0), + m_loadedFeatures(0) { } @@ -199,6 +200,37 @@ bool QmlProfilerFileReader::load(QIODevice *device) } } +quint64 QmlProfilerFileReader::loadedFeatures() const +{ + return m_loadedFeatures; +} + +QmlDebug::ProfileFeature featureFromEvent(const QmlProfilerDataModel::QmlEventTypeData &event) { + if (event.rangeType < MaximumRangeType) + return featureFromRangeType(event.rangeType); + + switch (event.message) { + case Event: + switch (event.detailType) { + case AnimationFrame: + return ProfileAnimations; + case Key: + case Mouse: + return ProfileInputEvents; + default: + return MaximumProfileFeature; + } + case PixmapCacheEvent: + return ProfilePixmapCache; + case SceneGraphFrame: + return ProfileSceneGraph; + case MemoryAllocation: + return ProfileMemory; + default: + return MaximumProfileFeature; + } +} + void QmlProfilerFileReader::loadEventData(QXmlStreamReader &stream) { QTC_ASSERT(stream.name() == _("eventData"), return); @@ -308,6 +340,9 @@ void QmlProfilerFileReader::loadEventData(QXmlStreamReader &stream) if (eventIndex >= m_qmlEvents.size()) m_qmlEvents.resize(eventIndex + 1); m_qmlEvents[eventIndex] = event; + ProfileFeature feature = featureFromEvent(event); + if (feature != MaximumProfileFeature) + m_loadedFeatures |= (1ULL << static_cast<uint>(feature)); } break; } diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.h b/src/plugins/qmlprofiler/qmlprofilertracefile.h index 30d5a49236..a0c0cef074 100644 --- a/src/plugins/qmlprofiler/qmlprofilertracefile.h +++ b/src/plugins/qmlprofiler/qmlprofilertracefile.h @@ -59,6 +59,7 @@ public: void setFuture(QFutureInterface<void> *future); bool load(QIODevice *device); + quint64 loadedFeatures() const; signals: void error(const QString &error); @@ -75,6 +76,7 @@ private: QVector<QmlProfilerDataModel::QmlEventTypeData> m_qmlEvents; QVector<QmlProfilerDataModel::QmlEventData> m_ranges; QVector<QmlProfilerDataModel::QmlEventNoteData> m_notes; + quint64 m_loadedFeatures; }; |