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>
This commit is contained in:
Ulf Hermann
2014-09-09 18:22:58 +02:00
parent 7290c43da1
commit 6d58de0bad
17 changed files with 214 additions and 19 deletions

View File

@@ -120,8 +120,31 @@ enum AnimationThread {
MaximumAnimationThread MaximumAnimationThread
}; };
enum ProfileFeature {
ProfileJavaScript,
ProfileMemory,
ProfilePixmapCache,
ProfileSceneGraph,
ProfileAnimations,
ProfilePainting,
ProfileCompiling,
ProfileCreating,
ProfileBinding,
ProfileHandlingSignal,
ProfileInputEvents,
MaximumProfileFeature
};
namespace Constants { namespace Constants {
const int QML_MIN_LEVEL = 1; // Set to 0 to remove the empty line between models in the timeline const int QML_MIN_LEVEL = 1; // Set to 0 to remove the empty line between models in the timeline
// Shorthand for all QML and JS range features.
const quint64 QML_JS_RANGE_FEATURES = (1 << ProfileCompiling) |
(1 << ProfileCreating) |
(1 << ProfileBinding) |
(1 << ProfileHandlingSignal) |
(1 << ProfileJavaScript);
} }
} // namespace QmlDebug } // namespace QmlDebug

View File

@@ -40,6 +40,7 @@ public:
, inProgressRanges(0) , inProgressRanges(0)
, maximumTime(0) , maximumTime(0)
, recording(false) , recording(false)
, features(0)
{ {
::memset(rangeCount, 0, MaximumRangeType * sizeof(int)); ::memset(rangeCount, 0, MaximumRangeType * sizeof(int));
} }
@@ -56,6 +57,7 @@ public:
int rangeCount[MaximumRangeType]; int rangeCount[MaximumRangeType];
qint64 maximumTime; qint64 maximumTime;
bool recording; bool recording;
quint64 features;
}; };
} // namespace QmlDebug } // namespace QmlDebug
@@ -68,16 +70,17 @@ void QmlProfilerTraceClientPrivate::sendRecordingStatus(int engineId)
{ {
QByteArray ba; QByteArray ba;
QDataStream stream(&ba, QIODevice::WriteOnly); QDataStream stream(&ba, QIODevice::WriteOnly);
stream << recording; stream << recording << engineId; // engineId -1 is OK. It means "all of them"
if (engineId != -1) if (recording)
stream << engineId; stream << features;
q->sendMessage(ba); q->sendMessage(ba);
} }
QmlProfilerTraceClient::QmlProfilerTraceClient(QmlDebugConnection *client) QmlProfilerTraceClient::QmlProfilerTraceClient(QmlDebugConnection *client, quint64 features)
: QmlDebugClient(QLatin1String("CanvasFrameRate"), client) : QmlDebugClient(QLatin1String("CanvasFrameRate"), client)
, d(new QmlProfilerTraceClientPrivate(this, client)) , d(new QmlProfilerTraceClientPrivate(this, client))
{ {
d->features = features;
connect(&d->engineControl, SIGNAL(engineAboutToBeAdded(int,QString)), connect(&d->engineControl, SIGNAL(engineAboutToBeAdded(int,QString)),
this, SLOT(sendRecordingStatus(int))); this, SLOT(sendRecordingStatus(int)));
} }
@@ -131,6 +134,11 @@ void QmlProfilerTraceClient::setRecording(bool v)
emit recordingChanged(v); emit recordingChanged(v);
} }
void QmlProfilerTraceClient::setFeatures(quint64 features)
{
d->features = features;
}
void QmlProfilerTraceClient::setRecordingFromServer(bool v) void QmlProfilerTraceClient::setRecordingFromServer(bool v)
{ {
if (v == d->recording) if (v == d->recording)

View File

@@ -50,7 +50,7 @@ class QMLDEBUG_EXPORT QmlProfilerTraceClient : public QmlDebug::QmlDebugClient
using QObject::event; using QObject::event;
public: public:
QmlProfilerTraceClient(QmlDebugConnection *client); QmlProfilerTraceClient(QmlDebugConnection *client, quint64 features);
~QmlProfilerTraceClient(); ~QmlProfilerTraceClient();
bool isEnabled() const; bool isEnabled() const;
@@ -60,6 +60,7 @@ public:
public slots: public slots:
void clearData(); void clearData();
void sendRecordingStatus(int engineId = -1); void sendRecordingStatus(int engineId = -1);
void setFeatures(quint64 features);
signals: signals:
void complete(qint64 maximumTime); void complete(qint64 maximumTime);

View File

@@ -59,6 +59,7 @@ void AbstractTimelineModel::setModelManager(QmlProfilerModelManager *modelManage
d->modelManager = modelManager; d->modelManager = modelManager;
connect(d->modelManager->qmlModel(),SIGNAL(changed()),this,SLOT(dataChanged())); connect(d->modelManager->qmlModel(),SIGNAL(changed()),this,SLOT(dataChanged()));
d->modelId = d->modelManager->registerModelProxy(); d->modelId = d->modelManager->registerModelProxy();
d->modelManager->announceFeatures(d->modelId, features());
} }
bool AbstractTimelineModel::isEmpty() const bool AbstractTimelineModel::isEmpty() const

View File

@@ -74,6 +74,7 @@ public:
virtual QVariantMap details(int index) const = 0; virtual QVariantMap details(int index) const = 0;
virtual int row(int index) const = 0; virtual int row(int index) const = 0;
virtual void loadData() = 0; virtual void loadData() = 0;
virtual quint64 features() const = 0;
// Methods which can optionally be implemented by child models. // Methods which can optionally be implemented by child models.
// returned map should contain "file", "line", "column" properties, or be empty // returned map should contain "file", "line", "column" properties, or be empty

View File

@@ -162,7 +162,8 @@ void QmlProfilerClientManager::enableServices()
disconnectClientSignals(); disconnectClientSignals();
d->profilerState->setServerRecording(false); // false by default (will be set to true when connected) d->profilerState->setServerRecording(false); // false by default (will be set to true when connected)
delete d->qmlclientplugin.data(); delete d->qmlclientplugin.data();
d->qmlclientplugin = new QmlProfilerTraceClient(d->connection); d->qmlclientplugin = new QmlProfilerTraceClient(d->connection,
d->profilerState->recordingFeatures());
delete d->v8clientplugin.data(); delete d->v8clientplugin.data();
d->v8clientplugin = new QV8ProfilerClient(d->connection); d->v8clientplugin = new QV8ProfilerClient(d->connection);
connectClientSignals(); connectClientSignals();
@@ -191,6 +192,8 @@ void QmlProfilerClientManager::connectClientSignals()
// fixme: this should be unified for both clients // fixme: this should be unified for both clients
connect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)), connect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)),
d->profilerState, SLOT(setServerRecording(bool))); d->profilerState, SLOT(setServerRecording(bool)));
connect(d->profilerState, SIGNAL(recordingFeaturesChanged(quint64)),
d->qmlclientplugin.data(), SLOT(setFeatures(quint64)));
} }
if (d->v8clientplugin) { if (d->v8clientplugin) {
connect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); connect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete()));
@@ -223,6 +226,8 @@ void QmlProfilerClientManager::disconnectClientSignals()
// fixme: this should be unified for both clients // fixme: this should be unified for both clients
disconnect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)), disconnect(d->qmlclientplugin.data(), SIGNAL(recordingChanged(bool)),
d->profilerState, SLOT(setServerRecording(bool))); d->profilerState, SLOT(setServerRecording(bool)));
disconnect(d->profilerState, SIGNAL(recordingFeaturesChanged(quint64)),
d->qmlclientplugin.data(), SLOT(setFeatures(quint64)));
} }
if (d->v8clientplugin) { if (d->v8clientplugin) {
disconnect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete())); disconnect(d->v8clientplugin.data(), SIGNAL(complete()), this, SLOT(v8Complete()));

