diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp index d99763e4cd5..623c22fe499 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -304,10 +304,15 @@ qint64 AbstractTimelineModel::endTime(int index) const return d->ranges[index].start + d->ranges[index].duration; } +/*! + Returns the type ID of the event with event ID \a index. The type ID is a globally valid ID which + can be used to communicate metainformation about events to other parts of the program. By default + it is -1, which means there is no global type information about the event. + */ int AbstractTimelineModel::typeId(int index) const { - Q_D(const AbstractTimelineModel); - return d->ranges[index].typeId; + Q_UNUSED(index) + return -1; } /*! @@ -374,10 +379,17 @@ QVariantMap AbstractTimelineModel::location(int index) const return map; } +/*! + Returns \c true if this model can contain events of global type Id \a typeIndex. Otherwise + returns \c false. + */ bool AbstractTimelineModel::handlesTypeId(int typeIndex) const { - Q_UNUSED(typeIndex); - return false; + if (typeIndex < 0) + return false; + + Q_D(const AbstractTimelineModel); + return accepted(d->modelManager->qmlModel()->getEventTypes().at(typeIndex)); } int AbstractTimelineModel::selectionIdForLocation(const QString &filename, int line, int column) const @@ -453,16 +465,17 @@ QColor AbstractTimelineModel::colorByHue(int hue) const } /*! - \fn int AbstractTimelineModel::insert(qint64 startTime, qint64 duration) - Inserts a range at the given time position and returns its index. + Inserts an event at the time specified by \a startTime with the given \a duration and returns + its index. The \a selectionId determines the selection group the new event belongs to. + \sa selectionId() */ -int AbstractTimelineModel::insert(qint64 startTime, qint64 duration, int typeId) +int AbstractTimelineModel::insert(qint64 startTime, qint64 duration, int selectionId) { Q_D(AbstractTimelineModel); /* Doing insert-sort here is preferable as most of the time the times will actually be * presorted in the right way. So usually this will just result in appending. */ int index = d->insertSorted(d->ranges, - AbstractTimelineModelPrivate::Range(startTime, duration, typeId)); + AbstractTimelineModelPrivate::Range(startTime, duration, selectionId)); if (index < d->ranges.size() - 1) d->incrementStartIndices(index); d->insertSorted(d->endTimes, @@ -471,15 +484,15 @@ int AbstractTimelineModel::insert(qint64 startTime, qint64 duration, int typeId) } /*! - \fn int AbstractTimelineModel::insertStart(qint64 startTime, int typeId) - Inserts the given data as range start at the given time position and - returns its index. The range end is not set. + Inserts a range start at the time given by \a startTime and returns its index. The range end is + not set. The \a selectionId determines the selection group the new event belongs to. + \sa selectionId() */ -int AbstractTimelineModel::insertStart(qint64 startTime, int typeId) +int AbstractTimelineModel::insertStart(qint64 startTime, int selectionId) { Q_D(AbstractTimelineModel); int index = d->insertSorted(d->ranges, - AbstractTimelineModelPrivate::Range(startTime, 0, typeId)); + AbstractTimelineModelPrivate::Range(startTime, 0, selectionId)); if (index < d->ranges.size() - 1) d->incrementStartIndices(index); return index; @@ -567,10 +580,18 @@ int AbstractTimelineModel::rowCount() const return d->expanded ? d->expandedRowCount : d->collapsedRowCount; } +/*! + Returns the ID of the selection group the event with event Id \a index belongs to. Selection + groups are local to the model and the model can arbitrarily assign events to selection groups + when inserting them. + If one event from a selection group is selected, all visible other events from the same + selection group are highlighted. Rows are expected to correspond to selection IDs when the view + is expanded. + */ int AbstractTimelineModel::selectionId(int index) const { Q_D(const AbstractTimelineModel); - return d->ranges[index].typeId; + return d->ranges[index].selectionId; } void AbstractTimelineModel::clear() diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.h b/src/plugins/qmlprofiler/abstracttimelinemodel.h index c877400f364..80086f0e6a9 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.h @@ -73,13 +73,12 @@ public: qint64 duration(int index) const; qint64 startTime(int index) const; qint64 endTime(int index) const; - int typeId(int index) const; + int selectionId(int index) const; int firstIndex(qint64 startTime) const; int firstIndexNoParents(qint64 startTime) const; int lastIndex(qint64 endTime) const; - bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const; bool expanded() const; bool hidden() const; void setExpanded(bool expanded); @@ -97,8 +96,9 @@ public: // Methods which can optionally be implemented by child models. // returned map should contain "file", "line", "column" properties, or be empty virtual QVariantMap location(int index) const; - virtual int selectionId(int index) const; + virtual int typeId(int index) const; virtual bool handlesTypeId(int typeId) const; + virtual bool accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const; virtual int selectionIdForLocation(const QString &filename, int line, int column) const; virtual int bindingLoopDest(int index) const; virtual float relativeHeight(int index) const; @@ -120,8 +120,8 @@ protected: QColor colorByFraction(double fraction) const; QColor colorByHue(int hue) const; - int insert(qint64 startTime, qint64 duration, int typeId); - int insertStart(qint64 startTime, int typeId); + int insert(qint64 startTime, qint64 duration, int selectionId); + int insertStart(qint64 startTime, int selectionId); void insertEnd(int index, qint64 duration); void computeNesting(); diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel_p.h b/src/plugins/qmlprofiler/abstracttimelinemodel_p.h index a3f4f3e5d7d..ab931030a4e 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel_p.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel_p.h @@ -48,12 +48,12 @@ public: }; struct Range { - Range() : start(-1), duration(-1), typeId(-1), parent(-1) {} - Range(qint64 start, qint64 duration, int typeId) : - start(start), duration(duration), typeId(typeId), parent(-1) {} + Range() : start(-1), duration(-1), selectionId(-1), parent(-1) {} + Range(qint64 start, qint64 duration, int selectionId) : + start(start), duration(duration), selectionId(selectionId), parent(-1) {} qint64 start; qint64 duration; - int typeId; + int selectionId; int parent; inline qint64 timestamp() const {return start;} }; diff --git a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp index 359f360ef12..ae174700780 100644 --- a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.cpp @@ -82,6 +82,7 @@ void QmlProfilerAnimationsModel::loadData() const QVector &referenceList = simpleModel->getEvents(); const QVector &typeList = simpleModel->getEventTypes(); + QmlDebug::AnimationThread lastThread; QmlPaintEventData lastEvent; qint64 minNextStartTimes[] = {0, 0}; @@ -90,7 +91,7 @@ void QmlProfilerAnimationsModel::loadData() if (!accepted(type)) continue; - lastEvent.threadId = (QmlDebug::AnimationThread)event.numericData3; + lastThread = (QmlDebug::AnimationThread)event.numericData3; // initial estimation of the event duration: 1/framerate qint64 estimatedDuration = event.numericData1 > 0 ? 1e9/event.numericData1 : 1; @@ -99,7 +100,7 @@ void QmlProfilerAnimationsModel::loadData() qint64 realEndTime = event.startTime; // ranges should not overlap. If they do, our estimate wasn't accurate enough - qint64 realStartTime = qMax(event.startTime - estimatedDuration, minNextStartTimes[lastEvent.threadId]); + qint64 realStartTime = qMax(event.startTime - estimatedDuration, minNextStartTimes[lastThread]); // Sometimes our estimate is far off or the server has miscalculated the frame rate if (realStartTime >= realEndTime) @@ -107,18 +108,19 @@ void QmlProfilerAnimationsModel::loadData() // Don't "fix" the framerate even if we've fixed the duration. // The server should know better after all and if it doesn't we want to see that. + lastEvent.typeId = event.typeIndex; lastEvent.framerate = (int)event.numericData1; lastEvent.animationcount = (int)event.numericData2; QTC_ASSERT(lastEvent.animationcount > 0, continue); - m_data.insert(insert(realStartTime, realEndTime - realStartTime, event.typeIndex), lastEvent); + m_data.insert(insert(realStartTime, realEndTime - realStartTime, lastThread), lastEvent); - if (lastEvent.threadId == QmlDebug::GuiThread) + if (lastThread == QmlDebug::GuiThread) m_maxGuiThreadAnimations = qMax(lastEvent.animationcount, m_maxGuiThreadAnimations); else m_maxRenderThreadAnimations = qMax(lastEvent.animationcount, m_maxRenderThreadAnimations); - minNextStartTimes[lastEvent.threadId] = event.startTime + 1; + minNextStartTimes[lastThread] = event.startTime + 1; updateProgress(count(), referenceList.count()); } @@ -131,14 +133,14 @@ void QmlProfilerAnimationsModel::loadData() /////////////////// QML interface -int QmlProfilerAnimationsModel::rowFromThreadId(QmlDebug::AnimationThread threadId) const +int QmlProfilerAnimationsModel::rowFromThreadId(int threadId) const { return (threadId == QmlDebug::GuiThread || m_maxGuiThreadAnimations == 0) ? 1 : 2; } int QmlProfilerAnimationsModel::row(int index) const { - return rowFromThreadId(m_data[index].threadId); + return rowFromThreadId(selectionId(index)); } int QmlProfilerAnimationsModel::rowMaxValue(int rowNumber) const @@ -153,9 +155,9 @@ int QmlProfilerAnimationsModel::rowMaxValue(int rowNumber) const } } -int QmlProfilerAnimationsModel::selectionId(int index) const +int QmlProfilerAnimationsModel::typeId(int index) const { - return m_data[index].threadId; + return m_data[index].typeId; } QColor QmlProfilerAnimationsModel::color(int index) const @@ -170,16 +172,16 @@ QColor QmlProfilerAnimationsModel::color(int index) const float QmlProfilerAnimationsModel::relativeHeight(int index) const { - const QmlPaintEventData &data = m_data[index]; + const int thread = selectionId(index); // Add some height to the events if we're far from the scale threshold of 2 * DefaultRowHeight. // Like that you can see the smaller events more easily. - int scaleThreshold = 2 * defaultRowHeight() - rowHeight(rowFromThreadId(data.threadId)); + int scaleThreshold = 2 * defaultRowHeight() - rowHeight(rowFromThreadId(thread)); float boost = scaleThreshold > 0 ? (0.15 * scaleThreshold / defaultRowHeight()) : 0; - return boost + (1.0 - boost) * (float)data.animationcount / - (float)(data.threadId == QmlDebug::GuiThread ? m_maxGuiThreadAnimations : - m_maxRenderThreadAnimations); + return boost + (1.0 - boost) * (float)m_data[index].animationcount / + (float)(thread == QmlDebug::GuiThread ? m_maxGuiThreadAnimations : + m_maxRenderThreadAnimations); } QVariantList QmlProfilerAnimationsModel::labels() const @@ -213,8 +215,8 @@ QVariantMap QmlProfilerAnimationsModel::details(int index) const result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(duration(index))); result.insert(tr("Framerate"), QString::fromLatin1("%1 FPS").arg(m_data[index].framerate)); result.insert(tr("Animations"), QString::fromLatin1("%1").arg(m_data[index].animationcount)); - result.insert(tr("Context"), tr(m_data[index].threadId == QmlDebug::GuiThread ? - "GUI Thread" : "Render Thread")); + result.insert(tr("Context"), tr(selectionId(index) == QmlDebug::GuiThread ? "GUI Thread" : + "Render Thread")); return result; } diff --git a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.h b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.h index 94070440e97..b7a7c70d5f9 100644 --- a/src/plugins/qmlprofiler/qmlprofileranimationsmodel.h +++ b/src/plugins/qmlprofiler/qmlprofileranimationsmodel.h @@ -57,14 +57,14 @@ public: struct QmlPaintEventData { int framerate; int animationcount; - QmlDebug::AnimationThread threadId; + int typeId; }; QmlProfilerAnimationsModel(QObject *parent = 0); int rowMaxValue(int rowNumber) const; - int selectionId(int index) const; + int typeId(int index) const; int row(int index) const; QColor color(int index) const; @@ -84,7 +84,7 @@ private: QVector m_data; int m_maxGuiThreadAnimations; int m_maxRenderThreadAnimations; - int rowFromThreadId(QmlDebug::AnimationThread threadId) const; + int rowFromThreadId(int threadId) const; }; } diff --git a/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp b/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp index 6356e5a5749..0bc5ca67bde 100644 --- a/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerrangemodel.cpp @@ -259,15 +259,9 @@ QVariantMap QmlProfilerRangeModel::location(int index) const return result; } -bool QmlProfilerRangeModel::handlesTypeId(int typeId) const +int QmlProfilerRangeModel::typeId(int index) const { - if (typeId < 0) - return false; - const QmlProfilerDataModel::QmlEventTypeData &type = - modelManager()->qmlModel()->getEventTypes().at(typeId); - if (type.message != message() || type.rangeType != rangeType()) - return false; - return true; + return selectionId(index); } int QmlProfilerRangeModel::selectionIdForLocation(const QString &filename, int line, int column) const diff --git a/src/plugins/qmlprofiler/qmlprofilerrangemodel.h b/src/plugins/qmlprofiler/qmlprofilerrangemodel.h index 3cd9cfc58e7..a6859041c4f 100644 --- a/src/plugins/qmlprofiler/qmlprofilerrangemodel.h +++ b/src/plugins/qmlprofiler/qmlprofilerrangemodel.h @@ -74,7 +74,7 @@ public: QVariantMap details(int index) const; QVariantMap location(int index) const; - bool handlesTypeId(int typeIndex) const; + int typeId(int index) const; int selectionIdForLocation(const QString &filename, int line, int column) const; protected: