diff options
-rw-r--r-- | plugins/qmlprofilerextension/inputeventsmodel.cpp | 87 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/inputeventsmodel.h | 20 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/memoryusagemodel.cpp | 168 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/memoryusagemodel.h | 24 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/pixmapcachemodel.cpp | 267 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/pixmapcachemodel.h | 71 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/qmlprofilerextension.qbs | 1 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp | 25 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp | 221 | ||||
-rw-r--r-- | plugins/qmlprofilerextension/scenegraphtimelinemodel.h | 60 |
10 files changed, 437 insertions, 507 deletions
diff --git a/plugins/qmlprofilerextension/inputeventsmodel.cpp b/plugins/qmlprofilerextension/inputeventsmodel.cpp index 7d67f2b773..41403d9016 100644 --- a/plugins/qmlprofilerextension/inputeventsmodel.cpp +++ b/plugins/qmlprofilerextension/inputeventsmodel.cpp @@ -19,34 +19,24 @@ #include "inputeventsmodel.h" #include "qmldebug/qmlprofilereventtypes.h" #include "qmlprofiler/qmlprofilermodelmanager.h" -#include "qmlprofiler/abstracttimelinemodel_p.h" namespace QmlProfilerExtension { namespace Internal { using namespace QmlProfiler; -class InputEventsModel::InputEventsModelPrivate : public AbstractTimelineModelPrivate +InputEventsModel::InputEventsModel(QmlProfilerModelManager *manager, QObject *parent) : + QmlProfilerTimelineModel(manager, + tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileInputEvents)), + QmlDebug::Event, QmlDebug::MaximumRangeType, parent), + m_keyTypeId(-1), m_mouseTypeId(-1) { - Q_DECLARE_PUBLIC(InputEventsModel) -}; - -InputEventsModel::InputEventsModel(QObject *parent) - : AbstractTimelineModel(new InputEventsModelPrivate(), - tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileInputEvents)), - QmlDebug::Event, QmlDebug::MaximumRangeType, parent) -{ -} - -quint64 InputEventsModel::features() const -{ - return 1 << QmlDebug::ProfileInputEvents; + announceFeatures(1 << QmlDebug::ProfileInputEvents); } -int InputEventsModel::selectionId(int index) const +int InputEventsModel::typeId(int index) const { - Q_D(const InputEventsModel); - return d->modelManager->qmlModel()->getEventTypes()[range(index).typeId].detailType; + return selectionId(index) == QmlDebug::Mouse ? m_mouseTypeId : m_keyTypeId; } QColor InputEventsModel::color(int index) const @@ -56,24 +46,17 @@ QColor InputEventsModel::color(int index) const QVariantList InputEventsModel::labels() const { - Q_D(const InputEventsModel); QVariantList result; - if (d->expanded && !d->hidden && !isEmpty()) { - { - QVariantMap element; - element.insert(QLatin1String("description"), QVariant(tr("Mouse Events"))); - element.insert(QLatin1String("id"), QVariant(QmlDebug::Mouse)); - result << element; - } + QVariantMap element; + element.insert(QLatin1String("description"), QVariant(tr("Mouse Events"))); + element.insert(QLatin1String("id"), QVariant(QmlDebug::Mouse)); + result << element; - { - QVariantMap element; - element.insert(QLatin1String("description"), QVariant(tr("Keyboard Events"))); - element.insert(QLatin1String("id"), QVariant(QmlDebug::Key)); - result << element; - } - } + element.clear(); + element.insert(QLatin1String("description"), QVariant(tr("Keyboard Events"))); + element.insert(QLatin1String("id"), QVariant(QmlDebug::Key)); + result << element; return result; } @@ -87,18 +70,21 @@ QVariantMap InputEventsModel::details(int index) const return result; } -int InputEventsModel::row(int index) const +int InputEventsModel::expandedRow(int index) const { - if (!expanded()) - return 1; return selectionId(index) == QmlDebug::Mouse ? 1 : 2; } +int InputEventsModel::collapsedRow(int index) const +{ + Q_UNUSED(index) + return 1; +} + void InputEventsModel::loadData() { - Q_D(InputEventsModel); clear(); - QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel(); + QmlProfilerDataModel *simpleModel = modelManager()->qmlModel(); if (simpleModel->isEmpty()) return; @@ -107,18 +93,29 @@ void InputEventsModel::loadData() const QmlProfilerDataModel::QmlEventTypeData &type = types[event.typeIndex]; if (!accepted(type)) continue; - insert(event.startTime, 0, event.typeIndex); - d->modelManager->modelProxyCountUpdated(d->modelId, count(), - simpleModel->getEvents().count()); + insert(event.startTime, 0, type.detailType); + if (type.detailType == QmlDebug::Mouse) { + if (m_mouseTypeId == -1) + m_mouseTypeId = event.typeIndex; + } else if (m_keyTypeId == -1) { + m_keyTypeId = event.typeIndex; + } + updateProgress(count(), simpleModel->getEvents().count()); } - d->collapsedRowCount = 2; - d->expandedRowCount = 3; - d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); + setCollapsedRowCount(2); + setExpandedRowCount(3); + updateProgress(1, 1); +} + +void InputEventsModel::clear() +{ + m_keyTypeId = m_mouseTypeId = -1; + QmlProfilerTimelineModel::clear(); } bool InputEventsModel::accepted(const QmlProfilerDataModel::QmlEventTypeData &event) const { - return AbstractTimelineModel::accepted(event) && + return QmlProfilerTimelineModel::accepted(event) && (event.detailType == QmlDebug::Mouse || event.detailType == QmlDebug::Key); } diff --git a/plugins/qmlprofilerextension/inputeventsmodel.h b/plugins/qmlprofilerextension/inputeventsmodel.h index a06c4995a5..43a9dc4498 100644 --- a/plugins/qmlprofilerextension/inputeventsmodel.h +++ b/plugins/qmlprofilerextension/inputeventsmodel.h @@ -19,30 +19,34 @@ #ifndef INPUTEVENTSMODEL_H #define INPUTEVENTSMODEL_H -#include "qmlprofiler/abstracttimelinemodel.h" +#include "qmlprofiler/qmlprofilertimelinemodel.h" namespace QmlProfilerExtension { namespace Internal { -class InputEventsModel : public QmlProfiler::AbstractTimelineModel +class InputEventsModel : public QmlProfiler::QmlProfilerTimelineModel { Q_OBJECT - class InputEventsModelPrivate; - Q_DECLARE_PRIVATE(InputEventsModel) protected: bool accepted(const QmlProfiler::QmlProfilerDataModel::QmlEventTypeData &event) const; public: - InputEventsModel(QObject *parent = 0); - quint64 features() const; + InputEventsModel(QmlProfiler::QmlProfilerModelManager *manager, QObject *parent = 0); - int selectionId(int index) const; + int typeId(int index) const; QColor color(int index) const; QVariantList labels() const; QVariantMap details(int index) const; - int row(int index) const; + int expandedRow(int index) const; + int collapsedRow(int index) const; void loadData(); + void clear(); + +private: + int m_keyTypeId; + int m_mouseTypeId; + }; } diff --git a/plugins/qmlprofilerextension/memoryusagemodel.cpp b/plugins/qmlprofilerextension/memoryusagemodel.cpp index a32d27f6a6..4510ed59c1 100644 --- a/plugins/qmlprofilerextension/memoryusagemodel.cpp +++ b/plugins/qmlprofilerextension/memoryusagemodel.cpp @@ -19,7 +19,6 @@ #include "memoryusagemodel.h" #include "qmldebug/qmlprofilereventtypes.h" #include "qmlprofiler/qmlprofilermodelmanager.h" -#include "qmlprofiler/abstracttimelinemodel_p.h" #include <QStack> @@ -28,53 +27,35 @@ namespace Internal { using namespace QmlProfiler; -class MemoryUsageModel::MemoryUsageModelPrivate : public AbstractTimelineModelPrivate +MemoryUsageModel::MemoryUsageModel(QmlProfilerModelManager *manager, QObject *parent) : + QmlProfilerTimelineModel(manager, + tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileMemory)), + QmlDebug::MemoryAllocation, QmlDebug::MaximumRangeType, parent) { -public: - static QString memoryTypeName(int type); - - QVector<MemoryAllocation> data; - qint64 maxSize; -private: - Q_DECLARE_PUBLIC(MemoryUsageModel) -}; - -MemoryUsageModel::MemoryUsageModel(QObject *parent) - : AbstractTimelineModel(new MemoryUsageModelPrivate(), - tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileMemory)), - QmlDebug::MemoryAllocation, QmlDebug::MaximumRangeType, parent) -{ - Q_D(MemoryUsageModel); - d->maxSize = 1; + m_maxSize = 1; + announceFeatures((1 << QmlDebug::ProfileMemory) | QmlDebug::Constants::QML_JS_RANGE_FEATURES); } -quint64 MemoryUsageModel::features() const +int MemoryUsageModel::rowMaxValue(int rowNumber) const { - // Will listen to all range events, too, to determine context. - return (1 << QmlDebug::ProfileMemory) | QmlDebug::Constants::QML_JS_RANGE_FEATURES; + Q_UNUSED(rowNumber); + return m_maxSize; } -int MemoryUsageModel::rowMaxValue(int rowNumber) const +int MemoryUsageModel::expandedRow(int index) const { - Q_D(const MemoryUsageModel); - Q_UNUSED(rowNumber); - return d->maxSize; + int type = selectionId(index); + return (type == QmlDebug::HeapPage || type == QmlDebug::LargeItem) ? 1 : 2; } -int MemoryUsageModel::row(int index) const +int MemoryUsageModel::collapsedRow(int index) const { - Q_D(const MemoryUsageModel); - QmlDebug::MemoryType type = d->data[index].type; - if (type == QmlDebug::HeapPage || type == QmlDebug::LargeItem) - return 1; - else - return 2; + return expandedRow(index); } -int MemoryUsageModel::selectionId(int index) const +int MemoryUsageModel::typeId(int index) const { - Q_D(const MemoryUsageModel); - return d->data[index].type; + return m_data[index].typeId; } QColor MemoryUsageModel::color(int index) const @@ -84,8 +65,7 @@ QColor MemoryUsageModel::color(int index) const float MemoryUsageModel::relativeHeight(int index) const { - Q_D(const MemoryUsageModel); - return qMin(1.0f, (float)d->data[index].size / (float)d->maxSize); + return qMin(1.0f, (float)m_data[index].size / (float)m_maxSize); } QVariantMap MemoryUsageModel::location(int index) const @@ -94,13 +74,12 @@ QVariantMap MemoryUsageModel::location(int index) const static const QLatin1String line("line"); static const QLatin1String column("column"); - Q_D(const MemoryUsageModel); QVariantMap result; - int originType = d->data[index].originTypeIndex; + int originType = m_data[index].originTypeIndex; if (originType > -1) { const QmlDebug::QmlEventLocation &location = - d->modelManager->qmlModel()->getEventTypes().at(originType).location; + modelManager()->qmlModel()->getEventTypes().at(originType).location; result.insert(file, location.filename); result.insert(line, location.line); @@ -112,36 +91,25 @@ QVariantMap MemoryUsageModel::location(int index) const QVariantList MemoryUsageModel::labels() const { - Q_D(const MemoryUsageModel); QVariantList result; - if (d->expanded && !d->hidden && !isEmpty()) { - { - QVariantMap element; - element.insert(QLatin1String("description"), QVariant(tr("Memory Allocation"))); - - element.insert(QLatin1String("id"), QVariant(QmlDebug::HeapPage)); - result << element; - } + QVariantMap element; + element.insert(QLatin1String("description"), QVariant(tr("Memory Allocation"))); + element.insert(QLatin1String("id"), QVariant(QmlDebug::HeapPage)); + result << element; - { - QVariantMap element; - element.insert(QLatin1String("description"), QVariant(tr("Memory Usage"))); - - element.insert(QLatin1String("id"), QVariant(QmlDebug::SmallItem)); - result << element; - } - } + element.clear(); + element.insert(QLatin1String("description"), QVariant(tr("Memory Usage"))); + element.insert(QLatin1String("id"), QVariant(QmlDebug::SmallItem)); + result << element; return result; } QVariantMap MemoryUsageModel::details(int index) const { - Q_D(const MemoryUsageModel); - QVariantMap result; - const MemoryAllocation *ev = &d->data[index]; + const MemoryAllocation *ev = &m_data[index]; if (ev->allocated >= -ev->deallocated) result.insert(QLatin1String("displayName"), tr("Memory Allocated")); @@ -157,11 +125,11 @@ QVariantMap MemoryUsageModel::details(int index) const result.insert(tr("Deallocated"), QString::fromLatin1("%1 bytes").arg(-ev->deallocated)); result.insert(tr("Deallocations"), QString::number(ev->deallocations)); } - result.insert(tr("Type"), QVariant(MemoryUsageModelPrivate::memoryTypeName(ev->type))); + result.insert(tr("Type"), QVariant(memoryTypeName(selectionId(index)))); if (ev->originTypeIndex != -1) { result.insert(tr("Location"), - d->modelManager->qmlModel()->getEventTypes().at(ev->originTypeIndex).displayName); + modelManager()->qmlModel()->getEventTypes().at(ev->originTypeIndex).displayName); } return result; } @@ -177,9 +145,8 @@ struct RangeStackFrame { void MemoryUsageModel::loadData() { - Q_D(MemoryUsageModel); clear(); - QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel(); + QmlProfilerDataModel *simpleModel = modelManager()->qmlModel(); if (simpleModel->isEmpty()) return; @@ -189,7 +156,6 @@ void MemoryUsageModel::loadData() int currentJSHeapIndex = -1; QStack<RangeStackFrame> rangeStack; - MemoryAllocation dummy; const QVector<QmlProfilerDataModel::QmlEventTypeData> &types = simpleModel->getEventTypes(); foreach (const QmlProfilerDataModel::QmlEventData &event, simpleModel->getEvents()) { @@ -205,74 +171,76 @@ void MemoryUsageModel::loadData() } if (type.detailType == QmlDebug::SmallItem || type.detailType == QmlDebug::LargeItem) { - MemoryAllocation &last = currentUsageIndex > -1 ? d->data[currentUsageIndex] : dummy; - if (!rangeStack.empty() && type.detailType == last.type && - last.originTypeIndex == rangeStack.top().originTypeIndex && - rangeStack.top().startTime < range(currentUsageIndex).start) { - last.update(event.numericData1); - currentUsage = last.size; + if (!rangeStack.empty() && currentUsageIndex > -1 && + type.detailType == selectionId(currentUsageIndex) && + m_data[currentUsageIndex].originTypeIndex == rangeStack.top().originTypeIndex && + rangeStack.top().startTime < startTime(currentUsageIndex)) { + m_data[currentUsageIndex].update(event.numericData1); + currentUsage = m_data[currentUsageIndex].size; } else { - MemoryAllocation allocation(QmlDebug::SmallItem, currentUsage, + MemoryAllocation allocation(event.typeIndex, currentUsage, rangeStack.empty() ? -1 : rangeStack.top().originTypeIndex); allocation.update(event.numericData1); currentUsage = allocation.size; if (currentUsageIndex != -1) { insertEnd(currentUsageIndex, - event.startTime - range(currentUsageIndex).start - 1); + event.startTime - startTime(currentUsageIndex) - 1); } - currentUsageIndex = insertStart(event.startTime, event.typeIndex); - d->data.insert(currentUsageIndex, allocation); + currentUsageIndex = insertStart(event.startTime, QmlDebug::SmallItem); + m_data.insert(currentUsageIndex, allocation); } } if (type.detailType == QmlDebug::HeapPage || type.detailType == QmlDebug::LargeItem) { - MemoryAllocation &last = currentJSHeapIndex > -1 ? d->data[currentJSHeapIndex] : dummy; - if (!rangeStack.empty() && type.detailType == last.type && - last.originTypeIndex == rangeStack.top().originTypeIndex && - rangeStack.top().startTime < range(currentJSHeapIndex).start) { - last.update(event.numericData1); - currentSize = last.size; + if (!rangeStack.empty() && currentJSHeapIndex > -1 && + type.detailType == selectionId(currentJSHeapIndex) && + m_data[currentJSHeapIndex].originTypeIndex == + rangeStack.top().originTypeIndex && + rangeStack.top().startTime < startTime(currentJSHeapIndex)) { + m_data[currentJSHeapIndex].update(event.numericData1); + currentSize = m_data[currentJSHeapIndex].size; } else { - MemoryAllocation allocation((QmlDebug::MemoryType)type.detailType, currentSize, + MemoryAllocation allocation(event.typeIndex, currentSize, rangeStack.empty() ? -1 : rangeStack.top().originTypeIndex); allocation.update(event.numericData1); currentSize = allocation.size; - if (currentSize > d->maxSize) - d->maxSize = currentSize; + if (currentSize > m_maxSize) + m_maxSize = currentSize; if (currentJSHeapIndex != -1) insertEnd(currentJSHeapIndex, - event.startTime - range(currentJSHeapIndex).start - 1); - currentJSHeapIndex = insertStart(event.startTime, event.typeIndex); - d->data.insert(currentJSHeapIndex, allocation); + event.startTime - startTime(currentJSHeapIndex) - 1); + currentJSHeapIndex = insertStart(event.startTime, type.detailType); + m_data.insert(currentJSHeapIndex, allocation); } } - d->modelManager->modelProxyCountUpdated(d->modelId, count(), - simpleModel->getEvents().count()); + updateProgress(count(), simpleModel->getEvents().count()); } if (currentJSHeapIndex != -1) - insertEnd(currentJSHeapIndex, traceEndTime() - range(currentJSHeapIndex).start - 1); + insertEnd(currentJSHeapIndex, modelManager()->traceTime()->endTime() - + startTime(currentJSHeapIndex) - 1); if (currentUsageIndex != -1) - insertEnd(currentUsageIndex, traceEndTime() - range(currentUsageIndex).start - 1); + insertEnd(currentUsageIndex, modelManager()->traceTime()->endTime() - + startTime(currentUsageIndex) - 1); computeNesting(); - d->expandedRowCount = d->collapsedRowCount = 3; - d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); + setExpandedRowCount(3); + setCollapsedRowCount(3); + updateProgress(1, 1); } void MemoryUsageModel::clear() { - Q_D(MemoryUsageModel); - d->data.clear(); - d->maxSize = 1; - AbstractTimelineModel::clear(); + m_data.clear(); + m_maxSize = 1; + QmlProfilerTimelineModel::clear(); } -QString MemoryUsageModel::MemoryUsageModelPrivate::memoryTypeName(int type) +QString MemoryUsageModel::memoryTypeName(int type) { switch (type) { case QmlDebug::HeapPage: return tr("Heap Allocation"); @@ -283,9 +251,9 @@ QString MemoryUsageModel::MemoryUsageModelPrivate::memoryTypeName(int type) } } -MemoryUsageModel::MemoryAllocation::MemoryAllocation(QmlDebug::MemoryType type, qint64 baseAmount, +MemoryUsageModel::MemoryAllocation::MemoryAllocation(int type, qint64 baseAmount, int originTypeIndex) : - type(type), size(baseAmount), allocated(0), deallocated(0), allocations(0), deallocations(0), + typeId(type), size(baseAmount), allocated(0), deallocated(0), allocations(0), deallocations(0), originTypeIndex(originTypeIndex) { } diff --git a/plugins/qmlprofilerextension/memoryusagemodel.h b/plugins/qmlprofilerextension/memoryusagemodel.h index 9a297d748e..acd8431673 100644 --- a/plugins/qmlprofilerextension/memoryusagemodel.h +++ b/plugins/qmlprofilerextension/memoryusagemodel.h @@ -19,8 +19,7 @@ #ifndef MEMORYUSAGEMODEL_H #define MEMORYUSAGEMODEL_H -#include "qmlprofiler/qmlprofilertimelinemodelproxy.h" -#include "qmlprofiler/abstracttimelinemodel.h" +#include "qmlprofiler/qmlprofilertimelinemodel.h" #include "qmlprofiler/qmlprofilerdatamodel.h" #include <QStringList> @@ -29,13 +28,13 @@ namespace QmlProfilerExtension { namespace Internal { -class MemoryUsageModel : public QmlProfiler::AbstractTimelineModel +class MemoryUsageModel : public QmlProfiler::QmlProfilerTimelineModel { Q_OBJECT public: struct MemoryAllocation { - QmlDebug::MemoryType type; + int typeId; qint64 size; qint64 allocated; qint64 deallocated; @@ -43,18 +42,17 @@ public: int deallocations; int originTypeIndex; - MemoryAllocation(QmlDebug::MemoryType type = QmlDebug::MaximumMemoryType, - qint64 baseAmount = 0, int originTypeIndex = -1); + MemoryAllocation(int typeId = -1, qint64 baseAmount = 0, int originTypeIndex = -1); void update(qint64 amount); }; - MemoryUsageModel(QObject *parent = 0); - quint64 features() const; + MemoryUsageModel(QmlProfiler::QmlProfilerModelManager *manager, QObject *parent = 0); int rowMaxValue(int rowNumber) const; - int row(int index) const; - int selectionId(int index) const; + int expandedRow(int index) const; + int collapsedRow(int index) const; + int typeId(int index) const; QColor color(int index) const; float relativeHeight(int index) const; @@ -68,8 +66,10 @@ protected: void clear(); private: - class MemoryUsageModelPrivate; - Q_DECLARE_PRIVATE(MemoryUsageModel) + static QString memoryTypeName(int type); + + QVector<MemoryAllocation> m_data; + qint64 m_maxSize; }; } // namespace Internal diff --git a/plugins/qmlprofilerextension/pixmapcachemodel.cpp b/plugins/qmlprofilerextension/pixmapcachemodel.cpp index 597804b4d4..f6e998596a 100644 --- a/plugins/qmlprofilerextension/pixmapcachemodel.cpp +++ b/plugins/qmlprofilerextension/pixmapcachemodel.cpp @@ -19,118 +19,57 @@ #include "pixmapcachemodel.h" #include "qmldebug/qmlprofilereventtypes.h" #include "qmlprofiler/qmlprofilermodelmanager.h" -#include "qmlprofiler/abstracttimelinemodel_p.h" - -#include <QDebug> -#include <QSize> namespace QmlProfilerExtension { namespace Internal { using namespace QmlProfiler; -enum CacheState { - Uncached, // After loading started (or some other proof of existence) or after uncaching - ToBeCached, // After determining the pixmap is to be cached but before knowing its size - Cached, // After caching a pixmap or determining the size of a ToBeCached pixmap - Uncacheable, // If loading failed without ToBeCached or after a corrupt pixmap has been uncached - Corrupt // If after ToBeCached we learn that loading failed -}; - -enum LoadState { - Initial, - Loading, - Finished, - Error -}; - -struct PixmapState { - PixmapState(int width, int height, CacheState cache = Uncached) : - size(width, height), started(-1), loadState(Initial), cacheState(cache) {} - PixmapState(CacheState cache = Uncached) : started(-1), loadState(Initial), cacheState(cache) {} - QSize size; - int started; - LoadState loadState; - CacheState cacheState; -}; - -struct Pixmap { - Pixmap() {} - Pixmap(const QString &url) : url(url), sizes(1) {} - QString url; - QVector<PixmapState> sizes; -}; - -class PixmapCacheModel::PixmapCacheModelPrivate : public AbstractTimelineModelPrivate -{ -public: - void computeMaxCacheSize(); - void resizeUnfinishedLoads(); - void flattenLoads(); - int updateCacheCount(int lastCacheSizeEvent, qint64 startTime, qint64 pixSize, - PixmapCacheEvent &newEvent, int typeId); - - QVector<PixmapCacheEvent> data; - QVector<Pixmap> pixmaps; - - qint64 maxCacheSize; -private: - Q_DECLARE_PUBLIC(PixmapCacheModel) -}; - -PixmapCacheModel::PixmapCacheModel(QObject *parent) - : AbstractTimelineModel(new PixmapCacheModelPrivate(), - tr(QmlProfilerModelManager::featureName(QmlDebug::ProfilePixmapCache)), - QmlDebug::PixmapCacheEvent, QmlDebug::MaximumRangeType, parent) -{ - Q_D(PixmapCacheModel); - d->maxCacheSize = 1; -} - -quint64 PixmapCacheModel::features() const +PixmapCacheModel::PixmapCacheModel(QmlProfilerModelManager *manager, QObject *parent) : + QmlProfilerTimelineModel(manager, + tr(QmlProfilerModelManager::featureName(QmlDebug::ProfilePixmapCache)), + QmlDebug::PixmapCacheEvent, QmlDebug::MaximumRangeType, parent) { - return 1 << QmlDebug::ProfilePixmapCache; + m_maxCacheSize = 1; + announceFeatures(1 << QmlDebug::ProfilePixmapCache); } int PixmapCacheModel::rowMaxValue(int rowNumber) const { - Q_D(const PixmapCacheModel); if (rowNumber == 1) { - return d->maxCacheSize; + return m_maxCacheSize; } else { - return AbstractTimelineModel::rowMaxValue(rowNumber); + return QmlProfilerTimelineModel::rowMaxValue(rowNumber); } } -int PixmapCacheModel::row(int index) const +int PixmapCacheModel::expandedRow(int index) const { - Q_D(const PixmapCacheModel); - if (d->expanded) - return selectionId(index) + 1; - return d->data[index].rowNumberCollapsed; + return selectionId(index) + 1; } -int PixmapCacheModel::selectionId(int index) const +int PixmapCacheModel::collapsedRow(int index) const { - Q_D(const PixmapCacheModel); - return d->data[index].pixmapEventType == PixmapCacheCountChanged ? - 0 : d->data[index].urlIndex + 1; + return m_data[index].rowNumberCollapsed; +} + +int PixmapCacheModel::typeId(int index) const +{ + return m_data[index].typeId; } QColor PixmapCacheModel::color(int index) const { - Q_D(const PixmapCacheModel); - if (d->data[index].pixmapEventType == PixmapCacheCountChanged) - return colorByHue(PixmapCacheCountHue); + if (m_data[index].pixmapEventType == PixmapCacheCountChanged) + return colorByHue(s_pixmapCacheCountHue); return colorBySelectionId(index); } float PixmapCacheModel::relativeHeight(int index) const { - Q_D(const PixmapCacheModel); - if (d->data[index].pixmapEventType == PixmapCacheCountChanged) - return (float)d->data[index].cacheSize / (float)d->maxCacheSize; + if (m_data[index].pixmapEventType == PixmapCacheCountChanged) + return (float)m_data[index].cacheSize / (float)m_maxCacheSize; else return 1.0f; } @@ -145,29 +84,24 @@ QString getFilenameOnly(QString absUrl) QVariantList PixmapCacheModel::labels() const { - Q_D(const PixmapCacheModel); QVariantList result; - if (d->expanded && !d->hidden && !isEmpty()) { - { - // Cache Size - QVariantMap element; - element.insert(QLatin1String("description"), QVariant(QLatin1String("Cache Size"))); + // Cache Size + QVariantMap element; + element.insert(QLatin1String("description"), QVariant(QLatin1String("Cache Size"))); - element.insert(QLatin1String("id"), QVariant(0)); - result << element; - } + element.insert(QLatin1String("id"), QVariant(0)); + result << element; - for (int i=0; i < d->pixmaps.count(); i++) { - // Loading - QVariantMap element; - element.insert(QLatin1String("displayName"), d->pixmaps[i].url); - element.insert(QLatin1String("description"), - QVariant(getFilenameOnly(d->pixmaps[i].url))); + for (int i=0; i < m_pixmaps.count(); i++) { + // Loading + QVariantMap element; + element.insert(QLatin1String("displayName"), m_pixmaps[i].url); + element.insert(QLatin1String("description"), + QVariant(getFilenameOnly(m_pixmaps[i].url))); - element.insert(QLatin1String("id"), QVariant(i+1)); - result << element; - } + element.insert(QLatin1String("id"), QVariant(i+1)); + result << element; } return result; @@ -175,27 +109,26 @@ QVariantList PixmapCacheModel::labels() const QVariantMap PixmapCacheModel::details(int index) const { - Q_D(const PixmapCacheModel); QVariantMap result; - const PixmapCacheEvent *ev = &d->data[index]; + const PixmapCacheEvent *ev = &m_data[index]; if (ev->pixmapEventType == PixmapCacheCountChanged) { result.insert(QLatin1String("displayName"), tr("Image Cached")); } else { if (ev->pixmapEventType == PixmapLoadingStarted) { result.insert(QLatin1String("displayName"), tr("Image Loaded")); - if (d->pixmaps[ev->urlIndex].sizes[ev->sizeIndex].loadState != Finished) + if (m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].loadState != Finished) result.insert(tr("Result"), tr("Load Error")); } - result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(range(index).duration)); + result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(duration(index))); } result.insert(tr("Cache Size"), QString::fromLatin1("%1 px").arg(ev->cacheSize)); - result.insert(tr("File"), getFilenameOnly(d->pixmaps[ev->urlIndex].url)); + result.insert(tr("File"), getFilenameOnly(m_pixmaps[ev->urlIndex].url)); result.insert(tr("Width"), QString::fromLatin1("%1 px") - .arg(d->pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.width())); + .arg(m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.width())); result.insert(tr("Height"), QString::fromLatin1("%1 px") - .arg(d->pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.height())); + .arg(m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].size.height())); return result; } @@ -231,9 +164,8 @@ QVariantMap PixmapCacheModel::details(int index) const void PixmapCacheModel::loadData() { - Q_D(PixmapCacheModel); clear(); - QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel(); + QmlProfilerDataModel *simpleModel = modelManager()->qmlModel(); if (simpleModel->isEmpty()) return; @@ -247,24 +179,24 @@ void PixmapCacheModel::loadData() continue; PixmapCacheEvent newEvent; - newEvent.pixmapEventType = type.detailType; - qint64 startTime = event.startTime; + newEvent.pixmapEventType = static_cast<PixmapEventType>(type.detailType); + qint64 pixmapStartTime = event.startTime; newEvent.urlIndex = -1; - for (QVector<Pixmap>::const_iterator it(d->pixmaps.cend()); it != d->pixmaps.cbegin();) { + for (QVector<Pixmap>::const_iterator it(m_pixmaps.cend()); it != m_pixmaps.cbegin();) { if ((--it)->url == type.location.filename) { - newEvent.urlIndex = it - d->pixmaps.cbegin(); + newEvent.urlIndex = it - m_pixmaps.cbegin(); break; } } newEvent.sizeIndex = -1; if (newEvent.urlIndex == -1) { - newEvent.urlIndex = d->pixmaps.count(); - d->pixmaps << Pixmap(type.location.filename); + newEvent.urlIndex = m_pixmaps.count(); + m_pixmaps << Pixmap(type.location.filename); } - Pixmap &pixmap = d->pixmaps[newEvent.urlIndex]; + Pixmap &pixmap = m_pixmaps[newEvent.urlIndex]; switch (newEvent.pixmapEventType) { case PixmapSizeKnown: {// pixmap size // Look for pixmaps for which we don't know the size, yet and which have actually been @@ -290,7 +222,7 @@ void PixmapCacheModel::loadData() PixmapState &state = pixmap.sizes[newEvent.sizeIndex]; if (state.cacheState == ToBeCached) { - lastCacheSizeEvent = d->updateCacheCount(lastCacheSizeEvent, startTime, + lastCacheSizeEvent = updateCacheCount(lastCacheSizeEvent, pixmapStartTime, state.size.width() * state.size.height(), newEvent, event.typeIndex); state.cacheState = Cached; @@ -298,7 +230,7 @@ void PixmapCacheModel::loadData() break; } case PixmapCacheCountChanged: {// Cache Size Changed Event - startTime = event.startTime + 1; // delay 1 ns for proper sorting + pixmapStartTime = event.startTime + 1; // delay 1 ns for proper sorting bool uncache = cumulatedCount > event.numericData3; cumulatedCount = event.numericData3; @@ -351,8 +283,8 @@ void PixmapCacheModel::loadData() pixmap.sizes << PixmapState(uncache ? Uncached : ToBeCached); } - lastCacheSizeEvent = d->updateCacheCount(lastCacheSizeEvent, startTime, pixSize, - newEvent, event.typeIndex); + lastCacheSizeEvent = updateCacheCount(lastCacheSizeEvent, pixmapStartTime, pixSize, + newEvent, event.typeIndex); break; } case PixmapLoadingStarted: { // Load @@ -372,8 +304,9 @@ void PixmapCacheModel::loadData() PixmapState &state = pixmap.sizes[newEvent.sizeIndex]; state.loadState = Loading; - state.started = insertStart(startTime, event.typeIndex); - d->data.insert(state.started, newEvent); + newEvent.typeId = event.typeIndex; + state.started = insertStart(pixmapStartTime, newEvent.urlIndex + 1); + m_data.insert(state.started, newEvent); break; } case PixmapLoadingFinished: @@ -416,16 +349,18 @@ void PixmapCacheModel::loadData() // If the pixmap loading wasn't started, start it at traceStartTime() if (state.loadState == Initial) { newEvent.pixmapEventType = PixmapLoadingStarted; - state.started = insert(traceStartTime(), startTime - traceStartTime(), - event.typeIndex); - d->data.insert(state.started, newEvent); + newEvent.typeId = event.typeIndex; + qint64 traceStart = modelManager()->traceTime()->startTime(); + state.started = insert(traceStart, pixmapStartTime - traceStart, + newEvent.urlIndex + 1); + m_data.insert(state.started, newEvent); // All other indices are wrong now as we've prepended. Fix them ... if (lastCacheSizeEvent >= state.started) ++lastCacheSizeEvent; - for (int pixmapIndex = 0; pixmapIndex < d->pixmaps.count(); ++pixmapIndex) { - Pixmap &brokenPixmap = d->pixmaps[pixmapIndex]; + for (int pixmapIndex = 0; pixmapIndex < m_pixmaps.count(); ++pixmapIndex) { + Pixmap &brokenPixmap = m_pixmaps[pixmapIndex]; for (int sizeIndex = 0; sizeIndex < brokenPixmap.sizes.count(); ++sizeIndex) { PixmapState &brokenSize = brokenPixmap.sizes[sizeIndex]; if ((pixmapIndex != newEvent.urlIndex || sizeIndex != newEvent.sizeIndex) && @@ -436,7 +371,7 @@ void PixmapCacheModel::loadData() } } - insertEnd(state.started, startTime - range(state.started).start); + insertEnd(state.started, pixmapStartTime - startTime(state.started)); if (newEvent.pixmapEventType == PixmapLoadingError) { state.loadState = Error; switch (state.cacheState) { @@ -461,73 +396,69 @@ void PixmapCacheModel::loadData() break; } - d->modelManager->modelProxyCountUpdated(d->modelId, count(), - 2 * simpleModel->getEvents().count()); + updateProgress(count(), 2 * simpleModel->getEvents().count()); } if (lastCacheSizeEvent != -1) - insertEnd(lastCacheSizeEvent, traceEndTime() - range(lastCacheSizeEvent).start); + insertEnd(lastCacheSizeEvent, modelManager()->traceTime()->endTime() - + startTime(lastCacheSizeEvent)); - d->resizeUnfinishedLoads(); + resizeUnfinishedLoads(); - d->computeMaxCacheSize(); - d->flattenLoads(); + computeMaxCacheSize(); + flattenLoads(); computeNesting(); - d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); + updateProgress(1, 1); } void PixmapCacheModel::clear() { - Q_D(PixmapCacheModel); - d->pixmaps.clear(); - d->maxCacheSize = 1; - d->data.clear(); - AbstractTimelineModel::clear(); + m_pixmaps.clear(); + m_maxCacheSize = 1; + m_data.clear(); + QmlProfilerTimelineModel::clear(); } -void PixmapCacheModel::PixmapCacheModelPrivate::computeMaxCacheSize() +void PixmapCacheModel::computeMaxCacheSize() { - maxCacheSize = 1; - foreach (const PixmapCacheModel::PixmapCacheEvent &event, data) { + m_maxCacheSize = 1; + foreach (const PixmapCacheModel::PixmapCacheEvent &event, m_data) { if (event.pixmapEventType == PixmapCacheModel::PixmapCacheCountChanged) { - if (event.cacheSize > maxCacheSize) - maxCacheSize = event.cacheSize; + if (event.cacheSize > m_maxCacheSize) + m_maxCacheSize = event.cacheSize; } } } -void PixmapCacheModel::PixmapCacheModelPrivate::resizeUnfinishedLoads() +void PixmapCacheModel::resizeUnfinishedLoads() { - Q_Q(PixmapCacheModel); // all the "load start" events with duration 0 continue till the end of the trace - for (int i = 0; i < q->count(); i++) { - if (data[i].pixmapEventType == PixmapCacheModel::PixmapLoadingStarted && - q->range(i).duration == 0) { - q->insertEnd(i, q->traceEndTime() - q->range(i).start); + for (int i = 0; i < count(); i++) { + if (m_data[i].pixmapEventType == PixmapCacheModel::PixmapLoadingStarted && + duration(i) == 0) { + insertEnd(i, modelManager()->traceTime()->endTime() - startTime(i)); } } } -void PixmapCacheModel::PixmapCacheModelPrivate::flattenLoads() +void PixmapCacheModel::flattenLoads() { - Q_Q(PixmapCacheModel); - collapsedRowCount = 0; + int collapsedRowCount = 0; // computes "compressed row" QVector <qint64> eventEndTimes; - for (int i = 0; i < q->count(); i++) { - PixmapCacheModel::PixmapCacheEvent &event = data[i]; - const Range &start = q->range(i); + for (int i = 0; i < count(); i++) { + PixmapCacheModel::PixmapCacheEvent &event = m_data[i]; if (event.pixmapEventType == PixmapCacheModel::PixmapLoadingStarted) { event.rowNumberCollapsed = 0; while (eventEndTimes.count() > event.rowNumberCollapsed && - eventEndTimes[event.rowNumberCollapsed] > start.start) + eventEndTimes[event.rowNumberCollapsed] > startTime(i)) event.rowNumberCollapsed++; if (eventEndTimes.count() == event.rowNumberCollapsed) eventEndTimes << 0; // increase stack length, proper value added below - eventEndTimes[event.rowNumberCollapsed] = start.start + start.duration; + eventEndTimes[event.rowNumberCollapsed] = endTime(i); // readjust to account for category empty row and bargraph event.rowNumberCollapsed += 2; @@ -537,26 +468,26 @@ void PixmapCacheModel::PixmapCacheModelPrivate::flattenLoads() } // Starting from 0, count is maxIndex+1 - collapsedRowCount++; - expandedRowCount = pixmaps.count() + 2; + setCollapsedRowCount(collapsedRowCount + 1); + setExpandedRowCount(m_pixmaps.count() + 2); } -int PixmapCacheModel::PixmapCacheModelPrivate::updateCacheCount(int lastCacheSizeEvent, - qint64 startTime, qint64 pixSize, PixmapCacheEvent &newEvent, int typeId) +int PixmapCacheModel::updateCacheCount(int lastCacheSizeEvent, + qint64 pixmapStartTime, qint64 pixSize, PixmapCacheEvent &newEvent, int typeId) { - Q_Q(PixmapCacheModel); newEvent.pixmapEventType = PixmapCacheCountChanged; newEvent.rowNumberCollapsed = 1; qint64 prevSize = 0; if (lastCacheSizeEvent != -1) { - prevSize = data[lastCacheSizeEvent].cacheSize; - q->insertEnd(lastCacheSizeEvent, startTime - q->range(lastCacheSizeEvent).start); + prevSize = m_data[lastCacheSizeEvent].cacheSize; + insertEnd(lastCacheSizeEvent, pixmapStartTime - startTime(lastCacheSizeEvent)); } newEvent.cacheSize = prevSize + pixSize; - int index = q->insertStart(startTime, typeId); - data.insert(index, newEvent); + newEvent.typeId = typeId; + int index = insertStart(pixmapStartTime, 0); + m_data.insert(index, newEvent); return index; } diff --git a/plugins/qmlprofilerextension/pixmapcachemodel.h b/plugins/qmlprofilerextension/pixmapcachemodel.h index 77d7155330..13dc412da1 100644 --- a/plugins/qmlprofilerextension/pixmapcachemodel.h +++ b/plugins/qmlprofilerextension/pixmapcachemodel.h @@ -19,27 +19,50 @@ #ifndef PIXMAPCACHEMODEL_H #define PIXMAPCACHEMODEL_H -#include "qmlprofiler/qmlprofilertimelinemodelproxy.h" -#include "qmlprofiler/abstracttimelinemodel.h" +#include "qmlprofiler/qmlprofilertimelinemodel.h" #include "qmlprofiler/qmlprofilerdatamodel.h" #include <QStringList> #include <QColor> +#include <QSize> namespace QmlProfilerExtension { namespace Internal { -class PixmapCacheModel : public QmlProfiler::AbstractTimelineModel +class PixmapCacheModel : public QmlProfiler::QmlProfilerTimelineModel { Q_OBJECT public: + enum CacheState { + Uncached, // After loading started (or some other proof of existence) or after uncaching + ToBeCached, // After determining the pixmap is to be cached but before knowing its size + Cached, // After caching a pixmap or determining the size of a ToBeCached pixmap + Uncacheable, // If loading failed without ToBeCached or after a corrupt pixmap has been uncached + Corrupt // If after ToBeCached we learn that loading failed + }; - struct PixmapCacheEvent { - int pixmapEventType; - int urlIndex; - int sizeIndex; - int rowNumberCollapsed; - qint64 cacheSize; + enum LoadState { + Initial, + Loading, + Finished, + Error + }; + + struct PixmapState { + PixmapState(int width, int height, CacheState cache = Uncached) : + size(width, height), started(-1), loadState(Initial), cacheState(cache) {} + PixmapState(CacheState cache = Uncached) : started(-1), loadState(Initial), cacheState(cache) {} + QSize size; + int started; + LoadState loadState; + CacheState cacheState; + }; + + struct Pixmap { + Pixmap() {} + Pixmap(const QString &url) : url(url), sizes(1) {} + QString url; + QVector<PixmapState> sizes; }; enum PixmapEventType { @@ -53,13 +76,22 @@ public: MaximumPixmapEventType }; - PixmapCacheModel(QObject *parent = 0); - quint64 features() const; + struct PixmapCacheEvent { + int typeId; + PixmapEventType pixmapEventType; + int urlIndex; + int sizeIndex; + int rowNumberCollapsed; + qint64 cacheSize; + }; + + PixmapCacheModel(QmlProfiler::QmlProfilerModelManager *manager, QObject *parent = 0); int rowMaxValue(int rowNumber) const; - int row(int index) const; - int selectionId(int index) const; + int expandedRow(int index) const; + int collapsedRow(int index) const; + int typeId(int index) const; QColor color(int index) const; float relativeHeight(int index) const; @@ -72,10 +104,17 @@ protected: void clear(); private: - static const int PixmapCacheCountHue = 240; + void computeMaxCacheSize(); + void resizeUnfinishedLoads(); + void flattenLoads(); + int updateCacheCount(int lastCacheSizeEvent, qint64 startTime, qint64 pixSize, + PixmapCacheEvent &newEvent, int typeId); + + QVector<PixmapCacheEvent> m_data; + QVector<Pixmap> m_pixmaps; + qint64 m_maxCacheSize; - class PixmapCacheModelPrivate; - Q_DECLARE_PRIVATE(PixmapCacheModel) + static const int s_pixmapCacheCountHue = 240; }; } // namespace Internal diff --git a/plugins/qmlprofilerextension/qmlprofilerextension.qbs b/plugins/qmlprofilerextension/qmlprofilerextension.qbs index 337461372e..d95e4fcb81 100644 --- a/plugins/qmlprofilerextension/qmlprofilerextension.qbs +++ b/plugins/qmlprofilerextension/qmlprofilerextension.qbs @@ -6,6 +6,7 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "LicenseChecker" } Depends { name: "QmlProfiler" } + Depends { name: "Timeline" } Depends { name: "Qt.widgets" } diff --git a/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp b/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp index fbb1752923..93923332f7 100644 --- a/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp +++ b/plugins/qmlprofilerextension/qmlprofilerextensionplugin.cpp @@ -18,6 +18,7 @@ #include "qmlprofilerextensionplugin.h" #include "qmlprofilerextensionconstants.h" +#include <qmlprofiler/qmlprofilertimelinemodelfactory.h> #include <licensechecker/licensecheckerplugin.h> @@ -45,6 +46,21 @@ using namespace QmlProfilerExtension::Internal; +class ModelFactory : public QmlProfiler::QmlProfilerTimelineModelFactory { + Q_OBJECT +public: + QList<QmlProfiler::QmlProfilerTimelineModel *> create( + QmlProfiler::QmlProfilerModelManager *manager) + { + QList<QmlProfiler::QmlProfilerTimelineModel *> models; + models << new PixmapCacheModel(manager, this) + << new SceneGraphTimelineModel(manager, this) + << new MemoryUsageModel(manager, this) + << new InputEventsModel(manager, this); + return models; + } +}; + QmlProfilerExtensionPlugin::QmlProfilerExtensionPlugin() { // Create your members @@ -72,12 +88,8 @@ bool QmlProfilerExtensionPlugin::initialize(const QStringList &arguments, QStrin = ExtensionSystem::PluginManager::getObject<LicenseChecker::LicenseCheckerPlugin>(); if (licenseChecker && licenseChecker->hasValidLicense()) { - if (licenseChecker->enterpriseFeatures()) { - addAutoReleasedObject(new PixmapCacheModel); - addAutoReleasedObject(new SceneGraphTimelineModel); - addAutoReleasedObject(new MemoryUsageModel); - addAutoReleasedObject(new InputEventsModel); - } + if (licenseChecker->enterpriseFeatures()) + addAutoReleasedObject(new ModelFactory); } else { qWarning() << "Invalid license, disabling QML Profiler Enterprise features"; } @@ -107,3 +119,4 @@ void QmlProfilerExtensionPlugin::triggerAction() tr("This is an action from QmlProfilerExtension.")); } +#include "qmlprofilerextensionplugin.moc" diff --git a/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp b/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp index 2250ce7cd3..7e0bd79f5e 100644 --- a/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp +++ b/plugins/qmlprofilerextension/scenegraphtimelinemodel.cpp @@ -19,7 +19,6 @@ #include "scenegraphtimelinemodel.h" #include "qmldebug/qmlprofilereventtypes.h" #include "qmlprofiler/qmlprofilermodelmanager.h" -#include "qmlprofiler/abstracttimelinemodel_p.h" #include <QCoreApplication> #include <QDebug> @@ -66,83 +65,31 @@ enum SceneGraphCategoryType { MaximumSceneGraphCategoryType }; -enum SceneGraphStage { - MinimumSceneGraphStage = 0, - Polish = MinimumSceneGraphStage, - Wait, - GUIThreadSync, - Animations, - MaximumGUIThreadStage, - - RenderThreadSync = MaximumGUIThreadStage, - Render, - Swap, - MaximumRenderThreadStage, - - RenderPreprocess = MaximumRenderThreadStage, - RenderUpdate, - RenderBind, - RenderRender, - MaximumRenderStage, - - Material = MaximumRenderStage, - MaximumMaterialStage, - - GlyphRender = MaximumMaterialStage, - GlyphStore, - MaximumGlyphStage, - - TextureBind = MaximumGlyphStage, - TextureConvert, - TextureSwizzle, - TextureUpload, - TextureMipmap, - TextureDeletion, - MaximumTextureStage, - - MaximumSceneGraphStage = MaximumTextureStage -}; - - -Q_STATIC_ASSERT(sizeof(StageLabels) == MaximumSceneGraphStage * sizeof(const char *)); - -class SceneGraphTimelineModel::SceneGraphTimelineModelPrivate : - public AbstractTimelineModel::AbstractTimelineModelPrivate -{ -public: - void flattenLoads(); +Q_STATIC_ASSERT(sizeof(StageLabels) == + SceneGraphTimelineModel::MaximumSceneGraphStage * sizeof(const char *)); - QVector<SceneGraphEvent> data; - qint64 insert(qint64 start, qint64 duration, int typeIndex, SceneGraphStage stage, - int glyphCount = -1); - static const char *threadLabel(SceneGraphStage stage); - -private: - Q_DECLARE_PUBLIC(SceneGraphTimelineModel) -}; - -SceneGraphTimelineModel::SceneGraphTimelineModel(QObject *parent) - : AbstractTimelineModel(new SceneGraphTimelineModelPrivate, - tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileSceneGraph)), - QmlDebug::SceneGraphFrame, QmlDebug::MaximumRangeType, parent) +SceneGraphTimelineModel::SceneGraphTimelineModel(QmlProfilerModelManager *manager, + QObject *parent) : + QmlProfilerTimelineModel(manager, + tr(QmlProfilerModelManager::featureName(QmlDebug::ProfileSceneGraph)), + QmlDebug::SceneGraphFrame, QmlDebug::MaximumRangeType, parent) { + announceFeatures(1 << QmlDebug::ProfileSceneGraph); } -quint64 SceneGraphTimelineModel::features() const +int SceneGraphTimelineModel::expandedRow(int index) const { - return 1 << QmlDebug::ProfileSceneGraph; + return selectionId(index) + 1; } -int SceneGraphTimelineModel::row(int index) const +int SceneGraphTimelineModel::collapsedRow(int index) const { - Q_D(const SceneGraphTimelineModel); - return expanded() ? (d->data[index].stage + 1) : d->data[index].rowNumberCollapsed; + return m_data[index].rowNumberCollapsed; } -int SceneGraphTimelineModel::selectionId(int index) const +int SceneGraphTimelineModel::typeId(int index) const { - Q_D(const SceneGraphTimelineModel); - return d->data[index].stage; + return m_data[index].typeId; } QColor SceneGraphTimelineModel::color(int index) const @@ -152,18 +99,15 @@ QColor SceneGraphTimelineModel::color(int index) const QVariantList SceneGraphTimelineModel::labels() const { - Q_D(const SceneGraphTimelineModel); QVariantList result; - if (d->expanded && !d->hidden && !isEmpty()) { - for (SceneGraphStage i = MinimumSceneGraphStage; i < MaximumSceneGraphStage; - i = static_cast<SceneGraphStage>(i + 1)) { - QVariantMap element; - element.insert(QLatin1String("displayName"), tr(d->threadLabel(i))); - element.insert(QLatin1String("description"), tr(StageLabels[i])); - element.insert(QLatin1String("id"), i); - result << element; - } + 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; @@ -171,25 +115,24 @@ QVariantList SceneGraphTimelineModel::labels() const QVariantMap SceneGraphTimelineModel::details(int index) const { - Q_D(const SceneGraphTimelineModel); QVariantMap result; - const SceneGraphEvent *ev = &d->data[index]; + 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))); - result.insert(QLatin1String("displayName"), - tr(d->threadLabel(static_cast<SceneGraphStage>(ev->stage)))); - result.insert(tr("Stage"), tr(StageLabels[ev->stage])); - result.insert(tr("Duration"), QmlProfilerBaseModel::formatTime(range(index).duration)); - if (ev->glyphCount >= 0) - result.insert(tr("Glyphs"), QString::number(ev->glyphCount)); + const int glyphCount = m_data[index].glyphCount; + if (glyphCount >= 0) + result.insert(tr("Glyphs"), QString::number(glyphCount)); return result; } void SceneGraphTimelineModel::loadData() { - Q_D(SceneGraphTimelineModel); clear(); - QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel(); + QmlProfilerDataModel *simpleModel = modelManager()->qmlModel(); if (simpleModel->isEmpty()) return; @@ -208,111 +151,108 @@ void SceneGraphTimelineModel::loadData() // parts of the breakdown are usually very short. qint64 startTime = event.startTime - event.numericData1 - event.numericData2 - event.numericData3 - event.numericData4; - startTime += d->insert(startTime, event.numericData1, event.typeIndex, - RenderPreprocess); - startTime += d->insert(startTime, event.numericData2, event.typeIndex, RenderUpdate); - startTime += d->insert(startTime, event.numericData3, event.typeIndex, RenderBind); - d->insert(startTime, event.numericData4, event.typeIndex, RenderRender); + 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 += d->insert(startTime, event.numericData2, event.typeIndex, GlyphRender, - event.numericData1); - d->insert(startTime, event.numericData3, event.typeIndex, GlyphStore, - event.numericData1); + startTime += insert(startTime, event.numericData2, event.typeIndex, GlyphRender, + event.numericData1); + insert(startTime, event.numericData3, event.typeIndex, GlyphStore, event.numericData1); break; } case QmlDebug::SceneGraphContextFrame: { - d->insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex, + 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 += d->insert(startTime, event.numericData1, event.typeIndex, + startTime += insert(startTime, event.numericData1, event.typeIndex, RenderThreadSync); - startTime += d->insert(startTime, event.numericData2, event.typeIndex, + startTime += insert(startTime, event.numericData2, event.typeIndex, Render); - d->insert(startTime, event.numericData3, event.typeIndex, Swap); + 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 += d->insert(startTime, event.numericData1, event.typeIndex, TextureBind); - startTime += d->insert(startTime, event.numericData2, event.typeIndex, TextureConvert); - startTime += d->insert(startTime, event.numericData3, event.typeIndex, TextureSwizzle); - startTime += d->insert(startTime, event.numericData4, event.typeIndex, TextureUpload); - d->insert(startTime, event.numericData5, event.typeIndex, TextureMipmap); + 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: { - d->insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex, - TextureDeletion); + 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 += d->insert(startTime, event.numericData1, event.typeIndex, Polish); - startTime += d->insert(startTime, event.numericData2, event.typeIndex, Wait); - startTime += d->insert(startTime, event.numericData3, event.typeIndex, GUIThreadSync); - d->insert(startTime, event.numericData4, event.typeIndex, Animations); + 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 - d->insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex, - Animations); + insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex, + Animations); break; } case QmlDebug::SceneGraphPolishFrame: { // GUI thread, separate polish stage - d->insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex, - Polish); + insert(event.startTime - event.numericData1, event.numericData1, event.typeIndex, + Polish); break; } default: break; } - d->modelManager->modelProxyCountUpdated(d->modelId, count(), simpleModel->getEvents().count()); + updateProgress(count(), simpleModel->getEvents().count()); } computeNesting(); - d->flattenLoads(); - d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); + flattenLoads(); + updateProgress(1, 1); } -void SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::flattenLoads() +void SceneGraphTimelineModel::flattenLoads() { - Q_Q(SceneGraphTimelineModel); - collapsedRowCount = 0; + int collapsedRowCount = 0; // computes "compressed row" QVector <qint64> eventEndTimes; - for (int i = 0; i < q->count(); i++) { - SceneGraphEvent &event = data[i]; - const Range &start = q->range(i); + 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 (event.stage < MaximumGUIThreadStage) + if (stage < MaximumGUIThreadStage) event.rowNumberCollapsed = SceneGraphGUIThread; - else if (event.stage < MaximumRenderThreadStage) + else if (stage < MaximumRenderThreadStage) event.rowNumberCollapsed = SceneGraphRenderThread; else event.rowNumberCollapsed = SceneGraphRenderThreadDetails; while (eventEndTimes.count() > event.rowNumberCollapsed && - eventEndTimes[event.rowNumberCollapsed] > start.start) + eventEndTimes[event.rowNumberCollapsed] > startTime(i)) ++event.rowNumberCollapsed; while (eventEndTimes.count() <= event.rowNumberCollapsed) eventEndTimes << 0; // increase stack length, proper value added below - eventEndTimes[event.rowNumberCollapsed] = start.start + start.duration; + eventEndTimes[event.rowNumberCollapsed] = endTime(i); // readjust to account for category empty row event.rowNumberCollapsed++; @@ -321,8 +261,8 @@ void SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::flattenLoads() } // Starting from 0, count is maxIndex+1 - collapsedRowCount++; - expandedRowCount = MaximumSceneGraphStage + 1; + setCollapsedRowCount(collapsedRowCount + 1); + setExpandedRowCount(MaximumSceneGraphStage + 1); } /*! @@ -330,19 +270,18 @@ void SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::flattenLoads() * \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::SceneGraphTimelineModelPrivate::insert(qint64 start, - qint64 duration, int typeIndex, SceneGraphStage stage, int glyphCount) +qint64 SceneGraphTimelineModel::insert(qint64 start, qint64 duration, int typeIndex, + SceneGraphStage stage, int glyphCount) { if (duration <= 0) return 0; - Q_Q(SceneGraphTimelineModel); - data.insert(q->insert(start, duration, typeIndex), SceneGraphEvent(stage, glyphCount)); + m_data.insert(QmlProfilerTimelineModel::insert(start, duration, stage), + SceneGraphEvent(typeIndex, glyphCount)); return duration; } -const char *SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::threadLabel( - SceneGraphStage stage) +const char *SceneGraphTimelineModel::threadLabel(SceneGraphStage stage) { if (stage < MaximumGUIThreadStage) return ThreadLabels[SceneGraphGUIThread]; @@ -355,14 +294,12 @@ const char *SceneGraphTimelineModel::SceneGraphTimelineModelPrivate::threadLabel void SceneGraphTimelineModel::clear() { - Q_D(SceneGraphTimelineModel); - d->collapsedRowCount = 1; - d->data.clear(); - AbstractTimelineModel::clear(); + m_data.clear(); + QmlProfilerTimelineModel::clear(); } -SceneGraphTimelineModel::SceneGraphEvent::SceneGraphEvent(int stage, int glyphCount) : - stage(stage), rowNumberCollapsed(-1), glyphCount(glyphCount) +SceneGraphTimelineModel::SceneGraphEvent::SceneGraphEvent(int typeId, int glyphCount) : + typeId(typeId), rowNumberCollapsed(-1), glyphCount(glyphCount) { } diff --git a/plugins/qmlprofilerextension/scenegraphtimelinemodel.h b/plugins/qmlprofilerextension/scenegraphtimelinemodel.h index bd3e5ad107..6225963993 100644 --- a/plugins/qmlprofilerextension/scenegraphtimelinemodel.h +++ b/plugins/qmlprofilerextension/scenegraphtimelinemodel.h @@ -19,7 +19,7 @@ #ifndef SCENEGRAPHTIMELINEMODEL_H #define SCENEGRAPHTIMELINEMODEL_H -#include "qmlprofiler/abstracttimelinemodel.h" +#include "qmlprofiler/qmlprofilertimelinemodel.h" #include "qmlprofiler/qmlprofilermodelmanager.h" #include "qmlprofiler/qmlprofilerdatamodel.h" @@ -29,23 +29,59 @@ namespace QmlProfilerExtension { namespace Internal { -class SceneGraphTimelineModel : public QmlProfiler::AbstractTimelineModel +class SceneGraphTimelineModel : public QmlProfiler::QmlProfilerTimelineModel { Q_OBJECT public: + enum SceneGraphStage { + MinimumSceneGraphStage = 0, + Polish = MinimumSceneGraphStage, + Wait, + GUIThreadSync, + Animations, + MaximumGUIThreadStage, + + RenderThreadSync = MaximumGUIThreadStage, + Render, + Swap, + MaximumRenderThreadStage, + + RenderPreprocess = MaximumRenderThreadStage, + RenderUpdate, + RenderBind, + RenderRender, + MaximumRenderStage, + + Material = MaximumRenderStage, + MaximumMaterialStage, + + GlyphRender = MaximumMaterialStage, + GlyphStore, + MaximumGlyphStage, + + TextureBind = MaximumGlyphStage, + TextureConvert, + TextureSwizzle, + TextureUpload, + TextureMipmap, + TextureDeletion, + MaximumTextureStage, + + MaximumSceneGraphStage = MaximumTextureStage + }; struct SceneGraphEvent { - SceneGraphEvent(int stage = -1, int glyphCount = -1); - int stage; + SceneGraphEvent(int typeId = -1, int glyphCount = -1); + int typeId; int rowNumberCollapsed; int glyphCount; // only used for one event type }; - SceneGraphTimelineModel(QObject *parent = 0); - quint64 features() const; + SceneGraphTimelineModel(QmlProfiler::QmlProfilerModelManager *manager, QObject *parent = 0); - int row(int index) const; - int selectionId(int index) const; + int expandedRow(int index) const; + int collapsedRow(int index) const; + int typeId(int index) const; QColor color(int index) const; QVariantList labels() const; @@ -57,8 +93,12 @@ protected: void clear(); private: - class SceneGraphTimelineModelPrivate; - Q_DECLARE_PRIVATE(SceneGraphTimelineModel) + void flattenLoads(); + qint64 insert(qint64 start, qint64 duration, int typeIndex, SceneGraphStage stage, + int glyphCount = -1); + static const char *threadLabel(SceneGraphStage stage); + + QVector<SceneGraphEvent> m_data; }; } // namespace Internal |