aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristiaan Janssen <christiaan.janssen@digia.com>2013-06-11 14:48:47 +0200
committerKai Koehne <kai.koehne@digia.com>2013-06-11 16:31:38 +0300
commit3f6226930fc469693a9722c27b15273eb7cbefc9 (patch)
treede257aeafb2c202c976ada259dac55986cd271f9
parent59a91692b33a4beffaa02cc5d84c16ff2f7008dc (diff)
QmlProfiler: showing paint events
Change-Id: Iaf62b0291b4586ddbafe61d890206c2e5c779f1c Reviewed-by: Kai Koehne <kai.koehne@digia.com>
-rw-r--r--libs/qmldebug/qmlprofilereventtypes.h2
-rw-r--r--libs/qmldebug/qmlprofilertraceclient.cpp2
-rw-r--r--plugins/qmlprofiler/abstracttimelinemodel.cpp6
-rw-r--r--plugins/qmlprofiler/abstracttimelinemodel.h2
-rw-r--r--plugins/qmlprofiler/qmlprofiler.pro6
-rw-r--r--plugins/qmlprofiler/qmlprofiler.qbs2
-rw-r--r--plugins/qmlprofiler/qmlprofilermodelmanager.cpp10
-rw-r--r--plugins/qmlprofiler/qmlprofilermodelmanager.h5
-rw-r--r--plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp420
-rw-r--r--plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h118
-rw-r--r--plugins/qmlprofiler/qmlprofilersimplemodel.cpp8
-rw-r--r--plugins/qmlprofiler/qmlprofilersimplemodel.h11
-rw-r--r--plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp4
-rw-r--r--plugins/qmlprofiler/qmlprofilertool.cpp2
-rw-r--r--plugins/qmlprofiler/timelinemodelaggregator.cpp6
-rw-r--r--qtcreatorplugin.pri1
16 files changed, 592 insertions, 13 deletions
diff --git a/libs/qmldebug/qmlprofilereventtypes.h b/libs/qmldebug/qmlprofilereventtypes.h
index 7928bdf984..a5ece2928c 100644
--- a/libs/qmldebug/qmlprofilereventtypes.h
+++ b/libs/qmldebug/qmlprofilereventtypes.h
@@ -48,6 +48,8 @@ enum BindingType {
QmlBinding,
V8Binding,
OptimizedBinding,
+ QPainterEvent,
+ AnimationFrame,
MaximumBindingType
};
diff --git a/libs/qmldebug/qmlprofilertraceclient.cpp b/libs/qmldebug/qmlprofilertraceclient.cpp
index c7c99d353d..22c38b81fb 100644
--- a/libs/qmldebug/qmlprofilertraceclient.cpp
+++ b/libs/qmldebug/qmlprofilertraceclient.cpp
@@ -250,6 +250,8 @@ void QmlProfilerTraceClient::messageReceived(const QByteArray &data)
BindingType bindingType = QmlBinding;
if ((QmlEventType)range == Binding)
bindingType = d->bindingTypes.pop();
+ if ((QmlEventType)range == Painting)
+ bindingType = QPainterEvent;
emit this->range((QmlEventType)range, bindingType, startTime, time - startTime, data, location);
if (d->rangeCount[range] == 0) {
int count = d->rangeDatas[range].count() +
diff --git a/plugins/qmlprofiler/abstracttimelinemodel.cpp b/plugins/qmlprofiler/abstracttimelinemodel.cpp
index 0f04a04fc7..66d5be7296 100644
--- a/plugins/qmlprofiler/abstracttimelinemodel.cpp
+++ b/plugins/qmlprofiler/abstracttimelinemodel.cpp
@@ -65,5 +65,11 @@ int AbstractTimelineModel::getState() const
return (int)m_modelManager->state();
}
+int AbstractTimelineModel::getBindingLoopDest(int index) const
+{
+ Q_UNUSED(index);
+ return -1;
+}
+
}
diff --git a/plugins/qmlprofiler/abstracttimelinemodel.h b/plugins/qmlprofiler/abstracttimelinemodel.h
index bedfa2a9a7..081b3d26f9 100644
--- a/plugins/qmlprofiler/abstracttimelinemodel.h
+++ b/plugins/qmlprofiler/abstracttimelinemodel.h
@@ -79,7 +79,7 @@ public:
Q_INVOKABLE virtual qint64 getStartTime(int index) const = 0;
Q_INVOKABLE virtual qint64 getEndTime(int index) const = 0;
Q_INVOKABLE virtual int getEventId(int index) const = 0;
- Q_INVOKABLE virtual int getBindingLoopDest(int index) const = 0;
+ Q_INVOKABLE virtual int getBindingLoopDest(int index) const;
Q_INVOKABLE virtual QColor getColor(int index) const = 0;
Q_INVOKABLE virtual float getHeight(int index) const = 0;
diff --git a/plugins/qmlprofiler/qmlprofiler.pro b/plugins/qmlprofiler/qmlprofiler.pro
index 03aceb6970..6fe4fb18ba 100644
--- a/plugins/qmlprofiler/qmlprofiler.pro
+++ b/plugins/qmlprofiler/qmlprofiler.pro
@@ -30,7 +30,8 @@ SOURCES += \
qmlprofilertreeview.cpp \
qmlprofilertracefile.cpp \
abstracttimelinemodel.cpp \
- timelinemodelaggregator.cpp
+ timelinemodelaggregator.cpp \
+ qmlprofilerpainteventsmodelproxy.cpp
HEADERS += \
qmlprofilerconstants.h \
@@ -60,7 +61,8 @@ HEADERS += \
qmlprofilertreeview.h \
qmlprofilertracefile.h \
abstracttimelinemodel.h \
- timelinemodelaggregator.h
+ timelinemodelaggregator.h \
+ qmlprofilerpainteventsmodelproxy.h
RESOURCES += \
qml/qmlprofiler.qrc
diff --git a/plugins/qmlprofiler/qmlprofiler.qbs b/plugins/qmlprofiler/qmlprofiler.qbs
index 673c29cf22..a3e7428fe3 100644
--- a/plugins/qmlprofiler/qmlprofiler.qbs
+++ b/plugins/qmlprofiler/qmlprofiler.qbs
@@ -76,6 +76,8 @@ QtcPlugin {
"timelinemodelaggregator.h",
"timelinerenderer.cpp",
"timelinerenderer.h",
+ "qmlprofilerpainteventsmodelproxy.h",
+ "qmlprofilerpainteventsmodelproxy.cpp",
"canvas/qdeclarativecanvas.cpp",
"canvas/qdeclarativecanvas_p.h",
"canvas/qdeclarativecanvastimer.cpp",
diff --git a/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
index dc2d18d4ac..9f6b8725dc 100644
--- a/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
+++ b/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
@@ -202,6 +202,16 @@ void QmlProfilerModelManager::addV8Event(int depth, const QString &function, con
d->v8Model->addV8Event(depth, function, filename, lineNumber,totalTime, selfTime);
}
+void QmlProfilerModelManager::addFrameEvent(qint64 time, int framerate, int animationcount)
+{
+ if (d->traceTime->startTime() == -1)
+ d->traceTime->setStartTime(time);
+
+ QTC_ASSERT(state() == QmlProfilerDataState::AcquiringData, /**/);
+ d->model->addFrameEvent(time, framerate, animationcount);
+ emit countChanged();
+}
+
void QmlProfilerModelManager::addSceneGraphEvent(int eventType, int SGEtype, qint64 startTime, qint64 timing1, qint64 timing2, qint64 timing3, qint64 timing4, qint64 timing5)
{
if (d->traceTime->startTime() == -1)
diff --git a/plugins/qmlprofiler/qmlprofilermodelmanager.h b/plugins/qmlprofiler/qmlprofilermodelmanager.h
index d36bbceeac..faa4d53fe8 100644
--- a/plugins/qmlprofiler/qmlprofilermodelmanager.h
+++ b/plugins/qmlprofiler/qmlprofilermodelmanager.h
@@ -124,9 +124,8 @@ public slots:
qint64 timing1, qint64 timing2, qint64 timing3, qint64 timing4, qint64 timing5);
void addV8Event(int depth, const QString &function,const QString &filename, int lineNumber,
double totalTime, double selfTime);
-#ifdef PROFILER_FRAMEEVENTS
-/*change*/ void addFrameEvent(qint64 time, int framerate, int animationcount);
-#endif
+
+ void addFrameEvent(qint64 time, int framerate, int animationcount);
void complete();
diff --git a/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp
new file mode 100644
index 0000000000..75e1710d9f
--- /dev/null
+++ b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "qmlprofilerpainteventsmodelproxy.h"
+#include "qmlprofilermodelmanager.h"
+#include "qmlprofilersimplemodel.h"
+
+#include <QVector>
+#include <QHash>
+#include <QUrl>
+#include <QString>
+#include <QStack>
+
+#include <QDebug>
+
+namespace QmlProfiler {
+namespace Internal {
+
+struct CategorySpan {
+ bool expanded;
+ int expandedRows;
+ int contractedRows;
+};
+
+class PaintEventsModelProxy::PaintEventsModelProxyPrivate
+{
+public:
+ PaintEventsModelProxyPrivate(PaintEventsModelProxy *qq) : q(qq) {}
+ ~PaintEventsModelProxyPrivate() {}
+
+ QString displayTime(double time);
+ void computeAnimationCountLimit();
+
+ QVector <PaintEventsModelProxy::QmlPaintEventData> eventList;
+ int minAnimationCount;
+ int maxAnimationCount;
+
+ PaintEventsModelProxy *q;
+};
+
+PaintEventsModelProxy::PaintEventsModelProxy(QObject *parent)
+ : AbstractTimelineModel(parent), d(new PaintEventsModelProxyPrivate(this))
+{
+}
+
+PaintEventsModelProxy::~PaintEventsModelProxy()
+{
+ delete d;
+}
+
+int PaintEventsModelProxy::categories() const
+{
+ return categoryCount();
+}
+
+QStringList PaintEventsModelProxy::categoryTitles() const
+{
+ QStringList retString;
+ for (int i=0; i<categories(); i++)
+ retString << categoryLabel(i);
+ return retString;
+}
+
+QString PaintEventsModelProxy::name() const
+{
+ return QLatin1String("PaintEventsModelProxy");
+}
+
+const QVector<PaintEventsModelProxy::QmlPaintEventData> PaintEventsModelProxy::getData() const
+{
+ return d->eventList;
+}
+
+const QVector<PaintEventsModelProxy::QmlPaintEventData> PaintEventsModelProxy::getData(qint64 fromTime, qint64 toTime) const
+{
+ int fromIndex = findFirstIndex(fromTime);
+ int toIndex = findLastIndex(toTime);
+ if (fromIndex != -1 && toIndex > fromIndex)
+ return d->eventList.mid(fromIndex, toIndex - fromIndex + 1);
+ else
+ return QVector<PaintEventsModelProxy::QmlPaintEventData>();
+}
+
+void PaintEventsModelProxy::clear()
+{
+ d->eventList.clear();
+ d->minAnimationCount = 1;
+ d->maxAnimationCount = 1;
+}
+
+void PaintEventsModelProxy::dataChanged()
+{
+ if (m_modelManager->state() == QmlProfilerDataState::Done)
+ loadData();
+
+ if (m_modelManager->state() == QmlProfilerDataState::Empty)
+ clear();
+
+ emit stateChanged();
+ emit dataAvailable();
+ emit emptyChanged();
+}
+
+bool compareStartTimes(const PaintEventsModelProxy::QmlPaintEventData &t1, const PaintEventsModelProxy::QmlPaintEventData &t2)
+{
+ return t1.startTime < t2.startTime;
+}
+
+bool PaintEventsModelProxy::eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const
+{
+ return (event.eventType == QmlDebug::Painting && event.bindingType == QmlDebug::AnimationFrame);
+}
+
+void PaintEventsModelProxy::loadData()
+{
+ clear();
+ QmlProfilerSimpleModel *simpleModel = m_modelManager->simpleModel();
+ if (simpleModel->isEmpty())
+ return;
+
+// int lastEventId = 0;
+
+// d->prepare();
+
+ // collect events
+ const QVector<QmlProfilerSimpleModel::QmlEventData> referenceList = simpleModel->getEvents();
+ foreach (const QmlProfilerSimpleModel::QmlEventData &event, referenceList) {
+ if (!eventAccepted(event))
+ continue;
+
+ // the duration of the events is estimated from the framerate
+ // we need to correct it before appending a new event
+ if (d->eventList.count() > 0) {
+ QmlPaintEventData *lastEvent = &d->eventList[d->eventList.count()-1];
+ if (lastEvent->startTime + lastEvent->duration >= event.startTime)
+ // 1 nanosecond less to prevent overlap
+ lastEvent->duration = event.startTime - lastEvent->startTime - 1;
+ lastEvent->framerate = 1e9/lastEvent->duration;
+ }
+
+ QmlPaintEventData newEvent = {
+ event.startTime,
+ event.duration,
+ (int)event.numericData1,
+ (int)event.numericData2
+ };
+
+ d->eventList.append(newEvent);
+ }
+
+ d->computeAnimationCountLimit();
+
+// qSort(d->eventList.begin(), d->eventList.end(), compareStartTimes);
+
+ emit countChanged();
+}
+
+/////////////////// QML interface
+
+bool PaintEventsModelProxy::isEmpty() const
+{
+ return count() == 0;
+}
+
+int PaintEventsModelProxy::count() const
+{
+ return d->eventList.count();
+}
+
+qint64 PaintEventsModelProxy::lastTimeMark() const
+{
+ return d->eventList.last().startTime + d->eventList.last().duration;
+}
+
+void PaintEventsModelProxy::setExpanded(int category, bool expanded)
+{
+ Q_UNUSED(category);
+ Q_UNUSED(expanded);
+ emit expandedChanged();
+}
+
+int PaintEventsModelProxy::categoryDepth(int categoryIndex) const
+{
+ Q_UNUSED(categoryIndex);
+ if (isEmpty())
+ return 1;
+ else
+ return 2;
+}
+
+int PaintEventsModelProxy::categoryCount() const
+{
+ return 1;
+}
+
+const QString PaintEventsModelProxy::categoryLabel(int categoryIndex) const
+{
+ Q_UNUSED(categoryIndex);
+ return tr("Animations");
+}
+
+
+int PaintEventsModelProxy::findFirstIndex(qint64 startTime) const
+{
+ if (d->eventList.isEmpty())
+ return 0; // -1
+ if (d->eventList.count() == 1 || d->eventList.first().startTime+d->eventList.first().duration >= startTime)
+ return 0;
+ else
+ if (d->eventList.last().startTime+d->eventList.last().duration <= startTime)
+ return 0; // -1
+
+ int fromIndex = 0;
+ int toIndex = d->eventList.count()-1;
+ while (toIndex - fromIndex > 1) {
+ int midIndex = (fromIndex + toIndex)/2;
+ if (d->eventList[midIndex].startTime + d->eventList[midIndex].duration < startTime)
+ fromIndex = midIndex;
+ else
+ toIndex = midIndex;
+ }
+ return toIndex;
+}
+
+int PaintEventsModelProxy::findFirstIndexNoParents(qint64 startTime) const
+{
+ return findFirstIndex(startTime);
+}
+
+int PaintEventsModelProxy::findLastIndex(qint64 endTime) const
+{
+ if (d->eventList.isEmpty())
+ return 0; // -1
+ if (d->eventList.first().startTime >= endTime)
+ return 0; // -1
+ if (d->eventList.count() == 1)
+ return 0;
+ if (d->eventList.last().startTime <= endTime)
+ return d->eventList.count()-1;
+
+ int fromIndex = 0;
+ int toIndex = d->eventList.count()-1;
+ while (toIndex - fromIndex > 1) {
+ int midIndex = (fromIndex + toIndex)/2;
+ if (d->eventList[midIndex].startTime < endTime)
+ fromIndex = midIndex;
+ else
+ toIndex = midIndex;
+ }
+
+ return fromIndex;
+}
+
+int PaintEventsModelProxy::getEventType(int index) const
+{
+ Q_UNUSED(index);
+ return (int)QmlDebug::Painting;
+}
+
+int PaintEventsModelProxy::getEventRow(int index) const
+{
+ Q_UNUSED(index);
+ return 1;
+}
+
+qint64 PaintEventsModelProxy::getDuration(int index) const
+{
+ return d->eventList[index].duration;
+}
+
+qint64 PaintEventsModelProxy::getStartTime(int index) const
+{
+ return d->eventList[index].startTime;
+}
+
+qint64 PaintEventsModelProxy::getEndTime(int index) const
+{
+ return d->eventList[index].startTime + d->eventList[index].duration;
+}
+
+int PaintEventsModelProxy::getEventId(int index) const
+{
+ // there is only one event Id for all painting events
+ Q_UNUSED(index);
+ return 0;
+}
+
+QColor PaintEventsModelProxy::getColor(int index) const
+{
+ // TODO
+// return QColor("blue");
+// int ndx = getEventId(index);
+// return QColor::fromHsl((ndx*25)%360, 76, 166);
+ double fpsFraction = d->eventList[index].framerate / 60.0;
+ if (fpsFraction > 1.0)
+ fpsFraction = 1.0;
+ return QColor::fromHsl((fpsFraction*96)+10, 76, 166);
+}
+
+float PaintEventsModelProxy::getHeight(int index) const
+{
+ float scale = d->maxAnimationCount - d->minAnimationCount;
+ float fraction = 1.0f;
+ if (scale > 1)
+ fraction = (float)(d->eventList[index].animationcount -
+ d->minAnimationCount) / scale;
+
+ return fraction * 0.85f + 0.15f;
+}
+
+const QVariantList PaintEventsModelProxy::getLabelsForCategory(int category) const
+{
+ // TODO
+ QVariantList result;
+
+// if (d->categorySpan.count() > category && d->categorySpan[category].expanded) {
+// int eventCount = d->eventDict.count();
+// for (int i = 0; i < eventCount; i++) {
+// if (d->eventDict[i].eventType == category) {
+// QVariantMap element;
+// element.insert(QLatin1String("displayName"), QVariant(d->eventDict[i].displayName));
+// element.insert(QLatin1String("description"), QVariant(d->eventDict[i].details));
+// element.insert(QLatin1String("id"), QVariant(d->eventDict[i].eventId));
+// result << element;
+// }
+// }
+// }
+
+ return result;
+}
+
+QString PaintEventsModelProxy::PaintEventsModelProxyPrivate::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 PaintEventsModelProxy::PaintEventsModelProxyPrivate::computeAnimationCountLimit()
+{
+ minAnimationCount = 1;
+ maxAnimationCount = 1;
+ if (eventList.isEmpty())
+ return;
+
+ for (int i=0; i < eventList.count(); i++) {
+ if (eventList[i].animationcount < minAnimationCount)
+ minAnimationCount = eventList[i].animationcount;
+ if (eventList[i].animationcount > maxAnimationCount)
+ maxAnimationCount = eventList[i].animationcount;
+ }
+}
+
+const QVariantList PaintEventsModelProxy::getEventDetails(int index) const
+{
+ QVariantList result;
+// int eventId = getEventId(index);
+
+ {
+ QVariantMap valuePair;
+ valuePair.insert(tr("title"), QVariant(categoryLabel(0)));
+ result << valuePair;
+ }
+
+ // duration
+ {
+ QVariantMap valuePair;
+ valuePair.insert(tr("Duration:"), QVariant(d->displayTime(d->eventList[index].duration)));
+ result << valuePair;
+ }
+
+ // duration
+ {
+ QVariantMap valuePair;
+ valuePair.insert(tr("Framerate:"), QVariant(QString::fromLatin1("%1 FPS").arg(d->eventList[index].framerate)));
+ result << valuePair;
+ }
+
+ // duration
+ {
+ QVariantMap valuePair;
+ valuePair.insert(tr("Animations:"), QVariant(QString::fromLatin1("%1").arg(d->eventList[index].animationcount)));
+ result << valuePair;
+ }
+
+ return result;
+}
+
+}
+}
+
diff --git a/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h
new file mode 100644
index 0000000000..bdfbbb6d6a
--- /dev/null
+++ b/plugins/qmlprofiler/qmlprofilerpainteventsmodelproxy.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+
+#ifndef QMLPROFILERPAINTEVENTSMODELPROXY_H
+#define QMLPROFILERPAINTEVENTSMODELPROXY_H
+
+#include <QObject>
+#include "abstracttimelinemodel.h"
+#include <qmldebug/qmlprofilereventtypes.h>
+#include <qmldebug/qmlprofilereventlocation.h>
+//#include <QHash>
+//#include <QVector>
+#include <QVariantList>
+//#include <QVariantMap>
+#include "qmlprofilersimplemodel.h"
+#include <QColor>
+
+
+namespace QmlProfiler {
+namespace Internal {
+
+class QmlProfilerModelManager;
+
+class PaintEventsModelProxy : public AbstractTimelineModel
+{
+// Q_PROPERTY(bool empty READ isEmpty NOTIFY emptyChanged)
+
+ Q_OBJECT
+public:
+
+ struct QmlPaintEventData {
+ qint64 startTime;
+ qint64 duration;
+ int framerate;
+ int animationcount;
+ };
+
+ PaintEventsModelProxy(QObject *parent = 0);
+ ~PaintEventsModelProxy();
+
+
+ int categories() const;
+ QStringList categoryTitles() const;
+ QString name() const;
+
+ const QVector<QmlPaintEventData> getData() const;
+ const QVector<QmlPaintEventData> getData(qint64 fromTime, qint64 toTime) const;
+ void loadData();
+ Q_INVOKABLE int count() const;
+ void clear();
+
+ bool isEmpty() 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;
+
+private slots:
+ bool eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const;
+protected slots:
+ void dataChanged();
+
+private:
+ class PaintEventsModelProxyPrivate;
+ PaintEventsModelProxyPrivate *d;
+
+};
+
+}
+}
+
+#endif
diff --git a/plugins/qmlprofiler/qmlprofilersimplemodel.cpp b/plugins/qmlprofiler/qmlprofilersimplemodel.cpp
index ee98828562..bf2985de45 100644
--- a/plugins/qmlprofiler/qmlprofilersimplemodel.cpp
+++ b/plugins/qmlprofiler/qmlprofilersimplemodel.cpp
@@ -31,6 +31,7 @@
#include <QStringList>
#include <QVector>
#include <QDebug>
+#include "qmldebug/qmlprofilereventtypes.h"
namespace QmlProfiler {
namespace Internal {
@@ -74,6 +75,13 @@ void QmlProfilerSimpleModel::addRangedEvent(int type, int bindingType, qint64 st
eventList.append(eventData);
}
+void QmlProfilerSimpleModel::addFrameEvent(qint64 time, int framerate, int animationcount)
+{
+ qint64 duration = 1e9 / framerate;
+ QmlEventData eventData = {tr("Animations"), QmlDebug::Painting, QmlDebug::AnimationFrame, time, duration, QStringList(), QmlDebug::QmlEventLocation(), framerate, animationcount, 0, 0, 0};
+ eventList.append(eventData);
+}
+
void QmlProfilerSimpleModel::addSceneGraphEvent(int eventType, int SGEtype, qint64 startTime, qint64 timing1, qint64 timing2, qint64 timing3, qint64 timing4, qint64 timing5)
{
QmlEventData eventData = {QString(), eventType, SGEtype, startTime, 0, QStringList(), QmlDebug::QmlEventLocation(), timing1, timing2, timing3, timing4, timing5};
diff --git a/plugins/qmlprofiler/qmlprofilersimplemodel.h b/plugins/qmlprofiler/qmlprofilersimplemodel.h
index ed30b0bba2..c2c2c01bb0 100644
--- a/plugins/qmlprofiler/qmlprofilersimplemodel.h
+++ b/plugins/qmlprofiler/qmlprofilersimplemodel.h
@@ -54,11 +54,11 @@ public:
qint64 duration;
QStringList data;
QmlDebug::QmlEventLocation location;
- qint64 timing1;
- qint64 timing2;
- qint64 timing3;
- qint64 timing4;
- qint64 timing5;
+ qint64 numericData1;
+ qint64 numericData2;
+ qint64 numericData3;
+ qint64 numericData4;
+ qint64 numericData5;
};
explicit QmlProfilerSimpleModel(QObject *parent = 0);
@@ -69,6 +69,7 @@ public:
const QVector<QmlEventData> &getEvents() const;
int count() const;
void addRangedEvent(int type, int bindingType, qint64 startTime, qint64 length, const QStringList &data, const QmlDebug::QmlEventLocation &location);
+ void addFrameEvent(qint64 time, int framerate, int animationcount);
void addSceneGraphEvent(int eventType, int SGEtype, qint64 startTime, qint64 timing1, qint64 timing2, qint64 timing3, qint64 timing4, qint64 timing5);
qint64 lastTimeMark() const;
virtual void complete();
diff --git a/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp b/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp
index b2220e83a3..adfec9fd9c 100644
--- a/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp
+++ b/plugins/qmlprofiler/qmlprofilertimelinemodelproxy.cpp
@@ -163,6 +163,10 @@ bool compareEndTimes(const BasicTimelineModel::QmlRangeEventEndInstance &t1, con
bool BasicTimelineModel::eventAccepted(const QmlProfilerSimpleModel::QmlEventData &event) const
{
+ // only accept Qt4.x Painting events
+ if (event.eventType == QmlDebug::Painting)
+ return event.bindingType == QmlDebug::QPainterEvent;
+
return (event.eventType <= QmlDebug::HandlingSignal);
}
diff --git a/plugins/qmlprofiler/qmlprofilertool.cpp b/plugins/qmlprofiler/qmlprofilertool.cpp
index 5c3926c4b9..52bc43d207 100644
--- a/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -161,9 +161,7 @@ QmlProfilerTool::QmlProfilerTool(QObject *parent)
SIGNAL(addV8Event(int,QString,QString,int,double,double)),
d->m_profilerModelManager,
SLOT(addV8Event(int,QString,QString,int,double,double)));
-#ifdef PROFILER_FRAMEEVENTS
connect(d->m_profilerConnections, SIGNAL(addFrameEvent(qint64,int,int)), d->m_profilerModelManager, SLOT(addFrameEvent(qint64,int,int)));
-#endif
connect(d->m_profilerConnections, SIGNAL(traceStarted(qint64)), d->m_profilerModelManager->traceTime(), SLOT(setStartTime(qint64)));
connect(d->m_profilerConnections, SIGNAL(traceFinished(qint64)), d->m_profilerModelManager->traceTime(), SLOT(setEndTime(qint64)));
connect(d->m_profilerConnections, SIGNAL(dataReadyForProcessing()), d->m_profilerModelManager, SLOT(complete()));
diff --git a/plugins/qmlprofiler/timelinemodelaggregator.cpp b/plugins/qmlprofiler/timelinemodelaggregator.cpp
index bfd8c3276c..42a5882137 100644
--- a/plugins/qmlprofiler/timelinemodelaggregator.cpp
+++ b/plugins/qmlprofiler/timelinemodelaggregator.cpp
@@ -30,6 +30,7 @@
#include "timelinemodelaggregator.h"
#include <QStringList>
#include "qmlprofilertimelinemodelproxy.h"
+#include "qmlprofilerpainteventsmodelproxy.h"
#include <QVariant>
#include "qmlprofilerplugin.h"
@@ -72,6 +73,11 @@ void TimelineModelAggregator::setModelManager(QmlProfilerModelManager *modelMana
// connect(modelManager,SIGNAL(stateChanged()),this,SLOT(dataChanged()));
// connect(modelManager,SIGNAL(countChanged()),this,SIGNAL(countChanged()));
// d->modelList << new BasicTimelineModel(modelManager, this);
+
+ PaintEventsModelProxy *paintEventsModelProxy = new PaintEventsModelProxy(this);
+ paintEventsModelProxy->setModelManager(modelManager);
+ addModel(paintEventsModelProxy);
+
BasicTimelineModel *basicTimelineModel = new BasicTimelineModel(this);
basicTimelineModel->setModelManager(modelManager);
addModel(basicTimelineModel);
diff --git a/qtcreatorplugin.pri b/qtcreatorplugin.pri
index adf4faec63..ec8494ec0f 100644
--- a/qtcreatorplugin.pri
+++ b/qtcreatorplugin.pri
@@ -4,4 +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
include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri)