From 1de6e7b8e0ee465f642e1b2f5a14611e52a7e8c2 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 3 Sep 2014 19:28:35 +0200 Subject: Select specific features to be recorded when profiling QML Some features, like the memory profiler, create huge amounts of data. Often enough, we're not actually interested in all the data available from the profiler and collecting it all can lead to excessive memory consumption. This change enables us to optionally turn various aspects of QML profiling off. Task-number: QTBUG-41118 Change-Id: I7bb223414e24eb903124ffa6e0896af6ce974e49 Reviewed-by: Gunnar Sletta --- src/qml/debugger/qqmlabstractprofileradapter.cpp | 10 +++--- src/qml/debugger/qqmlabstractprofileradapter_p.h | 13 +++---- src/qml/debugger/qqmlprofiler.cpp | 14 ++++---- src/qml/debugger/qqmlprofiler_p.h | 41 +++++++++++++---------- src/qml/debugger/qqmlprofilerdefinitions_p.h | 16 +++++++++ src/qml/debugger/qqmlprofilerservice.cpp | 25 ++++++++------ src/qml/debugger/qqmlprofilerservice_p.h | 4 +-- src/qml/debugger/qv4profileradapter.cpp | 7 ++-- src/qml/jsruntime/qv4profiling.cpp | 38 +++++++++++---------- src/qml/jsruntime/qv4profiling_p.h | 18 +++++++--- src/qml/qml/qqmlobjectcreator.cpp | 2 +- src/quick/items/qquickview.cpp | 10 +++--- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 4 +-- src/quick/scenegraph/coreapi/qsgrenderer.cpp | 6 ++-- src/quick/scenegraph/qsgadaptationlayer.cpp | 3 +- src/quick/scenegraph/qsgrenderloop.cpp | 3 +- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 6 ++-- src/quick/scenegraph/qsgwindowsrenderloop.cpp | 2 +- src/quick/scenegraph/util/qsgatlastexture.cpp | 3 +- src/quick/scenegraph/util/qsgtexture.cpp | 3 +- src/quick/util/qquickpixmapcache.cpp | 28 +++++++++------- src/quick/util/qquickprofiler.cpp | 18 +++++----- src/quick/util/qquickprofiler_p.h | 21 ++++++++---- src/quickwidgets/qquickwidget.cpp | 14 ++++---- 24 files changed, 181 insertions(+), 128 deletions(-) diff --git a/src/qml/debugger/qqmlabstractprofileradapter.cpp b/src/qml/debugger/qqmlabstractprofileradapter.cpp index 1267503226..165772335a 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter.cpp +++ b/src/qml/debugger/qqmlabstractprofileradapter.cpp @@ -69,13 +69,13 @@ QT_BEGIN_NAMESPACE * If the profiler's thread is waiting for an initial start signal we can emit the signal over a * \c Qt::DirectConnection to avoid the delay of the event loop. */ -void QQmlAbstractProfilerAdapter::startProfiling() +void QQmlAbstractProfilerAdapter::startProfiling(quint64 features) { if (waiting) - emit profilingEnabledWhileWaiting(); + emit profilingEnabledWhileWaiting(features); else - emit profilingEnabled(); - running = true; + emit profilingEnabled(features); + featuresEnabled = features; } /*! @@ -90,7 +90,7 @@ void QQmlAbstractProfilerAdapter::stopProfiling() { emit profilingDisabledWhileWaiting(); else emit profilingDisabled(); - running = false; + featuresEnabled = 0; } /*! diff --git a/src/qml/debugger/qqmlabstractprofileradapter_p.h b/src/qml/debugger/qqmlabstractprofileradapter_p.h index f06d51e8f7..03f6645178 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter_p.h +++ b/src/qml/debugger/qqmlabstractprofileradapter_p.h @@ -59,12 +59,12 @@ class Q_QML_PRIVATE_EXPORT QQmlAbstractProfilerAdapter : public QObject, public public: QQmlAbstractProfilerAdapter(QQmlProfilerService *service) : - service(service), waiting(true), running(false) {} + service(service), waiting(true), featuresEnabled(0) {} virtual ~QQmlAbstractProfilerAdapter() {} virtual qint64 sendMessages(qint64 until, QList &messages) = 0; - void startProfiling(); + void startProfiling(quint64 features); void stopProfiling(); @@ -73,13 +73,14 @@ public: void stopWaiting() { waiting = false; } void startWaiting() { waiting = true; } - bool isRunning() const { return running; } + bool isRunning() const { return featuresEnabled != 0; } + quint64 features() const { return featuresEnabled; } void synchronize(const QElapsedTimer &t) { emit referenceTimeKnown(t); } signals: - void profilingEnabled(); - void profilingEnabledWhileWaiting(); + void profilingEnabled(quint64 features); + void profilingEnabledWhileWaiting(quint64 features); void profilingDisabled(); void profilingDisabledWhileWaiting(); @@ -92,7 +93,7 @@ protected: private: bool waiting; - bool running; + quint64 featuresEnabled; }; QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp index 3a647e704d..b102201ff1 100644 --- a/src/qml/debugger/qqmlprofiler.cpp +++ b/src/qml/debugger/qqmlprofiler.cpp @@ -82,9 +82,9 @@ QQmlProfilerAdapter::QQmlProfilerAdapter(QQmlProfilerService *service, QQmlEngin QQmlAbstractProfilerAdapter(service) { engine->enableProfiler(); - connect(this, SIGNAL(profilingEnabled()), engine->profiler, SLOT(startProfiling())); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), - engine->profiler, SLOT(startProfiling()), Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabled(quint64)), engine->profiler, SLOT(startProfiling(quint64))); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling())); connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()), Qt::DirectConnection); @@ -111,21 +111,21 @@ void QQmlProfilerAdapter::receiveData(const QList &new_data) } -QQmlProfiler::QQmlProfiler() : enabled(false) +QQmlProfiler::QQmlProfiler() : featuresEnabled(0) { static int metatype = qRegisterMetaType >(); Q_UNUSED(metatype); m_timer.start(); } -void QQmlProfiler::startProfiling() +void QQmlProfiler::startProfiling(quint64 features) { - enabled = true; + featuresEnabled = features; } void QQmlProfiler::stopProfiling() { - enabled = false; + featuresEnabled = false; reportData(); m_data.clear(); } diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 02cdbf0a4e..13e6b8ddae 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -56,14 +56,14 @@ QT_BEGIN_NAMESPACE -#define Q_QML_PROFILE_IF_ENABLED(profiler, Code)\ - if (profiler && profiler->enabled) {\ +#define Q_QML_PROFILE_IF_ENABLED(feature, profiler, Code)\ + if (profiler && (profiler->featuresEnabled & (1 << feature))) {\ Code;\ } else\ (void)0 -#define Q_QML_PROFILE(profiler, Method)\ - Q_QML_PROFILE_IF_ENABLED(profiler, profiler->Method) +#define Q_QML_PROFILE(feature, profiler, Method)\ + Q_QML_PROFILE_IF_ENABLED(feature, profiler, profiler->Method) // This struct is somewhat dangerous to use: // The messageType is a bit field. You can pack multiple messages into @@ -162,10 +162,10 @@ public: QQmlProfiler(); - bool enabled; + quint64 featuresEnabled; public slots: - void startProfiling(); + void startProfiling(quint64 features); void stopProfiling(); void reportData(); void setTimer(const QElapsedTimer &timer) { m_timer = timer; } @@ -204,12 +204,14 @@ struct QQmlBindingProfiler : public QQmlProfilerHelper { QQmlBindingProfiler(QQmlProfiler *profiler, const QString &url, int line, int column) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(profiler, startBinding(url, line, column)); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, + startBinding(url, line, column)); } ~QQmlBindingProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, + endRange()); } }; @@ -217,12 +219,14 @@ struct QQmlHandlingSignalProfiler : public QQmlProfilerHelper { QQmlHandlingSignalProfiler(QQmlProfiler *profiler, QQmlBoundSignalExpression *expression) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(profiler, startHandlingSignal(expression->sourceLocation())); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler, + startHandlingSignal(expression->sourceLocation())); } ~QQmlHandlingSignalProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler, + endRange()); } }; @@ -230,12 +234,12 @@ struct QQmlCompilingProfiler : public QQmlProfilerHelper { QQmlCompilingProfiler(QQmlProfiler *profiler, const QString &name) : QQmlProfilerHelper(profiler) { - Q_QML_PROFILE(profiler, startCompiling(name)); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, startCompiling(name)); } ~QQmlCompilingProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, endRange()); } }; @@ -278,20 +282,20 @@ private: QFiniteStack ranges; }; -#define Q_QML_OC_PROFILE(profilerMember, Code)\ - Q_QML_PROFILE_IF_ENABLED(profilerMember.profiler, Code) +#define Q_QML_OC_PROFILE(member, Code)\ + Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, member.profiler, Code) class QQmlObjectCreationProfiler : public QQmlVmeProfiler::Data { public: QQmlObjectCreationProfiler(QQmlProfiler *profiler) : profiler(profiler) { - Q_QML_PROFILE(profiler, startCreating()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, startCreating()); } ~QQmlObjectCreationProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange()); } void update(const QString &typeName, const QUrl &url, int line, int column) @@ -312,7 +316,7 @@ public: QQmlObjectCompletionProfiler(QQmlVmeProfiler *parent) : profiler(parent->profiler) { - Q_QML_PROFILE_IF_ENABLED(profiler, { + Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, { QQmlVmeProfiler::Data data = parent->pop(); profiler->startCreating(data.m_typeName, data.m_url, data.m_line, data.m_column); }); @@ -320,7 +324,8 @@ public: ~QQmlObjectCompletionProfiler() { - Q_QML_PROFILE(profiler, endRange()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, + endRange()); } private: QQmlProfiler *profiler; diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h index 92bab93300..e8ee98433d 100644 --- a/src/qml/debugger/qqmlprofilerdefinitions_p.h +++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h @@ -122,6 +122,22 @@ struct QQmlProfilerDefinitions { }; typedef QV4::Profiling::MemoryType MemoryType; + + enum ProfileFeature { + ProfileJavaScript = QV4::Profiling::FeatureFunctionCall, + ProfileMemory = QV4::Profiling::FeatureMemoryAllocation, + ProfilePixmapCache, + ProfileSceneGraph, + ProfileAnimations, + ProfilePainting, + ProfileCompiling, + ProfileCreating, + ProfileBinding, + ProfileHandlingSignal, + ProfileInputEvents, + + MaximumProfileFeature + }; }; QT_END_NAMESPACE diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index 6157d2f191..5ec8178f32 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -171,12 +171,12 @@ void QQmlProfilerService::addGlobalProfiler(QQmlAbstractProfilerAdapter *profile // Global profiler, not connected to a specific engine. // Global profilers are started whenever any engine profiler is started and stopped when // all engine profilers are stopped. - foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers) { - if (engineProfiler->isRunning()) { - profiler->startProfiling(); - break; - } - } + quint64 features = 0; + foreach (QQmlAbstractProfilerAdapter *engineProfiler, m_engineProfilers) + features |= engineProfiler->features(); + + if (features != 0) + profiler->startProfiling(features); } void QQmlProfilerService::removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler) @@ -206,7 +206,7 @@ void QQmlProfilerService::removeProfilerFromStartTimes(const QQmlAbstractProfile * * If any engine profiler is started like that also start all global profilers. */ -void QQmlProfilerService::startProfiling(QQmlEngine *engine) +void QQmlProfilerService::startProfiling(QQmlEngine *engine, quint64 features) { QMutexLocker lock(configMutex()); @@ -218,7 +218,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) if (engine != 0) { foreach (QQmlAbstractProfilerAdapter *profiler, m_engineProfilers.values(engine)) { if (!profiler->isRunning()) { - profiler->startProfiling(); + profiler->startProfiling(features); startedAny = true; } } @@ -230,7 +230,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) i != m_engineProfilers.end(); ++i) { if (!i.value()->isRunning()) { engines << i.key(); - i.value()->startProfiling(); + i.value()->startProfiling(features); startedAny = true; } } @@ -241,7 +241,7 @@ void QQmlProfilerService::startProfiling(QQmlEngine *engine) if (startedAny) { foreach (QQmlAbstractProfilerAdapter *profiler, m_globalProfilers) { if (!profiler->isRunning()) - profiler->startProfiling(); + profiler->startProfiling(features); } } @@ -359,14 +359,17 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) QQmlDebugStream stream(&rwData, QIODevice::ReadOnly); int engineId = -1; + quint64 features = std::numeric_limits::max(); bool enabled; stream >> enabled; if (!stream.atEnd()) stream >> engineId; + if (!stream.atEnd()) + stream >> features; // If engineId == -1 objectForId() and then the cast will return 0. if (enabled) - startProfiling(qobject_cast(objectForId(engineId))); + startProfiling(qobject_cast(objectForId(engineId)), features); else stopProfiling(qobject_cast(objectForId(engineId))); diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index 5405905861..c4c40adc4f 100644 --- a/src/qml/debugger/qqmlprofilerservice_p.h +++ b/src/qml/debugger/qqmlprofilerservice_p.h @@ -78,8 +78,8 @@ public: void addGlobalProfiler(QQmlAbstractProfilerAdapter *profiler); void removeGlobalProfiler(QQmlAbstractProfilerAdapter *profiler); - void startProfiling(QQmlEngine *engine = 0); - void stopProfiling(QQmlEngine *engine = 0); + void startProfiling(QQmlEngine *engine, quint64 features = std::numeric_limits::max()); + void stopProfiling(QQmlEngine *engine); QQmlProfilerService(); ~QQmlProfilerService(); diff --git a/src/qml/debugger/qv4profileradapter.cpp b/src/qml/debugger/qv4profileradapter.cpp index 19a6ea3e74..a5492ce805 100644 --- a/src/qml/debugger/qv4profileradapter.cpp +++ b/src/qml/debugger/qv4profileradapter.cpp @@ -41,9 +41,10 @@ QV4ProfilerAdapter::QV4ProfilerAdapter(QQmlProfilerService *service, QV4::Execut QQmlAbstractProfilerAdapter(service) { engine->enableProfiler(); - connect(this, SIGNAL(profilingEnabled()), engine->profiler, SLOT(startProfiling())); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), engine->profiler, SLOT(startProfiling()), - Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabled(quint64)), + engine->profiler, SLOT(startProfiling(quint64))); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + engine->profiler, SLOT(startProfiling(quint64)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), engine->profiler, SLOT(stopProfiling())); connect(this, SIGNAL(profilingDisabledWhileWaiting()), engine->profiler, SLOT(stopProfiling()), Qt::DirectConnection); diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index 693af854da..f1bd1d55d9 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -53,7 +53,7 @@ FunctionCallProperties FunctionCall::resolve() const } -Profiler::Profiler(QV4::ExecutionEngine *engine) : enabled(false), m_engine(engine) +Profiler::Profiler(QV4::ExecutionEngine *engine) : featuresEnabled(0), m_engine(engine) { static int metatype = qRegisterMetaType >(); static int metatype2 = qRegisterMetaType >(); @@ -69,7 +69,7 @@ struct FunctionCallComparator { void Profiler::stopProfiling() { - enabled = false; + featuresEnabled = 0; reportData(); } @@ -85,27 +85,29 @@ void Profiler::reportData() emit dataReady(resolved, m_memory_data); } -void Profiler::startProfiling() +void Profiler::startProfiling(quint64 features) { - if (!enabled) { + if (featuresEnabled == 0) { m_data.clear(); m_memory_data.clear(); - qint64 timestamp = m_timer.nsecsElapsed(); - MemoryAllocationProperties heap = {timestamp, - (qint64)m_engine->memoryManager->getAllocatedMem(), - HeapPage}; - m_memory_data.append(heap); - MemoryAllocationProperties small = {timestamp, - (qint64)m_engine->memoryManager->getUsedMem(), - SmallItem}; - m_memory_data.append(small); - MemoryAllocationProperties large = {timestamp, - (qint64)m_engine->memoryManager->getLargeItemsMem(), - LargeItem}; - m_memory_data.append(large); + if (features & (1 << FeatureMemoryAllocation)) { + qint64 timestamp = m_timer.nsecsElapsed(); + MemoryAllocationProperties heap = {timestamp, + (qint64)m_engine->memoryManager->getAllocatedMem(), + HeapPage}; + m_memory_data.append(heap); + MemoryAllocationProperties small = {timestamp, + (qint64)m_engine->memoryManager->getUsedMem(), + SmallItem}; + m_memory_data.append(small); + MemoryAllocationProperties large = {timestamp, + (qint64)m_engine->memoryManager->getLargeItemsMem(), + LargeItem}; + m_memory_data.append(large); + } - enabled = true; + featuresEnabled = features; } } diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h index f115137c86..8224f8a851 100644 --- a/src/qml/jsruntime/qv4profiling_p.h +++ b/src/qml/jsruntime/qv4profiling_p.h @@ -46,6 +46,11 @@ namespace QV4 { namespace Profiling { +enum Features { + FeatureFunctionCall, + FeatureMemoryAllocation +}; + enum MemoryType { HeapPage, LargeItem, @@ -106,15 +111,18 @@ private: }; #define Q_V4_PROFILE_ALLOC(engine, size, type)\ - (engine->profiler && engine->profiler->enabled ?\ + (engine->profiler &&\ + (engine->profiler->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\ engine->profiler->trackAlloc(size, type) : size) #define Q_V4_PROFILE_DEALLOC(engine, pointer, size, type) \ - (engine->profiler && engine->profiler->enabled ?\ + (engine->profiler &&\ + (engine->profiler->featuresEnabled & (1 << Profiling::FeatureMemoryAllocation)) ?\ engine->profiler->trackDealloc(pointer, size, type) : pointer) #define Q_V4_PROFILE(engine, ctx, function)\ - ((engine->profiler && engine->profiler->enabled) ?\ + (engine->profiler &&\ + (engine->profiler->featuresEnabled & (1 << Profiling::FeatureFunctionCall)) ?\ Profiling::FunctionCallProfiler::profileCall(engine->profiler, ctx, function) :\ function->code(ctx, function->codeData)) @@ -138,11 +146,11 @@ public: return pointer; } - bool enabled; + quint64 featuresEnabled; public slots: void stopProfiling(); - void startProfiling(); + void startProfiling(quint64 features); void reportData(); void setTimer(const QElapsedTimer &timer) { m_timer = timer; } diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 0ad60e01ab..a827e96ab1 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -93,7 +93,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile sharedState->rootContext = 0; QQmlProfiler *profiler = QQmlEnginePrivate::get(engine)->profiler; - Q_QML_PROFILE_IF_ENABLED(profiler, + Q_QML_PROFILE_IF_ENABLED(QQmlProfilerDefinitions::ProfileCreating, profiler, sharedState->profiler.init(profiler, compiledData->totalParserStatusCount)); } diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index 91a6468593..a55d056c75 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -594,7 +594,7 @@ void QQuickView::resizeEvent(QResizeEvent *e) /*! \reimp */ void QQuickView::keyPressEvent(QKeyEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::keyPressEvent(e); } @@ -602,7 +602,7 @@ void QQuickView::keyPressEvent(QKeyEvent *e) /*! \reimp */ void QQuickView::keyReleaseEvent(QKeyEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::keyReleaseEvent(e); } @@ -610,7 +610,7 @@ void QQuickView::keyReleaseEvent(QKeyEvent *e) /*! \reimp */ void QQuickView::mouseMoveEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::mouseMoveEvent(e); } @@ -618,7 +618,7 @@ void QQuickView::mouseMoveEvent(QMouseEvent *e) /*! \reimp */ void QQuickView::mousePressEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::mousePressEvent(e); } @@ -626,7 +626,7 @@ void QQuickView::mousePressEvent(QMouseEvent *e) /*! \reimp */ void QQuickView::mouseReleaseEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QQuickWindow::mouseReleaseEvent(e); } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index ecd450bcc8..0a39188b24 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -124,7 +124,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterial(QSGMaterial *material) if (shader) return shader; - if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::enabled) + if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) qsg_renderer_timer.start(); QSGMaterialShader *s = material->createShader(); @@ -169,7 +169,7 @@ ShaderManager::Shader *ShaderManager::prepareMaterialNoRewrite(QSGMaterial *mate if (shader) return shader; - if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::enabled) + if (QSG_LOG_TIME_COMPILATION().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) qsg_renderer_timer.start(); QSGMaterialShader *s = static_cast(material->createShader()); diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index d62802e854..dd089425f6 100644 --- a/src/quick/scenegraph/coreapi/qsgrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgrenderer.cpp @@ -176,7 +176,8 @@ void QSGRenderer::renderScene(const QSGBindable &bindable) m_is_rendering = true; - bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) frameTimer.start(); qint64 bindTime = 0; @@ -272,7 +273,8 @@ void QSGRenderer::preprocess() } } - bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled()|| QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERER().isDebugEnabled()|| + QQuickProfiler::profilingSceneGraph(); if (profileFrames) preprocessTime = frameTimer.nsecsElapsed(); diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index faf2762acc..fb9fe00ee5 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -153,7 +153,8 @@ void QSGDistanceFieldGlyphCache::update() if (m_pendingGlyphs.isEmpty()) return; - bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) qsg_render_timer.start(); diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index dc0939c023..4428918da5 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -362,7 +362,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) } QElapsedTimer renderTimer; qint64 renderTime = 0, syncTime = 0, polishTime = 0; - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) renderTimer.start(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 4e70c3f0a2..3866ed9a2b 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -521,7 +521,8 @@ void QSGRenderThread::sync(bool inExpose) void QSGRenderThread::syncAndRender() { - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) { sinceLastTime = threadTimer.nsecsElapsed(); threadTimer.start(); @@ -1087,7 +1088,8 @@ void QSGThreadedRenderLoop::polishAndSync(Window *w, bool inExpose) qint64 polishTime = 0; qint64 waitTime = 0; qint64 syncTime = 0; - bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) timer.start(); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index f2731e347b..de1160064d 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -55,7 +55,7 @@ extern Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_ static QElapsedTimer qsg_render_timer; #define QSG_RENDER_TIMING_SAMPLE(sampleName) \ qint64 sampleName = 0; \ - if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::enabled) \ + if (QSG_LOG_TIME_RENDERLOOP().isDebugEnabled() || QQuickProfiler::profilingSceneGraph()) \ sampleName = qsg_render_timer.nsecsElapsed() diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index a9cbbe1dc3..5edcb5d67a 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -377,7 +377,8 @@ void Atlas::bind(QSGTexture::Filtering filtering) // Upload all pending images.. for (int i=0; iclose(); } - Q_QUICK_PROFILE(pixmapStateChanged(job->url)); + PIXMAP_PROFILE(pixmapStateChanged(job->url)); // deleteLater, since not owned by this thread job->deleteLater(); } @@ -512,7 +514,7 @@ void QQuickPixmapReader::processJobs() runningJob->loading = true; QUrl url = runningJob->url; - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); QSize requestSize = runningJob->requestSize; locker.unlock(); @@ -660,7 +662,7 @@ void QQuickPixmapReader::cancel(QQuickPixmapReply *reply) // If loading was started (reply removed from jobs) but the reply was never processed // (otherwise it would have deleted itself) we need to profile an error. if (jobs.removeAll(reply) == 0) { - Q_QUICK_PROFILE(pixmapStateChanged(reply->url)); + PIXMAP_PROFILE(pixmapStateChanged(reply->url)); } delete reply; } @@ -894,12 +896,12 @@ bool QQuickPixmapReply::event(QEvent *event) if (data->pixmapStatus == QQuickPixmap::Ready) { data->textureFactory = de->textureFactory; data->implicitSize = de->implicitSize; - Q_QUICK_PROFILE(pixmapLoadingFinished(data->url, + PIXMAP_PROFILE(pixmapLoadingFinished(data->url, data->textureFactory != 0 && data->textureFactory->textureSize().isValid() ? data->textureFactory->textureSize() : (data->requestSize.isValid() ? data->requestSize : data->implicitSize))); } else { - Q_QUICK_PROFILE(pixmapStateChanged(data->url)); + PIXMAP_PROFILE(pixmapStateChanged(data->url)); data->errorString = de->errorString; data->removeFromCache(); // We don't continue to cache error'd pixmaps } @@ -907,7 +909,7 @@ bool QQuickPixmapReply::event(QEvent *event) data->reply = 0; emit finished(); } else { - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); } delete this; @@ -927,7 +929,7 @@ int QQuickPixmapData::cost() const void QQuickPixmapData::addref() { ++refCount; - Q_QUICK_PROFILE(pixmapCountChanged(url, refCount)); + PIXMAP_PROFILE(pixmapCountChanged(url, refCount)); if (prevUnreferencedPtr) pixmapStore()->referencePixmap(this); } @@ -936,7 +938,7 @@ void QQuickPixmapData::release() { Q_ASSERT(refCount > 0); --refCount; - Q_QUICK_PROFILE(pixmapCountChanged(url, refCount)); + PIXMAP_PROFILE(pixmapCountChanged(url, refCount)); if (refCount == 0) { if (reply) { QQuickPixmapReply *cancelReply = reply; @@ -967,7 +969,7 @@ void QQuickPixmapData::addToCache() QQuickPixmapKey key = { &url, &requestSize }; pixmapStore()->m_cache.insert(key, this); inCache = true; - Q_QUICK_PROFILE(pixmapCountChanged( + PIXMAP_PROFILE(pixmapCountChanged( url, pixmapStore()->m_cache.count())); } } @@ -978,7 +980,7 @@ void QQuickPixmapData::removeFromCache() QQuickPixmapKey key = { &url, &requestSize }; pixmapStore()->m_cache.remove(key); inCache = false; - Q_QUICK_PROFILE(pixmapCountChanged( + PIXMAP_PROFILE(pixmapCountChanged( url, pixmapStore()->m_cache.count())); } } @@ -1257,16 +1259,16 @@ void QQuickPixmap::load(QQmlEngine *engine, const QUrl &url, const QSize &reques if (!(options & QQuickPixmap::Asynchronous)) { bool ok = false; - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); d = createPixmapDataSync(this, engine, url, requestSize, &ok); if (ok) { - Q_QUICK_PROFILE(pixmapLoadingFinished(url, QSize(width(), height()))); + PIXMAP_PROFILE(pixmapLoadingFinished(url, QSize(width(), height()))); if (options & QQuickPixmap::Cache) d->addToCache(); return; } if (d) { // loadable, but encountered error while loading - Q_QUICK_PROFILE(pixmapStateChanged(url)); + PIXMAP_PROFILE(pixmapStateChanged(url)); return; } } diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp index 604d6e5cb1..3b34b7550b 100644 --- a/src/quick/util/qquickprofiler.cpp +++ b/src/quick/util/qquickprofiler.cpp @@ -40,7 +40,7 @@ QT_BEGIN_NAMESPACE // instance will be set, unset in constructor. Allows static methods to be inlined. QQuickProfiler *QQuickProfiler::s_instance = 0; -bool QQuickProfiler::enabled = false; +quint64 QQuickProfiler::featuresEnabled = 0; // convert to QByteArrays that can be sent to the debug client // use of QDataStream can skew results @@ -129,7 +129,7 @@ void QQuickProfiler::initialize() void animationTimerCallback(qint64 delta) { - Q_QUICK_PROFILE(animationFrame(delta, + Q_QUICK_PROFILE(QQuickProfiler::ProfileAnimations, animationFrame(delta, QThread::currentThread() == QCoreApplication::instance()->thread() ? QQuickProfiler::GuiThread : QQuickProfiler::RenderThread)); } @@ -158,10 +158,10 @@ QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) : m_timer.start(); // We can always do DirectConnection here as all methods are protected by mutexes - connect(this, SIGNAL(profilingEnabled()), this, SLOT(startProfilingImpl()), - Qt::DirectConnection); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), this, SLOT(startProfilingImpl()), + connect(this, SIGNAL(profilingEnabled(quint64)), this, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); + connect(this, SIGNAL(profilingEnabledWhileWaiting(quint64)), + this, SLOT(startProfilingImpl(quint64)), Qt::DirectConnection); connect(this, SIGNAL(referenceTimeKnown(QElapsedTimer)), this, SLOT(setTimer(QElapsedTimer)), Qt::DirectConnection); connect(this, SIGNAL(profilingDisabled()), this, SLOT(stopProfilingImpl()), @@ -179,23 +179,23 @@ QQuickProfiler::QQuickProfiler(QQmlProfilerService *service) : QQuickProfiler::~QQuickProfiler() { QMutexLocker lock(&m_dataMutex); - enabled = false; + featuresEnabled = 0; s_instance = 0; } -void QQuickProfiler::startProfilingImpl() +void QQuickProfiler::startProfilingImpl(quint64 features) { QMutexLocker lock(&m_dataMutex); next = 0; m_data.clear(); - enabled = true; + featuresEnabled = features; } void QQuickProfiler::stopProfilingImpl() { { QMutexLocker lock(&m_dataMutex); - enabled = false; + featuresEnabled = 0; next = 0; } service->dataReady(this); diff --git a/src/quick/util/qquickprofiler_p.h b/src/quick/util/qquickprofiler_p.h index 3aba3430e4..62e23cd393 100644 --- a/src/quick/util/qquickprofiler_p.h +++ b/src/quick/util/qquickprofiler_p.h @@ -54,18 +54,21 @@ QT_BEGIN_NAMESPACE -#define Q_QUICK_PROFILE_IF_ENABLED(Code)\ - if (QQuickProfiler::enabled) {\ +#define Q_QUICK_PROFILE_IF_ENABLED(feature, Code)\ + if (QQuickProfiler::featuresEnabled & (1 << feature)) {\ Code;\ } else\ (void)0 -#define Q_QUICK_PROFILE(Method)\ - Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::Method) +#define Q_QUICK_PROFILE(feature, Method)\ + Q_QUICK_PROFILE_IF_ENABLED(feature, QQuickProfiler::Method) #define Q_QUICK_SG_PROFILE(Type, Params)\ - Q_QUICK_PROFILE_IF_ENABLED((QQuickProfiler::sceneGraphFrame Params)) + Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\ + (QQuickProfiler::sceneGraphFrame Params)) +#define Q_QUICK_INPUT_PROFILE(Method)\ + Q_QUICK_PROFILE(QQuickProfiler::ProfileInputEvents, Method) // This struct is somewhat dangerous to use: // You can save values either with 32 or 64 bit precision. toByteArrays will @@ -196,7 +199,11 @@ public: qint64 sendMessages(qint64 until, QList &messages); - static bool enabled; + static quint64 featuresEnabled; + static bool profilingSceneGraph() + { + return featuresEnabled & (1 << QQuickProfiler::ProfileSceneGraph); + } static void initialize(); @@ -218,7 +225,7 @@ protected: } protected slots: - void startProfilingImpl(); + void startProfilingImpl(quint64 features); void stopProfilingImpl(); void reportDataImpl(); void setTimer(const QElapsedTimer &t); diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index 8d93bf389b..707dc9b0a0 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -959,7 +959,7 @@ void QQuickWidget::resizeEvent(QResizeEvent *e) void QQuickWidget::keyPressEvent(QKeyEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QCoreApplication::sendEvent(d->offscreenWindow, e); } @@ -968,7 +968,7 @@ void QQuickWidget::keyPressEvent(QKeyEvent *e) void QQuickWidget::keyReleaseEvent(QKeyEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QCoreApplication::sendEvent(d->offscreenWindow, e); } @@ -977,7 +977,7 @@ void QQuickWidget::keyReleaseEvent(QKeyEvent *e) void QQuickWidget::mouseMoveEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); // Use the constructor taking localPos and screenPos. That puts localPos into the // event's localPos and windowPos, and screenPos into the event's screenPos. This way @@ -992,7 +992,7 @@ void QQuickWidget::mouseMoveEvent(QMouseEvent *e) void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); // As the second mouse press is suppressed in widget windows we emulate it here for QML. // See QTBUG-25831 @@ -1025,7 +1025,7 @@ void QQuickWidget::hideEvent(QHideEvent *) void QQuickWidget::mousePressEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); @@ -1036,7 +1036,7 @@ void QQuickWidget::mousePressEvent(QMouseEvent *e) void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); QMouseEvent mappedEvent(e->type(), e->localPos(), e->screenPos(), e->button(), e->buttons(), e->modifiers()); QCoreApplication::sendEvent(d->offscreenWindow, &mappedEvent); @@ -1048,7 +1048,7 @@ void QQuickWidget::mouseReleaseEvent(QMouseEvent *e) void QQuickWidget::wheelEvent(QWheelEvent *e) { Q_D(QQuickWidget); - Q_QUICK_PROFILE(addEvent()); + Q_QUICK_INPUT_PROFILE(addEvent()); // Wheel events only have local and global positions, no need to map. QCoreApplication::sendEvent(d->offscreenWindow, e); -- cgit v1.2.3