diff options
author | Ulf Hermann <ulf.hermann@digia.com> | 2014-01-24 12:44:49 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-15 22:37:48 +0100 |
commit | 72420889aa54342da4472683e67e2c70b76a170f (patch) | |
tree | 3bbbb3a3f7b3286cb40f01763c42886bfd265500 /src/qml/debugger/qqmlprofilerservice.cpp | |
parent | 9424383e6d0ea1dd02dcf1070259e21550da692a (diff) |
Add dedicated QML profiler and adapter
The remaining "profiling" parts of the QML profiler service are
engine specific and are best accessed through their own adapter.
Change-Id: Idb763104bdd80e4dabdf132ec1a496b9bc9f6f46
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src/qml/debugger/qqmlprofilerservice.cpp')
-rw-r--r-- | src/qml/debugger/qqmlprofilerservice.cpp | 180 |
1 files changed, 3 insertions, 177 deletions
diff --git a/src/qml/debugger/qqmlprofilerservice.cpp b/src/qml/debugger/qqmlprofilerservice.cpp index e4620a282a..5500b8f22c 100644 --- a/src/qml/debugger/qqmlprofilerservice.cpp +++ b/src/qml/debugger/qqmlprofilerservice.cpp @@ -42,6 +42,7 @@ #include "qqmlprofilerservice_p.h" #include "qqmldebugserver_p.h" #include "qv4profileradapter_p.h" +#include "qqmlprofiler_p.h" #include <private/qqmlengine_p.h> #include <QtCore/qdatastream.h> @@ -52,87 +53,7 @@ QT_BEGIN_NAMESPACE -// instance will be set, unset in constructor. Allows static methods to be inlined. -QQmlProfilerService *QQmlProfilerService::m_instance = 0; Q_GLOBAL_STATIC(QQmlProfilerService, profilerInstance) -bool QQmlProfilerService::enabled = false; - -// convert to QByteArrays that can be sent to the debug client -// use of QDataStream can skew results -// (see tst_qqmldebugtrace::trace() benchmark) -void QQmlProfilerData::toByteArrays(QList<QByteArray> &messages) const -{ - QByteArray data; - Q_ASSERT_X(((messageType | detailType) & (1 << 31)) == 0, Q_FUNC_INFO, "You can use at most 31 message types and 31 detail types."); - for (uint decodedMessageType = 0; (messageType >> decodedMessageType) != 0; ++decodedMessageType) { - if ((messageType & (1 << decodedMessageType)) == 0) - continue; - - for (uint decodedDetailType = 0; (detailType >> decodedDetailType) != 0; ++decodedDetailType) { - if ((detailType & (1 << decodedDetailType)) == 0) - continue; - - //### using QDataStream is relatively expensive - QQmlDebugStream ds(&data, QIODevice::WriteOnly); - ds << time << decodedMessageType << decodedDetailType; - - switch (decodedMessageType) { - case QQmlProfilerService::Event: - if (decodedDetailType == (int)QQmlProfilerService::AnimationFrame) - ds << framerate << count; - break; - case QQmlProfilerService::RangeStart: - if (decodedDetailType == (int)QQmlProfilerService::Binding) - ds << bindingType; - break; - case QQmlProfilerService::RangeData: - ds << detailString; - break; - case QQmlProfilerService::RangeLocation: - ds << (detailUrl.isEmpty() ? detailString : detailUrl.toString()) << x << y; - break; - case QQmlProfilerService::RangeEnd: break; - case QQmlProfilerService::PixmapCacheEvent: - ds << detailUrl.toString(); - switch (decodedDetailType) { - case QQmlProfilerService::PixmapSizeKnown: ds << x << y; break; - case QQmlProfilerService::PixmapReferenceCountChanged: ds << count; break; - case QQmlProfilerService::PixmapCacheCountChanged: ds << count; break; - default: break; - } - break; - case QQmlProfilerService::SceneGraphFrame: - switch (decodedDetailType) { - // RendererFrame: preprocessTime, updateTime, bindingTime, renderTime - case QQmlProfilerService::SceneGraphRendererFrame: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; - // AdaptationLayerFrame: glyphCount (which is an integer), glyphRenderTime, glyphStoreTime - case QQmlProfilerService::SceneGraphAdaptationLayerFrame: ds << (int)subtime_1 << subtime_2 << subtime_3; break; - // ContextFrame: compiling material time - case QQmlProfilerService::SceneGraphContextFrame: ds << subtime_1; break; - // RenderLoop: syncTime, renderTime, swapTime - case QQmlProfilerService::SceneGraphRenderLoopFrame: ds << subtime_1 << subtime_2 << subtime_3; break; - // TexturePrepare: bind, convert, swizzle, upload, mipmap - case QQmlProfilerService::SceneGraphTexturePrepare: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4 << subtime_5; break; - // TextureDeletion: deletionTime - case QQmlProfilerService::SceneGraphTextureDeletion: ds << subtime_1; break; - // PolishAndSync: polishTime, waitTime, syncTime, animationsTime, - case QQmlProfilerService::SceneGraphPolishAndSync: ds << subtime_1 << subtime_2 << subtime_3 << subtime_4; break; - // WindowsRenderLoop: GL time, make current time, SceneGraph time - case QQmlProfilerService::SceneGraphWindowsRenderShow: ds << subtime_1 << subtime_2 << subtime_3; break; - // WindowsAnimations: update time - case QQmlProfilerService::SceneGraphWindowsAnimations: ds << subtime_1; break; - // WindowsRenderWindow: polish time; always comes packed after a RenderLoop - case QQmlProfilerService::SceneGraphWindowsPolishFrame: ds << subtime_4; break; - default:break; - } - break; - case QQmlProfilerService::Complete: break; - } - messages << data; - data.clear(); - } - } -} QQmlProfilerService::QQmlProfilerService() : QQmlConfigurableDebugService(QStringLiteral("CanvasFrameRate"), 1) @@ -149,8 +70,6 @@ QQmlProfilerService::~QQmlProfilerService() { // No need to lock here. If any engine or global profiler is still trying to register at this // point we have a nasty bug anyway. - enabled = false; - m_instance = 0; qDeleteAll(m_engineProfilers.keys()); qDeleteAll(m_globalProfilers); } @@ -190,8 +109,7 @@ void QQmlProfilerService::dataReady(QQmlAbstractProfilerAdapter *profiler) QQmlProfilerService *QQmlProfilerService::instance() { // just make sure that the service is properly registered - m_instance = profilerInstance(); - return m_instance; + return profilerInstance(); } void QQmlProfilerService::engineAboutToBeAdded(QQmlEngine *engine) @@ -199,7 +117,7 @@ void QQmlProfilerService::engineAboutToBeAdded(QQmlEngine *engine) Q_ASSERT_X(QThread::currentThread() != thread(), Q_FUNC_INFO, "QML profilers have to be added from the engine thread"); QMutexLocker lock(configMutex()); - QQmlProfiler *qmlAdapter = new QQmlProfiler(this); + QQmlProfilerAdapter *qmlAdapter = new QQmlProfilerAdapter(this, QQmlEnginePrivate::get(engine)); QV4ProfilerAdapter *v4Adapter = new QV4ProfilerAdapter(this, QV8Engine::getV4(engine->handle())); addEngineProfiler(qmlAdapter, engine); addEngineProfiler(v4Adapter, engine); @@ -329,43 +247,6 @@ void QQmlProfilerService::stopProfiling(QQmlEngine *engine) } } -QQmlProfiler::QQmlProfiler(QQmlProfilerService *service) : - QQmlAbstractProfilerAdapter(service), next(0) -{ - connect(this, SIGNAL(profilingEnabled()), this, SLOT(startProfiling())); - connect(this, SIGNAL(profilingEnabledWhileWaiting()), this, SLOT(startProfiling()), - Qt::DirectConnection); - connect(this, SIGNAL(profilingDisabled()), this, SLOT(stopProfiling())); - connect(this, SIGNAL(profilingDisabledWhileWaiting()), this, SLOT(stopProfiling()), - Qt::DirectConnection); -} - -qint64 QQmlProfiler::sendMessages(qint64 until, QList<QByteArray> &messages) -{ - QMutexLocker lock(&QQmlProfilerService::instance()->m_dataMutex); - QVector<QQmlProfilerData> *data = &(QQmlProfilerService::instance()->m_data); - while (next < data->size() && data->at(next).time <= until) { - data->at(next++).toByteArrays(messages); - } - return next < data->size() ? data->at(next).time : -1; -} - -void QQmlProfiler::startProfiling() -{ - if (!QQmlProfilerService::enabled) { - next = 0; - service->m_data.clear(); - QQmlProfilerService::enabled = true; - } -} - -void QQmlProfiler::stopProfiling() -{ - next = 0; - QQmlProfilerService::enabled = false; - service->dataReady(this); -} - /* Send the queued up messages. */ @@ -458,59 +339,4 @@ void QQmlProfilerService::messageReceived(const QByteArray &message) stopWaiting(); } -/*! - * \fn void QQmlVmeProfiler::Data::clear() - * Resets the profiling data to defaults. - */ - -/*! - * \fn bool QQmlVmeProfiler::startBackground(const QString &typeName) - * If profiling is enabled clears the current range data, then stops the - * profiler previously running in the foreground if any, then starts a new one - * in the background, setting the given typeName. \a typeName is the type of - * object being created. - */ - -/*! - * \fn bool QQmlVmeProfiler::start(const QString &typeName, const QUrl &url, int line, int column) - * If profiling is enabled clears the current range data, then stops the - * profiler previously running in the foreground if any, then starts a new one - * in the foreground, setting the given location. \a url is the URL of - * file being executed, \line line is the current line in in that file, and - * \a column is the current column in that file. - */ - -/*! - * \fn bool QQmlVmeProfiler::pop() - * Stops the currently running profiler, if any, then retrieves an old one from the stack - * of paused profilers and starts that if possible. - */ - -/*! - * \fn void QQmlVmeProfiler::push() - * Pushes the currently running profiler on the stack of paused profilers. Note: The profiler - * isn't paused here. That's a separate step. If it's never paused, but pop()'ed later that - * won't do any harm, though. - */ - -/*! - * \fn void QQmlVmeProfiler::clear() - * Stops the currently running (foreground and background) profilers and removes all saved - * data about paused profilers. - */ - -/*! - * \fn void QQmlVmeProfiler::stop() - * Stop profiler running in the foreground, if any. - */ - -/*! - * \fn bool QQmlVmeProfiler::foreground(const QUrl &url, int line, int column) - * Stops the profiler currently running in the foreground, if any and puts the - * next profiler from the background in its place if there are any profilers in - * the background. Additionally the rangeLocation is set. \a url is the URL of - * file being executed, \line line is the current line in in that file, and - * \a column is the current column in that file. - */ - QT_END_NAMESPACE |