diff --git a/src/qml/debugger/qqmlabstractprofileradapter.cpp b/src/qml/debugger/qqmlabstractprofileradapter.cpp index 12675032261e5636f68ef697f4d5d69b53965874..165772335abab38ae7d94101f384e0a1366cb15f 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 f06d51e8f7d2924f8405382dc4c5e6b62df43029..03f664517858baa332cc79ddef91e62a9292479b 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<QByteArray> &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 3a647e704d3d66722f16ed2ce97c97a3e9756563..b102201ff18de44669833133f159035f4fa4c4df 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<QQmlProfilerData> &new_data) } -QQmlProfiler::QQmlProfiler() : enabled(false) +QQmlProfiler::QQmlProfiler() : featuresEnabled(0) { static int metatype = qRegisterMetaType<QList<QQmlProfilerData> >(); 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 02cdbf0a4eafe2f0bc16aabc6a9e7fcde42fb77b..13e6b8ddae1279a40747a2d143e819626c6ee87d 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<Binding>()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, + endRange<Binding>()); } }; @@ -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<QQmlProfiler::HandlingSignal>()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileHandlingSignal, profiler, + endRange<QQmlProfiler::HandlingSignal>()); } }; @@ -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<Compiling>()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCompiling, profiler, endRange<Compiling>()); } }; @@ -278,20 +282,20 @@ private: QFiniteStack<Data> 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<QQmlProfilerDefinitions::Creating>()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, endRange<QQmlProfilerDefinitions::Creating>()); } 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<QQmlProfilerDefinitions::Creating>()); + Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileCreating, profiler, + endRange<QQmlProfilerDefinitions::Creating>()); } private: QQmlProfiler *profiler; diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h index 92bab93300732f99615ab21c3f010ae0713fa2e2..e8ee98433d98160ff576bb04e77583c9defd06ef 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 6157d2f191369f1b6e122a552badcee9c9a95fda..5ec8178f323a9cdb0bc41f617ee446b9e979b370 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<quint64>::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<QQmlEngine *>(objectForId(engineId))); + startProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId)), features); else stopProfiling(qobject_cast<QQmlEngine *>(objectForId(engineId))); diff --git a/src/qml/debugger/qqmlprofilerservice_p.h b/src/qml/debugger/qqmlprofilerservice_p.h index 54059058619bb3d151a4521301ddfccced948af4..c4c40adc4f87826a2f9d685964d2d6d830f9a5eb 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<quint64>::max()); + void stopProfiling(QQmlEngine *engine); QQmlProfilerService(); ~QQmlProfilerService(); diff --git a/src/qml/debugger/qv4profileradapter.cpp b/src/qml/debugger/qv4profileradapter.cpp index 19a6ea3e744f5e217f34f4b472de2e9abae2f180..a5492ce8057df541aa21d68168bbaf0b173e4fc6 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 693af854da9edb2927fe9d6d9fc4983324371c54..f1bd1d55d96ba309d8e54dfd3b7e8f31ce0553ef 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<QList<QV4::Profiling::FunctionCallProperties> >(); static int metatype2 = qRegisterMetaType<QList<QV4::Profiling::MemoryAllocationProperties> >(); @@ -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 f115137c86dde3cb8735a9379f063725e378eee4..8224f8a851ac569d27d53df3c513c2a1833e9250 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 0ad60e01abe9fb10bfb8a67526bb6078956455f6..a827e96ab12915fe11f2d1263eb684dd0cb2d4ae 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 91a646859306c62e7280ce8c0c124dfd59cccaee..a55d056c75eadaf753750a05fdace0ed6cc1ae66 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<QQuickProfiler::Key>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); QQuickWindow::keyPressEvent(e); } @@ -602,7 +602,7 @@ void QQuickView::keyPressEvent(QKeyEvent *e) /*! \reimp */ void QQuickView::keyReleaseEvent(QKeyEvent *e) { - Q_QUICK_PROFILE(addEvent<QQuickProfiler::Key>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); QQuickWindow::keyReleaseEvent(e); } @@ -610,7 +610,7 @@ void QQuickView::keyReleaseEvent(QKeyEvent *e) /*! \reimp */ void QQuickView::mouseMoveEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); QQuickWindow::mouseMoveEvent(e); } @@ -618,7 +618,7 @@ void QQuickView::mouseMoveEvent(QMouseEvent *e) /*! \reimp */ void QQuickView::mousePressEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); QQuickWindow::mousePressEvent(e); } @@ -626,7 +626,7 @@ void QQuickView::mousePressEvent(QMouseEvent *e) /*! \reimp */ void QQuickView::mouseReleaseEvent(QMouseEvent *e) { - Q_QUICK_PROFILE(addEvent<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); QQuickWindow::mouseReleaseEvent(e); } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index ecd450bcc83bb20619a308a1e9f7ae08abc585ad..0a39188b24ff6cb6c943d58fe13559f692ea47ee 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<QSGMaterialShader *>(material->createShader()); diff --git a/src/quick/scenegraph/coreapi/qsgrenderer.cpp b/src/quick/scenegraph/coreapi/qsgrenderer.cpp index d62802e85439bd021788b3de3dfd23a443b2353e..dd089425f6b59ecea13b5c90f72e5c186b88938d 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 faf2762accaf9e88a61b7d1d0c64d2f4b75422e6..fb9fe00ee52312dfb90f54456b4e6b1224571ea2 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 dc0939c023cb82810bebe47a1d8ea5b1956265b8..4428918da5de1dbc59b4f11a78120ff4f3047839 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 4e70c3f0a2a3d8c3b18229af50b0ef25329eea4e..3866ed9a2b917f7cb91f44776fb30c2e69ec3cb9 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 f2731e347b51f7302e3c1f2e41981fe0feef1243..de1160064d0d7cc1773e03d045cdcca3164077c0 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 a9cbbe1dc3779c2678edde36465c1d447e20e473..5edcb5d67abe3ff9446282757462c35f9ae29011 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; i<m_pending_uploads.size(); ++i) { - bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) qsg_renderer_timer.start(); diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 4b3ff8bed5dfdabb73c87d9b7eed6c301bc36194..4612e6b87d1d126b92970d8d3d7cea796fc26e72 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -633,7 +633,8 @@ void QSGPlainTexture::bind() m_dirty_texture = false; - bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || QQuickProfiler::enabled; + bool profileFrames = QSG_LOG_TIME_TEXTURE().isDebugEnabled() || + QQuickProfiler::profilingSceneGraph(); if (profileFrames) qsg_renderer_timer.start(); diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 818e6fb2bf9b82000d4e15a23e42601376d9f77b..0764665182b6734e7d00f0b290b47eac56c27c36 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -70,6 +70,8 @@ #define CACHE_EXPIRE_TIME 30 #define CACHE_REMOVAL_FRACTION 4 +#define PIXMAP_PROFILE(Code) Q_QUICK_PROFILE(QQuickProfiler::ProfilePixmapCache, Code) + QT_BEGIN_NAMESPACE @@ -500,7 +502,7 @@ void QQuickPixmapReader::processJobs() replies.remove(reply); reply->close(); } - Q_QUICK_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(job->url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(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<QQuickProfiler::PixmapLoadingStarted>(url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(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<QQuickProfiler::PixmapLoadingError>(reply->url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(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<QQuickProfiler::PixmapLoadingError>(data->url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(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<QQuickProfiler::PixmapLoadingError>(url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(url)); } delete this; @@ -927,7 +929,7 @@ int QQuickPixmapData::cost() const void QQuickPixmapData::addref() { ++refCount; - Q_QUICK_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount)); + PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount)); if (prevUnreferencedPtr) pixmapStore()->referencePixmap(this); } @@ -936,7 +938,7 @@ void QQuickPixmapData::release() { Q_ASSERT(refCount > 0); --refCount; - Q_QUICK_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(url, refCount)); + PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapReferenceCountChanged>(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<QQuickProfiler::PixmapCacheCountChanged>( + PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>( 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<QQuickProfiler::PixmapCacheCountChanged>( + PIXMAP_PROFILE(pixmapCountChanged<QQuickProfiler::PixmapCacheCountChanged>( 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<QQuickProfiler::PixmapLoadingStarted>(url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingStarted>(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<QQuickProfiler::PixmapLoadingError>(url)); + PIXMAP_PROFILE(pixmapStateChanged<QQuickProfiler::PixmapLoadingError>(url)); return; } } diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp index 604d6e5cb145b5dfc5d7bdfbf948d76948f371f9..3b34b7550b5b6b0ef068566fe05e2dad515bf278 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 3aba3430e4a8fe41298d361e7b3aec6a1be885f6..62e23cd393d90b484c07e2b1f581955c0018033f 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<Type> Params)) + Q_QUICK_PROFILE_IF_ENABLED(QQuickProfiler::ProfileSceneGraph,\ + (QQuickProfiler::sceneGraphFrame<Type> 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<QByteArray> &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 8d93bf389bdbbe0f671b57f3eb0b7b2341f115d5..707dc9b0a07daa6872a5eba107df502d6a57f791 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<QQuickProfiler::Key>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); 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<QQuickProfiler::Key>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Key>()); 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<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); // 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<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); // 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<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); 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<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); 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<QQuickProfiler::Mouse>()); + Q_QUICK_INPUT_PROFILE(addEvent<QQuickProfiler::Mouse>()); // Wheel events only have local and global positions, no need to map. QCoreApplication::sendEvent(d->offscreenWindow, e);