diff options
author | Ulf Hermann <ulf.hermann@digia.com> | 2014-09-09 18:22:58 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@digia.com> | 2014-09-15 09:15:24 +0200 |
commit | 6d58de0bad462ab4599428bb18d64d0cb0c7828d (patch) | |
tree | 7c274b60e0d69640019df2a3f4ebf4a03d409540 /src/plugins | |
parent | 7290c43da14c1f416c8de0654d8f335a3b271989 (diff) | |
download | qt-creator-6d58de0bad462ab4599428bb18d64d0cb0c7828d.tar.gz |
QmlProfiler: Allow preselection of events to be recorded
This allows us to reduce the amount of data we need to handle
if the user isn't interested in certain categories.
Task-number: QTBUG-41118
Change-Id: Ieaac12fb1dec29d6035642f433bc1a1d49e545c2
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src/plugins')
14 files changed, 177 insertions, 14 deletions
diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp index 95ee07da3d..e13cb2272f 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -59,6 +59,7 @@ void AbstractTimelineModel::setModelManager(QmlProfilerModelManager *modelManage d->modelManager = modelManager; connect(d->modelManager->qmlModel(),SIGNAL(changed()),this,SLOT(dataChanged())); d->modelId = d->modelManager->registerModelProxy(); + d->modelManager->announceFeatures(d->modelId, features()); } bool AbstractTimelineModel::isEmpty() const diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.h b/src/plugins/qmlprofiler/abstracttimelinemodel.h index a1e783d2bf..552d2de909 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.h @@ -74,6 +74,7 @@ public: virtual QVariantMap details(int index) const = 0; virtual int row(int index) const = 0; virtual void loadData() = 0; + virtual quint64 features() const = 0; // Methods which can optionally be implemented by child models. // returned map should contain "file", "line", "column" properties, or be empty diff --git a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp index 2d209f6f9f..efb1bfef9f 100644 --- a/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerclientmanager.cpp @@ -162,7 +162,8 @@ void QmlProfilerClientManager::enableServices() disconnectClientSignals(); d->profilerState->setServerRecording(false); // false by default (will be set to true when connected) delete d->qmlclientplugin.data(); - d->qmlclientplugin = new QmlProfilerTraceClient(d->connection); + d->qmlclientplugin = new QmlProfilerTraceClient(d->connection, + d->profilerState->recordingFeatures()); delete d->v8clientplugin.data(); d->v8clientplugin = new QV8ProfilerClient(d->connection); connectClientSignals(); @@ -191,6 +192,8 @@ void QmlProfilerClientManager::connectClientSignals() // fixme: this should be unified for both clients connect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)), d->profilerState, SLOT(setServerRecording(bool))); + connect(d->profilerState, SIGNAL(recordingFeaturesChanged(quint64)), + d->qmlclientplugin.data(), SLOT(setFeatures(quint64))); } if (d->v8clientplugin) { connect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); @@ -223,6 +226,8 @@ 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))); } if (d->v8clientplugin) { disconnect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); diff --git a/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp index 9691dd701e..ceb589f97d 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventsmodelproxy.cpp @@ -74,6 +74,8 @@ QmlProfilerEventsModelProxy::QmlProfilerEventsModelProxy(QmlProfilerModelManager modelManager->setProxyCountWeight(d->modelId, 2); d->acceptedTypes << QmlDebug::Compiling << QmlDebug::Creating << QmlDebug::Binding << QmlDebug::HandlingSignal << QmlDebug::Javascript; + + modelManager->announceFeatures(d->modelId, QmlDebug::Constants::QML_JS_RANGE_FEATURES); } QmlProfilerEventsModelProxy::~QmlProfilerEventsModelProxy() diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp index 4e633cbdd4..68a9b36903 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp @@ -40,6 +40,19 @@ namespace QmlProfiler { namespace Internal { +static const char *ProfileFeatureNames[QmlDebug::MaximumProfileFeature] = { + QT_TRANSLATE_NOOP("MainView", "JavaScript"), + QT_TRANSLATE_NOOP("MainView", "Memory Usage"), + QT_TRANSLATE_NOOP("MainView", "Pixmap Cache"), + QT_TRANSLATE_NOOP("MainView", "Scene Graph"), + QT_TRANSLATE_NOOP("MainView", "Animations"), + QT_TRANSLATE_NOOP("MainView", "Painting"), + QT_TRANSLATE_NOOP("MainView", "Compiling"), + QT_TRANSLATE_NOOP("MainView", "Creating"), + QT_TRANSLATE_NOOP("MainView", "Binding"), + QT_TRANSLATE_NOOP("MainView", "Handling Signal"), + QT_TRANSLATE_NOOP("MainView", "Input Events") +}; ///////////////////////////////////////////////////////////////////// QmlProfilerDataState::QmlProfilerDataState(QmlProfilerModelManager *modelManager, QObject *parent) @@ -163,6 +176,8 @@ public: QVector <double> partialCounts; QVector <int> partialCountWeights; + quint64 features; + int totalWeight; double progress; double previousProgress; @@ -251,6 +266,25 @@ 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); + } +} + +quint64 QmlProfilerModelManager::availableFeatures() +{ + return d->features; +} + +const char *QmlProfilerModelManager::featureName(QmlDebug::ProfileFeature feature) +{ + return ProfileFeatureNames[feature]; +} + qint64 QmlProfilerModelManager::estimatedProfilingTime() const { return d->estimatedTime; diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h index 2479eb037e..0dd6d583b8 100644 --- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.h +++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.h @@ -127,6 +127,9 @@ public: int registerModelProxy(); void setProxyCountWeight(int proxyId, int weight); void modelProxyCountUpdated(int proxyId, qint64 count, qint64 max); + void announceFeatures(int proxyId, quint64 features); + quint64 availableFeatures(); + static const char *featureName(QmlDebug::ProfileFeature feature); qint64 estimatedProfilingTime() const; @@ -137,6 +140,7 @@ signals: void dataAvailable(); void requestDetailsForLocation(int eventType, const QmlDebug::QmlEventLocation &location); + void availableFeaturesChanged(quint64 features); public slots: void clear(); diff --git a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp index 884c066c9b..4a5453d998 100644 --- a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp @@ -58,13 +58,18 @@ private: }; PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent) - : AbstractTimelineModel(new PaintEventsModelProxyPrivate, tr("Animations"), QmlDebug::Event, - QmlDebug::MaximumRangeType, parent) + : AbstractTimelineModel(new PaintEventsModelProxyPrivate, + tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileAnimations)), + QmlDebug::Event, QmlDebug::MaximumRangeType, parent) { Q_D(PaintEventsModelProxy); d->maxGuiThreadAnimations = d->maxRenderThreadAnimations = 0; } +quint64 PaintEventsModelProxy::features() const +{ + return 1 << QmlDebug::ProfileAnimations; +} void PaintEventsModelProxy::clear() { diff --git a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h index ef9844b271..bcdbfbbe81 100644 --- a/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h +++ b/src/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h @@ -75,6 +75,7 @@ public: QVariantList labels() const; QVariantMap details(int index) const; + quint64 features() const; private slots: bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const; diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp b/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp index a272a7ac70..188fbcff19 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.cpp @@ -64,6 +64,7 @@ public: QmlProfilerStateManager::QmlProfilerState m_currentState; bool m_clientRecording; bool m_serverRecording; + quint64 m_recordingFeatures; }; QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) : QObject(parent),d(new QmlProfilerStateManagerPrivate(this)) @@ -71,6 +72,7 @@ QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) : d->m_currentState = Idle; d->m_clientRecording = true; d->m_serverRecording = false; + d->m_recordingFeatures = 0; } QmlProfilerStateManager::~QmlProfilerStateManager() @@ -93,6 +95,11 @@ bool QmlProfilerStateManager::serverRecording() return d->m_serverRecording; } +quint64 QmlProfilerStateManager::recordingFeatures() const +{ + return d->m_recordingFeatures; +} + QString QmlProfilerStateManager::currentStateAsString() { return stringForState(d->m_currentState); @@ -173,5 +180,13 @@ void QmlProfilerStateManager::setServerRecording(bool recording) } } +void QmlProfilerStateManager::setRecordingFeatures(quint64 features) +{ + if (d->m_recordingFeatures != features) { + d->m_recordingFeatures = features; + emit recordingFeaturesChanged(features); + } +} + } } diff --git a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h index ee46c765ac..6cf009a922 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatemanager.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatemanager.h @@ -56,6 +56,7 @@ public: QmlProfilerState currentState(); bool clientRecording(); bool serverRecording(); + quint64 recordingFeatures() const; QString currentStateAsString(); @@ -63,11 +64,13 @@ signals: void stateChanged(); void clientRecordingChanged(); void serverRecordingChanged(); + void recordingFeaturesChanged(quint64); public slots: void setCurrentState(QmlProfilerState newState); void setClientRecording(bool recording); void setServerRecording(bool recording); + void setRecordingFeatures(quint64 features); private: class QmlProfilerStateManagerPrivate; diff --git a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp index 31996192c4..f460789aaf 100644 --- a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp @@ -44,6 +44,15 @@ namespace QmlProfiler { namespace Internal { +static const QmlDebug::ProfileFeature RangeFeatures[QmlDebug::MaximumRangeType] = { + QmlDebug::ProfilePainting, + QmlDebug::ProfileCompiling, + QmlDebug::ProfileCreating, + QmlDebug::ProfileBinding, + QmlDebug::ProfileHandlingSignal, + QmlDebug::ProfileJavaScript +}; + class RangeTimelineModel::RangeTimelineModelPrivate : public AbstractTimelineModelPrivate { public: @@ -70,6 +79,12 @@ RangeTimelineModel::RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *p d->contractedRows = 1; } +quint64 RangeTimelineModel::features() const +{ + Q_D(const RangeTimelineModel); + return 1 << RangeFeatures[d->rangeType]; +} + void RangeTimelineModel::clear() { Q_D(RangeTimelineModel); @@ -222,16 +237,19 @@ int RangeTimelineModel::rowCount() const return d->contractedRows; } -QString RangeTimelineModel::categoryLabel(int categoryIndex) +QString RangeTimelineModel::categoryLabel(QmlDebug::RangeType rangeType) { - switch (categoryIndex) { - case 0: return QCoreApplication::translate("MainView", "Painting"); break; - case 1: return QCoreApplication::translate("MainView", "Compiling"); break; - case 2: return QCoreApplication::translate("MainView", "Creating"); break; - case 3: return QCoreApplication::translate("MainView", "Binding"); break; - case 4: return QCoreApplication::translate("MainView", "Handling Signal"); break; - case 5: return QCoreApplication::translate("MainView", "JavaScript"); break; - default: return QString(); + switch (rangeType) { + case QmlDebug::Painting: + case QmlDebug::Compiling: + case QmlDebug::Creating: + case QmlDebug::Binding: + case QmlDebug::HandlingSignal: + case QmlDebug::Javascript: + return QCoreApplication::translate("MainView", + QmlProfilerModelManager::featureName(RangeFeatures[rangeType])); + default: + return QString(); } } diff --git a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h index ca49943e7a..9c6f71a588 100644 --- a/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h +++ b/src/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.h @@ -72,7 +72,8 @@ public: // QML interface int rowCount() const; - static QString categoryLabel(int categoryIndex); + static QString categoryLabel(QmlDebug::RangeType categoryIndex); + quint64 features() const; int row(int index) const; int eventId(int index) const; diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 5af5ffc07d..7d3d2cf7a2 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -81,11 +81,13 @@ using namespace Core; using namespace Core::Constants; using namespace Analyzer; using namespace Analyzer::Constants; -using namespace QmlProfiler::Internal; using namespace QmlProfiler::Constants; using namespace QmlDebug; using namespace ProjectExplorer; +namespace QmlProfiler { +namespace Internal { + class QmlProfilerTool::QmlProfilerToolPrivate { public: @@ -96,6 +98,8 @@ public: QmlProfilerViewManager *m_viewContainer; Utils::FileInProjectFinder m_projectFinder; QToolButton *m_recordButton; + QMenu *m_featuresMenu; + QToolButton *m_clearButton; // elapsed time display @@ -117,6 +121,10 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent) d->m_profilerState = 0; d->m_viewContainer = 0; + d->m_recordButton = 0; + d->m_featuresMenu = 0; + d->m_clearButton = 0; + d->m_timeLabel = 0; qmlRegisterType<TimelineRenderer>("Monitor", 1, 0,"TimelineRenderer"); @@ -132,6 +140,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))); d->m_profilerConnections->setModelManager(d->m_profilerModelManager); Command *command = 0; @@ -247,6 +257,13 @@ 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_recordButton->setPopupMode(QToolButton::MenuButtonPopup); + setAvailableFeatures(d->m_profilerModelManager->availableFeatures()); + connect(d->m_featuresMenu, SIGNAL(triggered(QAction*)), + this, SLOT(toggleRecordingFeature(QAction*))); + setRecording(d->m_profilerState->clientRecording()); layout->addWidget(d->m_recordButton); @@ -326,6 +343,9 @@ void QmlProfilerTool::setRecording(bool recording) } else { d->m_recordingTimer.stop(); } + d->m_recordButton->menu()->setEnabled(!recording); + } else { + d->m_recordButton->menu()->setEnabled(true); } } @@ -508,6 +528,36 @@ void QmlProfilerTool::clientsDisconnected() // If the connection is closed while the app is still running, no special action is needed } +template<QmlDebug::ProfileFeature feature> +void QmlProfilerTool::updateFeaturesMenu(quint64 features) +{ + if (features & (1 << feature)) { + QAction *action = d->m_featuresMenu->addAction(tr(QmlProfilerModelManager::featureName( + static_cast<QmlDebug::ProfileFeature>(feature)))); + action->setCheckable(true); + action->setData(static_cast<uint>(feature)); + action->setChecked(d->m_profilerState->recordingFeatures() & (1 << feature)); + } + updateFeaturesMenu<static_cast<QmlDebug::ProfileFeature>(feature + 1)>(features); +} + +template<> +void QmlProfilerTool::updateFeaturesMenu<QmlDebug::MaximumProfileFeature>(quint64 features) +{ + Q_UNUSED(features); + return; +} + +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<QmlDebug::ProfileFeature>(0)>(features); + } +} + void QmlProfilerTool::profilerDataModelStateChanged() { switch (d->m_profilerModelManager->state()) { @@ -608,3 +658,20 @@ void QmlProfilerTool::serverRecordingChanged() d->m_clearButton->setEnabled(true); } } + +void QmlProfilerTool::toggleRecordingFeature(QAction *action) +{ + uint feature = action->data().toUInt(); + if (action->isChecked()) + d->m_profilerState->setRecordingFeatures( + d->m_profilerState->recordingFeatures() | (1 << feature)); + else + d->m_profilerState->setRecordingFeatures( + d->m_profilerState->recordingFeatures() & (~(1 << feature))); + + // Keep the menu open to allow for more features to be toggled + d->m_recordButton->showMenu(); +} + +} +} diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index 9c87a53054..2ba237a477 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -32,6 +32,7 @@ #include <analyzerbase/ianalyzertool.h> #include <analyzerbase/analyzerruncontrol.h> +#include "qmldebug/qmlprofilereventtypes.h" QT_BEGIN_NAMESPACE class QMessageBox; @@ -68,6 +69,7 @@ public slots: void clientRecordingChanged(); void serverRecordingChanged(); void clientsDisconnected(); + void setAvailableFeatures(quint64 features); void recordingButtonChanged(bool recording); void setRecording(bool recording); @@ -84,9 +86,13 @@ private slots: void showSaveDialog(); void showLoadDialog(); + void toggleRecordingFeature(QAction *action); + private: void clearDisplay(); void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString()); + template<QmlDebug::ProfileFeature feature> + void updateFeaturesMenu(quint64 features); class QmlProfilerToolPrivate; QmlProfilerToolPrivate *d; |