View File

@@ -74,6 +74,8 @@ QmlProfilerEventsModelProxy::QmlProfilerEventsModelProxy(QmlProfilerModelManager
modelManager->setProxyCountWeight(d->modelId, 2); modelManager->setProxyCountWeight(d->modelId, 2);
d->acceptedTypes << QmlDebug::Compiling << QmlDebug::Creating << QmlDebug::Binding << QmlDebug::HandlingSignal << QmlDebug::Javascript; d->acceptedTypes << QmlDebug::Compiling << QmlDebug::Creating << QmlDebug::Binding << QmlDebug::HandlingSignal << QmlDebug::Javascript;
modelManager->announceFeatures(d->modelId, QmlDebug::Constants::QML_JS_RANGE_FEATURES);
} }
QmlProfilerEventsModelProxy::~QmlProfilerEventsModelProxy() QmlProfilerEventsModelProxy::~QmlProfilerEventsModelProxy()

View File

@@ -40,6 +40,19 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { 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) QmlProfilerDataState::QmlProfilerDataState(QmlProfilerModelManager *modelManager, QObject *parent)
@@ -163,6 +176,8 @@ public:
QVector <double> partialCounts; QVector <double> partialCounts;
QVector <int> partialCountWeights; QVector <int> partialCountWeights;
quint64 features;
int totalWeight; int totalWeight;
double progress; double progress;
double previousProgress; 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 qint64 QmlProfilerModelManager::estimatedProfilingTime() const
{ {
return d->estimatedTime; return d->estimatedTime;

View File

@@ -127,6 +127,9 @@ public:
int registerModelProxy(); int registerModelProxy();
void setProxyCountWeight(int proxyId, int weight); void setProxyCountWeight(int proxyId, int weight);
void modelProxyCountUpdated(int proxyId, qint64 count, qint64 max); 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; qint64 estimatedProfilingTime() const;
@@ -137,6 +140,7 @@ signals:
void dataAvailable(); void dataAvailable();
void requestDetailsForLocation(int eventType, const QmlDebug::QmlEventLocation &location); void requestDetailsForLocation(int eventType, const QmlDebug::QmlEventLocation &location);
void availableFeaturesChanged(quint64 features);
public slots: public slots:
void clear(); void clear();

View File

@@ -58,13 +58,18 @@ private:
}; };
PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent) PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent)
: AbstractTimelineModel(new PaintEventsModelProxyPrivate, tr("Animations"), QmlDebug::Event, : AbstractTimelineModel(new PaintEventsModelProxyPrivate,
QmlDebug::MaximumRangeType, parent) tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileAnimations)),
QmlDebug::Event, QmlDebug::MaximumRangeType, parent)
{ {
Q_D(PaintEventsModelProxy); Q_D(PaintEventsModelProxy);
d->maxGuiThreadAnimations = d->maxRenderThreadAnimations = 0; d->maxGuiThreadAnimations = d->maxRenderThreadAnimations = 0;
} }
quint64 PaintEventsModelProxy::features() const
{
return 1 << QmlDebug::ProfileAnimations;
}
void PaintEventsModelProxy::clear() void PaintEventsModelProxy::clear()
{ {

View File

@@ -75,6 +75,7 @@ public:
QVariantList labels() const; QVariantList labels() const;
QVariantMap details(int index) const; QVariantMap details(int index) const;
quint64 features() const;
private slots: private slots:
bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const; bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const;

View File

@@ -64,6 +64,7 @@ public:
QmlProfilerStateManager::QmlProfilerState m_currentState; QmlProfilerStateManager::QmlProfilerState m_currentState;
bool m_clientRecording; bool m_clientRecording;
bool m_serverRecording; bool m_serverRecording;
quint64 m_recordingFeatures;
}; };
QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) : QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) :
QObject(parent),d(new QmlProfilerStateManagerPrivate(this)) QObject(parent),d(new QmlProfilerStateManagerPrivate(this))
@@ -71,6 +72,7 @@ QmlProfilerStateManager::QmlProfilerStateManager(QObject *parent) :
d->m_currentState = Idle; d->m_currentState = Idle;
d->m_clientRecording = true; d->m_clientRecording = true;
d->m_serverRecording = false; d->m_serverRecording = false;
d->m_recordingFeatures = 0;
} }
QmlProfilerStateManager::~QmlProfilerStateManager() QmlProfilerStateManager::~QmlProfilerStateManager()
@@ -93,6 +95,11 @@ bool QmlProfilerStateManager::serverRecording()
return d->m_serverRecording; return d->m_serverRecording;
} }
quint64 QmlProfilerStateManager::recordingFeatures() const
{
return d->m_recordingFeatures;
}
QString QmlProfilerStateManager::currentStateAsString() QString QmlProfilerStateManager::currentStateAsString()
{ {
return stringForState(d->m_currentState); 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);
}
}
} }
} }

