aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristiaan Janssen <christiaan.janssen@digia.com>2013-06-11 15:13:33 +0200
committerKai Koehne <kai.koehne@digia.com>2013-06-11 16:47:07 +0300
commitb79b4437a20706d1429ae7124c8fc770fe434d2d (patch)
tree5b7e006e8391ac07721dea1ff54f2ca92d157a37
parent3f6226930fc469693a9722c27b15273eb7cbefc9 (diff)
QmlProfilerExtended: first commit
Change-Id: I8e5345a2b2db03f7cab6d2c3edca1fe8e068253a Reviewed-by: Kai Koehne <kai.koehne@digia.com>
-rw-r--r--plugins/qmlprofilerextended/QmlProfilerExtended.pluginspec.in13
-rw-r--r--plugins/qmlprofilerextended/qmlprofilerextended.pro20
-rw-r--r--plugins/qmlprofilerextended/qmlprofilerextended_dependencies.pri6
-rw-r--r--plugins/qmlprofilerextended/qmlprofilerextended_global.h30
-rw-r--r--plugins/qmlprofilerextended/qmlprofilerextendedconstants.h31
-rw-r--r--plugins/qmlprofilerextended/qmlprofilerextendedplugin.cpp90
-rw-r--r--plugins/qmlprofilerextended/qmlprofilerextendedplugin.h49
-rw-r--r--plugins/qmlprofilerextended/scenegraphtimelinemodel.cpp467
-rw-r--r--plugins/qmlprofilerextended/scenegraphtimelinemodel.h106
-rw-r--r--qmlprofiler.pro3
-rw-r--r--qtcreatorplugin.pri2
11 files changed, 815 insertions, 2 deletions
diff --git a/plugins/qmlprofilerextended/QmlProfilerExtended.pluginspec.in b/plugins/qmlprofilerextended/QmlProfilerExtended.pluginspec.in
new file mode 100644
index 0000000000..f551aa6abd
--- /dev/null
+++ b/plugins/qmlprofilerextended/QmlProfilerExtended.pluginspec.in
@@ -0,0 +1,13 @@
+<plugin name=\"QmlProfilerExtended\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_VERSION\">
+ <vendor>Digia Plc</vendor>
+ <copyright>(C) 2013 Digia Plc</copyright>
+ <license>
+ Commercial Usage
+
+ Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and Digia.
+ </license>
+ <category>Qt Quick</category>
+ <description>Qml Profiler Extended Plugin</description>
+ <url>http://www.qt-project.org</url>
+ $$dependencyList
+</plugin>
diff --git a/plugins/qmlprofilerextended/qmlprofilerextended.pro b/plugins/qmlprofilerextended/qmlprofilerextended.pro
new file mode 100644
index 0000000000..213f149817
--- /dev/null
+++ b/plugins/qmlprofilerextended/qmlprofilerextended.pro
@@ -0,0 +1,20 @@
+TARGET = QmlProfilerExtended
+TEMPLATE = lib
+
+include(../../qtcreatorplugin.pri)
+include(qmlprofilerextended_dependencies.pri)
+
+DEFINES += QMLPROFILEREXTENDED_LIBRARY
+
+# QmlProfilerExtended files
+
+SOURCES += qmlprofilerextendedplugin.cpp \
+ scenegraphtimelinemodel.cpp
+
+HEADERS += qmlprofilerextendedplugin.h\
+ qmlprofilerextended_global.h\
+ qmlprofilerextendedconstants.h \
+ scenegraphtimelinemodel.h
+
+OTHER_FILES += \
+ QmlProfilerExtended.json
diff --git a/plugins/qmlprofilerextended/qmlprofilerextended_dependencies.pri b/plugins/qmlprofilerextended/qmlprofilerextended_dependencies.pri
new file mode 100644
index 0000000000..67675535df
--- /dev/null
+++ b/plugins/qmlprofilerextended/qmlprofilerextended_dependencies.pri
@@ -0,0 +1,6 @@
+QTC_PLUGIN_NAME = QmlProfilerExtended
+#QTC_LIB_DEPENDS += \
+# qmldebug \
+# extensionsystem
+QTC_PLUGIN_DEPENDS += \
+ qmlprofiler
diff --git a/plugins/qmlprofilerextended/qmlprofilerextended_global.h b/plugins/qmlprofilerextended/qmlprofilerextended_global.h
new file mode 100644
index 0000000000..1970ca9fdf
--- /dev/null
+++ b/plugins/qmlprofilerextended/qmlprofilerextended_global.h
@@ -0,0 +1,30 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+****************************************************************************/
+
+#ifndef QMLPROFILEREXTENDED_GLOBAL_H
+#define QMLPROFILEREXTENDED_GLOBAL_H
+
+#include <QtGlobal>
+
+#if defined(QMLPROFILEREXTENDED_LIBRARY)
+# define QMLPROFILEREXTENDEDSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define QMLPROFILEREXTENDEDSHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // QMLPROFILEREXTENDED_GLOBAL_H
+
diff --git a/plugins/qmlprofilerextended/qmlprofilerextendedconstants.h b/plugins/qmlprofilerextended/qmlprofilerextendedconstants.h
new file mode 100644
index 0000000000..0502b22883
--- /dev/null
+++ b/plugins/qmlprofilerextended/qmlprofilerextendedconstants.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+****************************************************************************/
+
+#ifndef QMLPROFILEREXTENDEDCONSTANTS_H
+#define QMLPROFILEREXTENDEDCONSTANTS_H
+
+namespace QmlProfilerExtended {
+namespace Constants {
+
+const char ACTION_ID[] = "QmlProfilerExtended.Action";
+const char MENU_ID[] = "QmlProfilerExtended.Menu";
+
+} // namespace QmlProfilerExtended
+} // namespace Constants
+
+#endif // QMLPROFILEREXTENDEDCONSTANTS_H
+
diff --git a/plugins/qmlprofilerextended/qmlprofilerextendedplugin.cpp b/plugins/qmlprofilerextended/qmlprofilerextendedplugin.cpp
new file mode 100644
index 0000000000..5c6fcb8e70
--- /dev/null
+++ b/plugins/qmlprofilerextended/qmlprofilerextendedplugin.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+****************************************************************************/
+
+#include "qmlprofilerextendedplugin.h"
+#include "qmlprofilerextendedconstants.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/coreconstants.h>
+
+#include <QAction>
+#include <QMessageBox>
+#include <QMainWindow>
+#include <QMenu>
+
+#include <QtPlugin>
+
+#include "scenegraphtimelinemodel.h"
+
+using namespace QmlProfilerExtended::Internal;
+
+QmlProfilerExtendedPlugin::QmlProfilerExtendedPlugin()
+{
+ // Create your members
+}
+
+QmlProfilerExtendedPlugin::~QmlProfilerExtendedPlugin()
+{
+ // Unregister objects from the plugin manager's object pool
+ // Delete members
+}
+
+bool QmlProfilerExtendedPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ // Register objects in the plugin manager's object pool
+ // Load settings
+ // Add actions to menus
+ // Connect to other plugins' signals
+ // In the initialize method, a plugin can be sure that the plugins it
+ // depends on have initialized their members.
+
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ addAutoReleasedObject(new SceneGraphTimelineModel);
+
+ return true;
+}
+
+void QmlProfilerExtendedPlugin::extensionsInitialized()
+{
+ // Retrieve objects from the plugin manager's object pool
+ // In the extensionsInitialized method, a plugin can be sure that all
+ // plugins that depend on it are completely initialized.
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag QmlProfilerExtendedPlugin::aboutToShutdown()
+{
+ // Save settings
+ // Disconnect from signals that are not needed during shutdown
+ // Hide UI (if you add UI that is not in the main window directly)
+ return SynchronousShutdown;
+}
+
+void QmlProfilerExtendedPlugin::triggerAction()
+{
+ QMessageBox::information(Core::ICore::mainWindow(),
+ tr("Action triggered"),
+ tr("This is an action from QmlProfilerExtended."));
+}
+
+Q_EXPORT_PLUGIN2(QmlProfilerExtended, QmlProfilerExtendedPlugin)
+
diff --git a/plugins/qmlprofilerextended/qmlprofilerextendedplugin.h b/plugins/qmlprofilerextended/qmlprofilerextendedplugin.h
new file mode 100644
index 0000000000..078d597022
--- /dev/null
+++ b/plugins/qmlprofilerextended/qmlprofilerextendedplugin.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+****************************************************************************/
+
+#ifndef QMLPROFILEREXTENDED_H
+#define QMLPROFILEREXTENDED_H
+
+#include "qmlprofilerextended_global.h"
+
+#include <extensionsystem/iplugin.h>
+
+namespace QmlProfilerExtended {
+namespace Internal {
+
+class QmlProfilerExtendedPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmlProfilerExtended.json")
+
+public:
+ QmlProfilerExtendedPlugin();
+ ~QmlProfilerExtendedPlugin();
+
+ bool initialize(const QStringList &arguments, QString *errorString);
+ void extensionsInitialized();
+ ShutdownFlag aboutToShutdown();
+
+private slots:
+ void triggerAction();
+};
+
+} // namespace Internal
+} // namespace QmlProfilerExtended
+
+#endif // QMLPROFILEREXTENDED_H
+
diff --git a/plugins/qmlprofilerextended/scenegraphtimelinemodel.cpp b/plugins/qmlprofilerextended/scenegraphtimelinemodel.cpp
new file mode 100644
index 0000000000..7446638c55
--- /dev/null
+++ b/plugins/qmlprofilerextended/scenegraphtimelinemodel.cpp
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+****************************************************************************/
+
+#include "scenegraphtimelinemodel.h"
+#include "qmldebug/qmlprofilereventtypes.h"
+#include "qmlprofiler/qmlprofilermodelmanager.h"
+
+#include <QDebug>
+
+namespace QmlProfilerExtended {
+namespace Internal {
+
+using namespace QmlProfiler::Internal;
+
+enum SceneGraphEventType {
+ SceneGraphRendererFrame,
+ SceneGraphAdaptationLayerFrame,
+ SceneGraphContextFrame,
+ SceneGraphRenderLoopFrame,
+ SceneGraphTexturePrepare,
+ SceneGraphTextureDeletion,
+ SceneGraphPolishAndSync,
+ SceneGraphWindowsRenderShow,
+ SceneGraphWindowsAnimations,
+ SceneGraphWindowsPolishFrame,
+
+ MaximumSceneGraphFrameType
+};
+
+enum SceneGraphCategoryType {
+ SceneGraphRenderThread,
+ SceneGraphGUIThread,
+
+ MaximumSceneGraphCategoryType
+};
+
+class SceneGraphTimelineModel::SceneGraphTimelineModelPrivate {
+public:
+ SceneGraphTimelineModelPrivate(SceneGraphTimelineModel *qq):q(qq) {}
+ ~SceneGraphTimelineModelPrivate();
+
+ SceneGraphTimelineModel *q;
+
+ QVector < SceneGraphTimelineModel::SceneGraphEvent > eventList;
+ bool isExpanded;
+ QString displayTime(double time);
+ void addVP(QVariantList &l, QString label, qint64 time);
+};
+
+SceneGraphTimelineModel::SceneGraphTimelineModel(QObject *parent)
+ : AbstractTimelineModel(parent), d(new SceneGraphTimelineModelPrivate(this))
+{
+}
+
+SceneGraphTimelineModel::~SceneGraphTimelineModel()
+{
+}
+
+int SceneGraphTimelineModel::categories() const
+{
+ return 1;
+}
+
+QStringList SceneGraphTimelineModel::categoryTitles() const
+{
+ QStringList retString;
+ retString << categoryLabel(0);
+ return retString;
+}
+
+QString SceneGraphTimelineModel::name() const
+{
+ return QLatin1String("SceneGraphTimeLineModel");
+}
+
+int SceneGraphTimelineModel::count() const
+{
+ return d->eventList.count();
+}
+
+bool SceneGraphTimelineModel::isEmpty() const
+{
+ return d->eventList.isEmpty();
+}
+
+bool SceneGraphTimelineModel::eventAccepted(const QmlProfiler::Internal::QmlProfilerSimpleModel::QmlEventData &event) const
+{
+ return (event.eventType == QmlDebug::SceneGraphFrameEvent);
+}
+
+qint64 SceneGraphTimelineModel::lastTimeMark() const
+{
+ return d->eventList.last().startTime;
+}
+
+void SceneGraphTimelineModel::setExpanded(int category, bool expanded)
+{
+ // TODO: uncomment this for PixMap
+ //if (category == QmlDebug::SceneGraphFrameEvent)
+ d->isExpanded = expanded;
+}
+
+int SceneGraphTimelineModel::categoryDepth(int categoryIndex) const
+{
+ // TODO
+ if (isEmpty())
+ return 1;
+ return 3;
+
+ if (categoryIndex == QmlDebug::SceneGraphFrameEvent)
+ return 11;
+ return 1;
+}
+
+int SceneGraphTimelineModel::categoryCount() const
+{
+ return 1;
+}
+
+const QString SceneGraphTimelineModel::categoryLabel(int categoryIndex) const
+{
+ Q_UNUSED(categoryIndex);
+ return QLatin1String("SceneGraph");
+}
+
+int SceneGraphTimelineModel::findFirstIndex(qint64 startTime) const
+{
+ // TODO properly
+ int candidate = -2;
+ for (int i=0; i < d->eventList.count(); i++)
+ if (d->eventList[i].startTime + d->eventList[i].duration > startTime) {
+ candidate = i;
+ break;
+ }
+
+ if (candidate == -1)
+ return 0;
+ if (candidate == -2)
+ return d->eventList.count() - 1;
+
+ return candidate;
+}
+
+int SceneGraphTimelineModel::findFirstIndexNoParents(qint64 startTime) const
+{
+ // TODO properly
+ return findFirstIndex(startTime);
+
+// int candidate = -1;
+// // in the "endtime" list, find the first event that ends after startTime
+// if (d->endTimeData.isEmpty())
+// return 0; // -1
+// if (d->endTimeData.count() == 1 || d->endTimeData.first().endTime >= startTime)
+// candidate = 0;
+// else
+// if (d->endTimeData.last().endTime <= startTime)
+// return 0; // -1
+
+// if (candidate == -1) {
+// int fromIndex = 0;
+// int toIndex = d->endTimeData.count()-1;
+// while (toIndex - fromIndex > 1) {
+// int midIndex = (fromIndex + toIndex)/2;
+// if (d->endTimeData[midIndex].endTime < startTime)
+// fromIndex = midIndex;
+// else
+// toIndex = midIndex;
+// }
+
+// candidate = toIndex;
+// }
+
+// int ndx = d->endTimeData[candidate].startTimeIndex;
+
+// return ndx;
+}
+
+int SceneGraphTimelineModel::findLastIndex(qint64 endTime) const
+{
+ // TODO properly
+ int candidate = 0;
+ for (int i = d->eventList.count()-1; i >= 0; i--)
+ if (d->eventList[i].startTime < endTime) {
+ candidate = i;
+ break;
+ }
+ return candidate;
+}
+
+int SceneGraphTimelineModel::getEventType(int index) const
+{
+ // TODO fix
+ return QmlDebug::PixmapCacheEvent;
+ //return QmlDebug::SceneGraphFrameEvent;
+// return 0;
+}
+
+int SceneGraphTimelineModel::getEventRow(int index) const
+{
+ return d->eventList[index].sgEventType + 1;
+ if (d->isExpanded)
+ return d->eventList[index].sgEventType + 1;
+ else
+ return 0;
+}
+
+qint64 SceneGraphTimelineModel::getDuration(int index) const
+{
+ return d->eventList[index].duration;
+}
+
+qint64 SceneGraphTimelineModel::getStartTime(int index) const
+{
+ return d->eventList[index].startTime;
+}
+
+qint64 SceneGraphTimelineModel::getEndTime(int index) const
+{
+ return getStartTime(index)+getDuration(index);
+}
+
+int SceneGraphTimelineModel::getEventId(int index) const
+{
+ return d->eventList[index].sgEventType;
+}
+
+QColor SceneGraphTimelineModel::getColor(int index) const
+{
+ // get duration in seconds
+ double eventDuration = getDuration(index) / 1e9;
+
+ // supposedly never above 60 frames per second
+ // limit it in that case
+ if (eventDuration < 1/60.0)
+ eventDuration = 1/60.0;
+
+ // generate hue based on fraction of the 60fps
+ double fpsFraction = 1 / (eventDuration * 60.0);
+ if (fpsFraction > 1.0)
+ fpsFraction = 1.0;
+ return QColor::fromHsl((fpsFraction*96)+10, 76, 166);
+}
+
+float SceneGraphTimelineModel::getHeight(int index) const
+{
+ return 1.0f;
+}
+
+QString labelForSGType(int t)
+{
+ switch ((SceneGraphCategoryType)t) {
+ case SceneGraphRenderThread: return QLatin1String("Renderer Thread");
+ case SceneGraphGUIThread: return QLatin1String("GUI Thread");
+ }
+}
+
+const QVariantList SceneGraphTimelineModel::getLabelsForCategory(int category) const
+{
+ QVariantList result;
+
+ for (int i = 0; i < MaximumSceneGraphCategoryType; i++) {
+ QVariantMap element;
+ element.insert(QLatin1String("displayName"), QVariant(labelForSGType(i)));
+ element.insert(QLatin1String("description"), QVariant(labelForSGType(i)));
+ element.insert(QLatin1String("id"), QVariant(i));
+ result << element;
+ }
+
+ return result;
+}
+
+
+
+QString SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::displayTime(double time)
+{
+ if (time < 1e6)
+ return QString::number(time/1e3,'f',3) + trUtf8(" \xc2\xb5s");
+ if (time < 1e9)
+ return QString::number(time/1e6,'f',3) + tr(" ms");
+
+ return QString::number(time/1e9,'f',3) + tr(" s");
+}
+
+void SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::addVP(QVariantList &l, QString label, qint64 time)
+{
+ if (time > 0) {
+ QVariantMap res;
+ res.insert(label, QVariant(displayTime(time)));
+ l << res;
+ }
+}
+
+
+const QVariantList SceneGraphTimelineModel::getEventDetails(int index) const
+{
+ QVariantList result;
+ SceneGraphEvent *ev = &d->eventList[index];
+
+ {
+ QVariantMap res;
+ res.insert(tr("title"), QVariant(labelForSGType(ev->sgEventType)));
+ result << res;
+ }
+
+ d->addVP(result, tr("duration"), ev->duration );
+
+ if (ev->sgEventType == SceneGraphRenderThread) {
+ d->addVP(result, tr("polish"), ev->timing[14]);
+ d->addVP(result, tr("sync"), ev->timing[0]);
+ d->addVP(result, tr("preprocess"), ev->timing[1]);
+ d->addVP(result, tr("upload"), ev->timing[2]);
+ d->addVP(result, tr("swizzle"), ev->timing[3]);
+ d->addVP(result, tr("convert"), ev->timing[4]);
+ d->addVP(result, tr("mipmap"), ev->timing[5]);
+ d->addVP(result, tr("bind"), ev->timing[6]);
+ d->addVP(result, tr("material"), ev->timing[7]);
+ d->addVP(result, tr("glyph render"), ev->timing[8]);
+ d->addVP(result, tr("glyph store"), ev->timing[9]);
+ d->addVP(result, tr("update"), ev->timing[10]);
+ d->addVP(result, tr("binding"), ev->timing[11]);
+ d->addVP(result, tr("render"), ev->timing[12]);
+ d->addVP(result, tr("swap"), ev->timing[13]);
+ d->addVP(result, tr("animations"), ev->timing[15]);
+ }
+ if (ev->sgEventType == SceneGraphGUIThread) {
+ d->addVP(result, tr("polish"), ev->timing[0]);
+ d->addVP(result, tr("wait"), ev->timing[1]);
+ d->addVP(result, tr("sync"), ev->timing[2]);
+ d->addVP(result, tr("animations"), ev->timing[3]);
+ }
+
+ return result;
+}
+
+bool compareStartTimes(const SceneGraphTimelineModel::SceneGraphEvent&t1, const SceneGraphTimelineModel::SceneGraphEvent &t2)
+{
+ return t1.startTime < t2.startTime;
+}
+
+void SceneGraphTimelineModel::loadData()
+{
+ clear();
+ QmlProfilerSimpleModel *simpleModel = m_modelManager->simpleModel();
+ if (simpleModel->isEmpty())
+ return;
+
+ int lastRenderEvent = -1;
+
+ // combine the data of several eventtypes into two rows
+ foreach (const QmlProfilerSimpleModel::QmlEventData &event, simpleModel->getEvents()) {
+ if (!eventAccepted(event))
+ continue;
+
+ if (event.bindingType == SceneGraphRenderLoopFrame) {
+ SceneGraphEvent newEvent;
+ newEvent.sgEventType = SceneGraphRenderThread;
+ newEvent.duration = event.numericData1 + event.numericData2 + event.numericData3;
+ newEvent.startTime = event.startTime - newEvent.duration;
+ for (int i=0; i < timingFieldCount; i++)
+ newEvent.timing[i] = 0;
+
+ d->eventList << newEvent;
+ lastRenderEvent = d->eventList.count()-1;
+ }
+
+ if (lastRenderEvent >= 0) {
+ switch ((SceneGraphEventType)event.bindingType) {
+ case SceneGraphRendererFrame: {
+ d->eventList[lastRenderEvent].timing[1] = event.numericData1;
+ d->eventList[lastRenderEvent].timing[10] = event.numericData2;
+ d->eventList[lastRenderEvent].timing[11] = event.numericData3;
+ d->eventList[lastRenderEvent].timing[12] = event.numericData4;
+ break;
+ }
+ case SceneGraphAdaptationLayerFrame: {
+ d->eventList[lastRenderEvent].timing[8] = event.numericData2;
+ d->eventList[lastRenderEvent].timing[9] = event.numericData3;
+ break;
+ }
+ case SceneGraphContextFrame: {
+ d->eventList[lastRenderEvent].timing[7] = event.numericData1;
+ break;
+ }
+ case SceneGraphRenderLoopFrame: {
+ d->eventList[lastRenderEvent].timing[0] = event.numericData1;
+ d->eventList[lastRenderEvent].timing[13] = event.numericData3;
+
+ break;
+ }
+ case SceneGraphTexturePrepare: {
+ d->eventList[lastRenderEvent].timing[2] = event.numericData4;
+ d->eventList[lastRenderEvent].timing[3] = event.numericData3;
+ d->eventList[lastRenderEvent].timing[4] = event.numericData2;
+ d->eventList[lastRenderEvent].timing[5] = event.numericData5;
+ d->eventList[lastRenderEvent].timing[6] = event.numericData1;
+ break;
+ }
+ case SceneGraphPolishAndSync: {
+ // GUI thread
+ SceneGraphEvent newEvent;
+ newEvent.sgEventType = SceneGraphGUIThread;
+ newEvent.duration = event.numericData1 + event.numericData2 + event.numericData3 + event.numericData4;
+ newEvent.startTime = event.startTime - newEvent.duration;
+ for (int i=0; i < timingFieldCount; i++)
+ newEvent.timing[i] = 0;
+
+ newEvent.timing[0] = event.numericData1;
+ newEvent.timing[1] = event.numericData2;
+ newEvent.timing[2] = event.numericData3;
+ newEvent.timing[3] = event.numericData4;
+
+ d->eventList << newEvent;
+ break;
+ }
+ case SceneGraphWindowsAnimations: {
+ d->eventList[lastRenderEvent].timing[14] = event.numericData1;
+ break;
+ }
+ case SceneGraphWindowsPolishFrame: {
+ d->eventList[lastRenderEvent].timing[15] = event.numericData1;
+ break;
+ }
+ }
+ }
+ }
+
+ qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
+}
+
+void SceneGraphTimelineModel::clear()
+{
+ d->eventList.clear();
+}
+
+void SceneGraphTimelineModel::dataChanged()
+{
+ if (m_modelManager->state() == QmlProfilerDataState::Done)
+ loadData();
+
+ if (m_modelManager->state() == QmlProfilerDataState::Empty)
+ clear();
+
+ emit stateChanged();
+ emit dataAvailable();
+ emit emptyChanged();
+ return;
+}
+
+
+
+
+} // namespace Internal
+} // namespace QmlProfilerExtended
diff --git a/plugins/qmlprofilerextended/scenegraphtimelinemodel.h b/plugins/qmlprofilerextended/scenegraphtimelinemodel.h
new file mode 100644
index 0000000000..255ff936d5
--- /dev/null
+++ b/plugins/qmlprofilerextended/scenegraphtimelinemodel.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+****************************************************************************/
+
+#ifndef SCENEGRAPHTIMELINEMODEL_H
+#define SCENEGRAPHTIMELINEMODEL_H
+
+#include "qmlprofiler/abstracttimelinemodel.h"
+#include "qmlprofiler/qmlprofilermodelmanager.h"
+#include "qmlprofiler/qmlprofilersimplemodel.h"
+
+#include <QStringList>
+#include <QColor>
+
+namespace QmlProfilerExtended {
+namespace Internal {
+
+#define timingFieldCount 16
+
+class SceneGraphTimelineModel : public QmlProfiler::AbstractTimelineModel
+{
+ Q_OBJECT
+public:
+
+ struct SceneGraphEvent {
+ qint64 startTime;
+ qint64 duration;
+ int sgEventType;
+ qint64 timing[timingFieldCount];
+ };
+
+
+ SceneGraphTimelineModel(QObject *parent = 0);
+ ~SceneGraphTimelineModel();
+
+
+// void setModelManager(QmlProfiler::Internal::QmlProfilerModelManager *modelManager);
+
+ int categories() const;
+ QStringList categoryTitles() const;
+ QString name() const;
+ int count() const;
+
+ bool isEmpty() const;
+
+ bool eventAccepted(const QmlProfiler::Internal::QmlProfilerSimpleModel::QmlEventData &event) const;
+
+ Q_INVOKABLE qint64 lastTimeMark() const;
+
+ Q_INVOKABLE void setExpanded(int category, bool expanded);
+ Q_INVOKABLE int categoryDepth(int categoryIndex) const;
+ Q_INVOKABLE int categoryCount() const;
+ Q_INVOKABLE const QString categoryLabel(int categoryIndex) const;
+
+ int findFirstIndex(qint64 startTime) const;
+ int findFirstIndexNoParents(qint64 startTime) const;
+ int findLastIndex(qint64 endTime) const;
+
+ int getEventType(int index) const;
+ int getEventRow(int index) const;
+ Q_INVOKABLE qint64 getDuration(int index) const;
+ Q_INVOKABLE qint64 getStartTime(int index) const;
+ Q_INVOKABLE qint64 getEndTime(int index) const;
+ Q_INVOKABLE int getEventId(int index) const;
+ Q_INVOKABLE QColor getColor(int index) const;
+ Q_INVOKABLE float getHeight(int index) const;
+
+ Q_INVOKABLE const QVariantList getLabelsForCategory(int category) const;
+
+ Q_INVOKABLE const QVariantList getEventDetails(int index) const;
+
+ void loadData();
+ void clear();
+//signals:
+// void countChanged();
+// void dataAvailable();
+// void stateChanged();
+// void emptyChanged();
+// void expandedChanged();
+
+protected slots:
+ void dataChanged();
+
+private:
+ class SceneGraphTimelineModelPrivate;
+ SceneGraphTimelineModelPrivate *d;
+
+};
+
+} // namespace Internal
+} // namespace QmlProfilerExtended
+
+#endif // SCENEGRAPHTIMELINEMODEL_H
diff --git a/qmlprofiler.pro b/qmlprofiler.pro
index e00301d820..55ba4afb4f 100644
--- a/qmlprofiler.pro
+++ b/qmlprofiler.pro
@@ -2,4 +2,5 @@ TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += libs/qmldebug \
- plugins/qmlprofiler
+ plugins/qmlprofiler \
+ plugins/qmlprofilerextended
diff --git a/qtcreatorplugin.pri b/qtcreatorplugin.pri
index ec8494ec0f..3044256f79 100644
--- a/qtcreatorplugin.pri
+++ b/qtcreatorplugin.pri
@@ -4,5 +4,5 @@ IDE_BUILD_TREE=$$(IDE_BUILD_TREE)
isEmpty(IDE_SOURCE_TREE):error(Set IDE_SOURCE_TREE environment variable)
isEmpty(IDE_BUILD_TREE):error(Set IDE_BUILD_TREE environment variable)
-INCLUDEPATH+=$$PWD/libs
+INCLUDEPATH+=$$PWD/libs $$PWD/plugins
include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri)