aboutsummaryrefslogtreecommitdiffstats
path: root/plugins/qmlprofiler/scenegraphtimelinemodel.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2015-08-27 17:36:46 +0200
committerUlf Hermann <ulf.hermann@theqtcompany.com>2015-08-27 18:48:09 +0300
commitdd988bdb5ec7ae4cd082e077c0c9ff051157e1c5 (patch)
tree4b80752ca0ed96ea12274ea675e0926e8a1a38ac /plugins/qmlprofiler/scenegraphtimelinemodel.cpp
parentc17e3107d16f182561154737aa970c320026162f (diff)
Rename files to follow common pattern among extension plugins
This way the plugin will successfully build with qbs again. Change-Id: Iac5fc64753bb225649ba9f62199d6248450e1546 Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
Diffstat (limited to 'plugins/qmlprofiler/scenegraphtimelinemodel.cpp')
-rw-r--r--plugins/qmlprofiler/scenegraphtimelinemodel.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/plugins/qmlprofiler/scenegraphtimelinemodel.cpp b/plugins/qmlprofiler/scenegraphtimelinemodel.cpp
new file mode 100644
index 00000000000..9c7be933cc4
--- /dev/null
+++ b/plugins/qmlprofiler/scenegraphtimelinemodel.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd
+** All rights reserved.
+** For any questions to The Qt Company, please use contact form at http://www.qt.io/contact-us
+**
+** This file is part of the Qt Enterprise Qt Quick Profiler Add-on.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://www.qt.io/contact-us
+**
+****************************************************************************/
+
+#include "scenegraphtimelinemodel.h"
+#include "qmldebug/qmlprofilereventtypes.h"
+#include "qmlprofiler/qmlprofilermodelmanager.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+
+namespace QmlProfilerExtension {
+namespace Internal {
+
+using namespace QmlProfiler;
+
+static const char *ThreadLabels[] = {
+ QT_TRANSLATE_NOOP("MainView", "GUI Thread"),
+ QT_TRANSLATE_NOOP("MainView", "Render Thread"),
+ QT_TRANSLATE_NOOP("MainView", "Render Thread Details")
+};
+
+static const char *StageLabels[] = {
+ QT_TRANSLATE_NOOP("MainView", "Polish"),
+ QT_TRANSLATE_NOOP("MainView", "Wait"),
+ QT_TRANSLATE_NOOP("MainView", "GUI Thread Sync"),
+ QT_TRANSLATE_NOOP("MainView", "Animations"),
+ QT_TRANSLATE_NOOP("MainView", "Render Thread Sync"),
+ QT_TRANSLATE_NOOP("MainView", "Render"),
+ QT_TRANSLATE_NOOP("MainView", "Swap"),
+ QT_TRANSLATE_NOOP("MainView", "Render Preprocess"),
+ QT_TRANSLATE_NOOP("MainView", "Render Update"),
+ QT_TRANSLATE_NOOP("MainView", "Render Bind"),
+ QT_TRANSLATE_NOOP("MainView", "Render Render"),
+ QT_TRANSLATE_NOOP("MainView", "Material Compile"),
+ QT_TRANSLATE_NOOP("MainView", "Glyph Render"),
+ QT_TRANSLATE_NOOP("MainView", "Glyph Upload"),
+ QT_TRANSLATE_NOOP("MainView", "Texture Bind"),
+ QT_TRANSLATE_NOOP("MainView", "Texture Convert"),
+ QT_TRANSLATE_NOOP("MainView", "Texture Swizzle"),
+ QT_TRANSLATE_NOOP("MainView", "Texture Upload"),
+ QT_TRANSLATE_NOOP("MainView", "Texture Mipmap"),
+ QT_TRANSLATE_NOOP("MainView", "Texture Delete")
+};
+
+enum SceneGraphCategoryType {
+ SceneGraphGUIThread,
+ SceneGraphRenderThread,
+ SceneGraphRenderThreadDetails,
+
+ MaximumSceneGraphCategoryType
+};
+
+Q_STATIC_ASSERT(sizeof(StageLabels) ==
+ SceneGraphTimelineModel::MaximumSceneGraphStage * sizeof(const char *));
+
+SceneGraphTimelineModel::SceneGraphTimelineModel(QmlProfilerModelManager *manager,
+ QObject *parent) :
+ QmlProfilerTimelineModel(manager, QmlDebug::SceneGraphFrame, QmlDebug::MaximumRangeType,
+ QmlDebug::ProfileSceneGraph, parent)
+{
+}
+
+int SceneGraphTimelineModel::expandedRow(int index) const
+{
+ return selectionId(index) + 1;
+}
+
+int SceneGraphTimelineModel::collapsedRow(int index) const
+{
+ return m_data[index].rowNumberCollapsed;
+}
+
+int SceneGraphTimelineModel::typeId(int index) const
+{
+ return m_data[index].typeId;
+}
+
+QColor SceneGraphTimelineModel::color(int index) const
+{
+ return colorBySelectionId(index);
+}
+
+QVariantList SceneGraphTimelineModel::labels() const
+{
+ QVariantList result;
+
+ for (SceneGraphStage i = MinimumSceneGraphStage; i < MaximumSceneGraphStage;
+ i = static_cast<SceneGraphStage>(i + 1)) {
+ QVariantMap element;
+ element.insert(QLatin1String("displayName"), tr(threadLabel(i)));
+ element.insert(QLatin1String("description"), tr(StageLabels[i]));
+ element.insert(QLatin1String("id"), i);
+ result << element;
+ }
+
+ return result;
+}
+
+QVariantMap SceneGraphTimelineModel::details(int index) const
+{
+ QVariantMap result;
+ const SceneGraphStage stage = static_cast<SceneGraphStage>(selectionId(index));
+
+ result.insert(QLatin1String("displayName"), tr(threadLabel(stage)));
+ result.insert(tr("Stage"), tr(StageLabels[stage]));
+ result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(duration(index)));
+
+ const int glyphCount = m_data[index].glyphCount;
+ if (glyphCount >= 0)
+ result.insert(tr("Glyphs"), QString::number(glyphCount));
+
+ return result;
+}
+
+void SceneGraphTimelineModel::loadData()
+{
+ QmlProfilerDataModel *simpleModel = modelManager()->qmlModel();
+ if (simpleModel->isEmpty())
+ return;
+
+ // combine the data of several eventtypes into two rows
+ const QVector<QmlProfilerDataModel::QmlEventTypeData> &types = simpleModel->getEventTypes();
+ foreach (const QmlProfilerDataModel::QmlEventData &event, simpleModel->getEvents()) {
+ const QmlProfilerDataModel::QmlEventTypeData &type = types[event.typeIndex];
+ if (!accepted(type))
+ continue;
+
+ switch ((QmlDebug::SceneGraphFrameType)type.detailType) {
+ case QmlDebug::SceneGraphRendererFrame: {
+ // Breakdown of render times. We repeat "render" here as "net" render time. It would
+ // look incomplete if that was left out as the printf profiler lists it, too, and people
+ // are apparently comparing that. Unfortunately it is somewhat redundant as the other
+ // parts of the breakdown are usually very short.
+ qint64 startTime = event.startTime - event.numericData1 - event.numericData2 -
+ event.numericData3 - event.numericData4;
+ startTime += insert(startTime, event.numericData1, event.typeIndex, RenderPreprocess);
+ startTime += insert(startTime, event.numericData2, event.typeIndex, RenderUpdate);
+ startTime += insert(startTime, event.numericData3, event.typeIndex, RenderBind);
+ insert(startTime, event.numericData4, event.typeIndex, RenderRender);
+ break;
+ }
+ case QmlDebug::SceneGraphAdaptationLayerFrame: {
+ qint64 startTime = event.startTime - event.numericData2 - event.numericData3;
+ startTime += insert(startTime, event.numericData2, event.typeIndex, GlyphRender,
+ event.numericData1);
+ insert(startTime, event.numericData3, event.typeIndex, GlyphStore, event.numericData1);
+ break;
+ }
+ case QmlDebug::SceneGraphContextFrame: {
+ insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex,
+ Material);
+ break;
+ }
+ case QmlDebug::SceneGraphRenderLoopFrame: {
+ qint64 startTime = event.startTime - event.numericData1 - event.numericData2 -
+ event.numericData3;
+ startTime += insert(startTime, event.numericData1, event.typeIndex,
+ RenderThreadSync);
+ startTime += insert(startTime, event.numericData2, event.typeIndex,
+ Render);
+ insert(startTime, event.numericData3, event.typeIndex, Swap);
+ break;
+ }
+ case QmlDebug::SceneGraphTexturePrepare: {
+ qint64 startTime = event.startTime - event.numericData1 - event.numericData2 -
+ event.numericData3 - event.numericData4 - event.numericData5;
+ startTime += insert(startTime, event.numericData1, event.typeIndex, TextureBind);
+ startTime += insert(startTime, event.numericData2, event.typeIndex, TextureConvert);
+ startTime += insert(startTime, event.numericData3, event.typeIndex, TextureSwizzle);
+ startTime += insert(startTime, event.numericData4, event.typeIndex, TextureUpload);
+ insert(startTime, event.numericData5, event.typeIndex, TextureMipmap);
+ break;
+ }
+ case QmlDebug::SceneGraphTextureDeletion: {
+ insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex,
+ TextureDeletion);
+ break;
+ }
+ case QmlDebug::SceneGraphPolishAndSync: {
+ qint64 startTime = event.startTime - event.numericData1 - event.numericData2 -
+ event.numericData3 - event.numericData4;
+
+ startTime += insert(startTime, event.numericData1, event.typeIndex, Polish);
+ startTime += insert(startTime, event.numericData2, event.typeIndex, Wait);
+ startTime += insert(startTime, event.numericData3, event.typeIndex, GUIThreadSync);
+ insert(startTime, event.numericData4, event.typeIndex, Animations);
+ break;
+ }
+ case QmlDebug::SceneGraphWindowsAnimations: {
+ // GUI thread, separate animations stage
+ insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex,
+ Animations);
+ break;
+ }
+ case QmlDebug::SceneGraphPolishFrame: {
+ // GUI thread, separate polish stage
+ insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex,
+ Polish);
+ break;
+ }
+ default: break;
+ }
+
+ updateProgress(count(), simpleModel->getEvents().count());
+ }
+
+ computeNesting();
+ flattenLoads();
+ updateProgress(1, 1);
+}
+
+void SceneGraphTimelineModel::flattenLoads()
+{
+ int collapsedRowCount = 0;
+
+ // computes "compressed row"
+ QVector <qint64> eventEndTimes;
+
+ for (int i = 0; i < count(); i++) {
+ SceneGraphEvent &event = m_data[i];
+ int stage = selectionId(i);
+ // Don't try to put render thread events in GUI row and vice versa.
+ // Rows below those are free for all.
+ if (stage < MaximumGUIThreadStage)
+ event.rowNumberCollapsed = SceneGraphGUIThread;
+ else if (stage < MaximumRenderThreadStage)
+ event.rowNumberCollapsed = SceneGraphRenderThread;
+ else
+ event.rowNumberCollapsed = SceneGraphRenderThreadDetails;
+
+ while (eventEndTimes.count() > event.rowNumberCollapsed &&
+ eventEndTimes[event.rowNumberCollapsed] > startTime(i))
+ ++event.rowNumberCollapsed;
+
+ while (eventEndTimes.count() <= event.rowNumberCollapsed)
+ eventEndTimes << 0; // increase stack length, proper value added below
+ eventEndTimes[event.rowNumberCollapsed] = endTime(i);
+
+ // readjust to account for category empty row
+ event.rowNumberCollapsed++;
+ if (event.rowNumberCollapsed > collapsedRowCount)
+ collapsedRowCount = event.rowNumberCollapsed;
+ }
+
+ // Starting from 0, count is maxIndex+1
+ setCollapsedRowCount(collapsedRowCount + 1);
+ setExpandedRowCount(MaximumSceneGraphStage + 1);
+}
+
+/*!
+ * Inserts an event characterized by \a start time, \a duration, \a typeIndex, \a stage and possibly
+ * \a glyphCount (if it's a \c GlyphRender or \c GlyphStore event) into the scene graph model if its
+ * \a duration is greater than 0. Returns \a duration in that case; otherwise returns 0.
+ */
+qint64 SceneGraphTimelineModel::insert(qint64 start, qint64 duration, int typeIndex,
+ SceneGraphStage stage, int glyphCount)
+{
+ if (duration <= 0)
+ return 0;
+
+ m_data.insert(QmlProfilerTimelineModel::insert(start, duration, stage),
+ SceneGraphEvent(typeIndex, glyphCount));
+ return duration;
+}
+
+const char *SceneGraphTimelineModel::threadLabel(SceneGraphStage stage)
+{
+ if (stage < MaximumGUIThreadStage)
+ return ThreadLabels[SceneGraphGUIThread];
+ else if (stage < MaximumRenderThreadStage)
+ return ThreadLabels[SceneGraphRenderThread];
+ else
+ return ThreadLabels[SceneGraphRenderThreadDetails];
+
+}
+
+void SceneGraphTimelineModel::clear()
+{
+ m_data.clear();
+ QmlProfilerTimelineModel::clear();
+}
+
+SceneGraphTimelineModel::SceneGraphEvent::SceneGraphEvent(int typeId, int glyphCount) :
+ typeId(typeId), rowNumberCollapsed(-1), glyphCount(glyphCount)
+{
+}
+
+} // namespace Internal
+} // namespace QmlProfilerExtension