View File

@@ -56,6 +56,7 @@ public:
QmlProfilerState currentState(); QmlProfilerState currentState();
bool clientRecording(); bool clientRecording();
bool serverRecording(); bool serverRecording();
quint64 recordingFeatures() const;
QString currentStateAsString(); QString currentStateAsString();
@@ -63,11 +64,13 @@ signals:
void stateChanged(); void stateChanged();
void clientRecordingChanged(); void clientRecordingChanged();
void serverRecordingChanged(); void serverRecordingChanged();
void recordingFeaturesChanged(quint64);
public slots: public slots:
void setCurrentState(QmlProfilerState newState); void setCurrentState(QmlProfilerState newState);
void setClientRecording(bool recording); void setClientRecording(bool recording);
void setServerRecording(bool recording); void setServerRecording(bool recording);
void setRecordingFeatures(quint64 features);
private: private:
class QmlProfilerStateManagerPrivate; class QmlProfilerStateManagerPrivate;

View File

@@ -44,6 +44,15 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { 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 class RangeTimelineModel::RangeTimelineModelPrivate : public AbstractTimelineModelPrivate
{ {
public: public:
@@ -70,6 +79,12 @@ RangeTimelineModel::RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *p
d->contractedRows = 1; d->contractedRows = 1;
} }
quint64 RangeTimelineModel::features() const
{
Q_D(const RangeTimelineModel);
return 1 << RangeFeatures[d->rangeType];
}
void RangeTimelineModel::clear() void RangeTimelineModel::clear()
{ {
Q_D(RangeTimelineModel); Q_D(RangeTimelineModel);
@@ -222,16 +237,19 @@ int RangeTimelineModel::rowCount() const
return d->contractedRows; return d->contractedRows;
} }
QString RangeTimelineModel::categoryLabel(int categoryIndex) QString RangeTimelineModel::categoryLabel(QmlDebug::RangeType rangeType)
{ {
switch (categoryIndex) { switch (rangeType) {
case 0: return QCoreApplication::translate("MainView", "Painting"); break; case QmlDebug::Painting:
case 1: return QCoreApplication::translate("MainView", "Compiling"); break; case QmlDebug::Compiling:
case 2: return QCoreApplication::translate("MainView", "Creating"); break; case QmlDebug::Creating:
case 3: return QCoreApplication::translate("MainView", "Binding"); break; case QmlDebug::Binding:
case 4: return QCoreApplication::translate("MainView", "Handling Signal"); break; case QmlDebug::HandlingSignal:
case 5: return QCoreApplication::translate("MainView", "JavaScript"); break; case QmlDebug::Javascript:
default: return QString(); return QCoreApplication::translate("MainView",
QmlProfilerModelManager::featureName(RangeFeatures[rangeType]));
default:
return QString();
} }
} }

View File

@@ -72,7 +72,8 @@ public:
// QML interface // QML interface
int rowCount() const; int rowCount() const;
static QString categoryLabel(int categoryIndex); static QString categoryLabel(QmlDebug::RangeType categoryIndex);
quint64 features() const;
int row(int index) const; int row(int index) const;
int eventId(int index) const; int eventId(int index) const;

View File

@@ -81,11 +81,13 @@ using namespace Core;
using namespace Core::Constants; using namespace Core::Constants;
using namespace Analyzer; using namespace Analyzer;
using namespace Analyzer::Constants; using namespace Analyzer::Constants;
using namespace QmlProfiler::Internal;
using namespace QmlProfiler::Constants; using namespace QmlProfiler::Constants;
using namespace QmlDebug; using namespace QmlDebug;
using namespace ProjectExplorer; using namespace ProjectExplorer;
namespace QmlProfiler {
namespace Internal {
class QmlProfilerTool::QmlProfilerToolPrivate class QmlProfilerTool::QmlProfilerToolPrivate
{ {
public: public:
@@ -96,6 +98,8 @@ public:
QmlProfilerViewManager *m_viewContainer; QmlProfilerViewManager *m_viewContainer;
Utils::FileInProjectFinder m_projectFinder; Utils::FileInProjectFinder m_projectFinder;
QToolButton *m_recordButton; QToolButton *m_recordButton;
QMenu *m_featuresMenu;
QToolButton *m_clearButton; QToolButton *m_clearButton;
// elapsed time display // elapsed time display
@@ -117,6 +121,10 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_profilerState = 0; d->m_profilerState = 0;
d->m_viewContainer = 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"); qmlRegisterType<TimelineRenderer>("Monitor", 1, 0,"TimelineRenderer");
@@ -132,6 +140,8 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this); d->m_profilerModelManager = new QmlProfilerModelManager(&d->m_projectFinder, this);
connect(d->m_profilerModelManager, SIGNAL(stateChanged()), this, SLOT(profilerDataModelStateChanged())); 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(error(QString)), this, SLOT(showErrorDialog(QString)));
connect(d->m_profilerModelManager, SIGNAL(availableFeaturesChanged(quint64)),
this, SLOT(setAvailableFeatures(quint64)));
d->m_profilerConnections->setModelManager(d->m_profilerModelManager); d->m_profilerConnections->setModelManager(d->m_profilerModelManager);
Command *command = 0; Command *command = 0;
@@ -247,6 +257,13 @@ QWidget *QmlProfilerTool::createWidgets()
connect(d->m_recordButton,SIGNAL(clicked(bool)), this, SLOT(recordingButtonChanged(bool))); connect(d->m_recordButton,SIGNAL(clicked(bool)), this, SLOT(recordingButtonChanged(bool)));
d->m_recordButton->setChecked(true); 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()); setRecording(d->m_profilerState->clientRecording());
layout->addWidget(d->m_recordButton); layout->addWidget(d->m_recordButton);
@@ -326,6 +343,9 @@ void QmlProfilerTool::setRecording(bool recording)
} else { } else {
d->m_recordingTimer.stop(); 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 // 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() void QmlProfilerTool::profilerDataModelStateChanged()
{ {
switch (d->m_profilerModelManager->state()) { switch (d->m_profilerModelManager->state()) {
@@ -608,3 +658,20 @@ void QmlProfilerTool::serverRecordingChanged()
d->m_clearButton->setEnabled(true); 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();
}
}
}

View File

@@ -32,6 +32,7 @@
#include <analyzerbase/ianalyzertool.h> #include <analyzerbase/ianalyzertool.h>
#include <analyzerbase/analyzerruncontrol.h> #include <analyzerbase/analyzerruncontrol.h>
#include "qmldebug/qmlprofilereventtypes.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QMessageBox; class QMessageBox;
@@ -68,6 +69,7 @@ public slots:
void clientRecordingChanged(); void clientRecordingChanged();
void serverRecordingChanged(); void serverRecordingChanged();
void clientsDisconnected(); void clientsDisconnected();
void setAvailableFeatures(quint64 features);
void recordingButtonChanged(bool recording); void recordingButtonChanged(bool recording);
void setRecording(bool recording); void setRecording(bool recording);
@@ -84,9 +86,13 @@ private slots:
void showSaveDialog(); void showSaveDialog();
void showLoadDialog(); void showLoadDialog();
void toggleRecordingFeature(QAction *action);
private: private:
void clearDisplay(); void clearDisplay();
void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString()); void populateFileFinder(QString projectDirectory = QString(), QString activeSysroot = QString());
template<QmlDebug::ProfileFeature feature>
void updateFeaturesMenu(quint64 features);
class QmlProfilerToolPrivate; class QmlProfilerToolPrivate;
QmlProfilerToolPrivate *d; QmlProfilerToolPrivate *d;