diff options
Diffstat (limited to 'src/citra_qt/debugger')
| -rw-r--r-- | src/citra_qt/debugger/profiler.cpp | 138 | ||||
| -rw-r--r-- | src/citra_qt/debugger/profiler.h | 50 | ||||
| -rw-r--r-- | src/citra_qt/debugger/profiler.ui | 33 | 
3 files changed, 221 insertions, 0 deletions
| diff --git a/src/citra_qt/debugger/profiler.cpp b/src/citra_qt/debugger/profiler.cpp new file mode 100644 index 000000000..ae0568b6a --- /dev/null +++ b/src/citra_qt/debugger/profiler.cpp @@ -0,0 +1,138 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "profiler.h" + +#include "common/profiler_reporting.h" + +using namespace Common::Profiling; + +static QVariant GetDataForColumn(int col, const AggregatedDuration& duration) +{ +    static auto duration_to_float = [](Duration dur) -> float { +        using FloatMs = std::chrono::duration<float, std::chrono::milliseconds::period>; +        return std::chrono::duration_cast<FloatMs>(dur).count(); +    }; + +    switch (col) { +    case 1: return duration_to_float(duration.avg); +    case 2: return duration_to_float(duration.min); +    case 3: return duration_to_float(duration.max); +    default: return QVariant(); +    } +} + +static const TimingCategoryInfo* GetCategoryInfo(int id) +{ +    const auto& categories = GetProfilingManager().GetTimingCategoriesInfo(); +    if (id >= categories.size()) { +        return nullptr; +    } else { +        return &categories[id]; +    } +} + +ProfilerModel::ProfilerModel(QObject* parent) : QAbstractItemModel(parent) +{ +    updateProfilingInfo(); +    const auto& categories = GetProfilingManager().GetTimingCategoriesInfo(); +    results.time_per_category.resize(categories.size()); +} + +QVariant ProfilerModel::headerData(int section, Qt::Orientation orientation, int role) const +{ +    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { +        switch (section) { +        case 0: return tr("Category"); +        case 1: return tr("Avg"); +        case 2: return tr("Min"); +        case 3: return tr("Max"); +        } +    } + +    return QVariant(); +} + +QModelIndex ProfilerModel::index(int row, int column, const QModelIndex& parent) const +{ +    return createIndex(row, column); +} + +QModelIndex ProfilerModel::parent(const QModelIndex& child) const +{ +    return QModelIndex(); +} + +int ProfilerModel::columnCount(const QModelIndex& parent) const +{ +    return 4; +} + +int ProfilerModel::rowCount(const QModelIndex& parent) const +{ +    if (parent.isValid()) { +        return 0; +    } else { +        return results.time_per_category.size() + 2; +    } +} + +QVariant ProfilerModel::data(const QModelIndex& index, int role) const +{ +    if (role == Qt::DisplayRole) { +        if (index.row() == 0) { +            if (index.column() == 0) { +                return tr("Frame"); +            } else { +                return GetDataForColumn(index.column(), results.frame_time); +            } +        } else if (index.row() == 1) { +            if (index.column() == 0) { +                return tr("Frame (with swapping)"); +            } else { +                return GetDataForColumn(index.column(), results.interframe_time); +            } +        } else { +            if (index.column() == 0) { +                const TimingCategoryInfo* info = GetCategoryInfo(index.row() - 2); +                return info != nullptr ? QString(info->name) : QVariant(); +            } else { +                if (index.row() - 2 < results.time_per_category.size()) { +                    return GetDataForColumn(index.column(), results.time_per_category[index.row() - 2]); +                } else { +                    return QVariant(); +                } +            } +        } +    } + +    return QVariant(); +} + +void ProfilerModel::updateProfilingInfo() +{ +    results = GetTimingResultsAggregator()->GetAggregatedResults(); +    emit dataChanged(createIndex(0, 1), createIndex(rowCount() - 1, 3)); +} + +ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent) +{ +    ui.setupUi(this); + +    model = new ProfilerModel(this); +    ui.treeView->setModel(model); + +    connect(this, SIGNAL(visibilityChanged(bool)), SLOT(setProfilingInfoUpdateEnabled(bool))); +    connect(&update_timer, SIGNAL(timeout()), model, SLOT(updateProfilingInfo())); +} + +void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable) +{ +    if (enable) { +        update_timer.start(100); +        model->updateProfilingInfo(); +    } else { +        update_timer.stop(); +    } +} diff --git a/src/citra_qt/debugger/profiler.h b/src/citra_qt/debugger/profiler.h new file mode 100644 index 000000000..a6d87aa0f --- /dev/null +++ b/src/citra_qt/debugger/profiler.h @@ -0,0 +1,50 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <QAbstractItemModel> +#include <QDockWidget> +#include <QTimer> +#include "ui_profiler.h" + +#include "common/profiler_reporting.h" + +class ProfilerModel : public QAbstractItemModel +{ +    Q_OBJECT + +public: +    ProfilerModel(QObject* parent); + +    QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; +    QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override; +    QModelIndex parent(const QModelIndex& child) const override; +    int columnCount(const QModelIndex& parent = QModelIndex()) const override; +    int rowCount(const QModelIndex& parent = QModelIndex()) const override; +    QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; + +public slots: +    void updateProfilingInfo(); + +private: +    Common::Profiling::AggregatedFrameResult results; +}; + +class ProfilerWidget : public QDockWidget +{ +    Q_OBJECT + +public: +    ProfilerWidget(QWidget* parent = 0); + +private slots: +    void setProfilingInfoUpdateEnabled(bool enable); + +private: +    Ui::Profiler ui; +    ProfilerModel* model; + +    QTimer update_timer; +}; diff --git a/src/citra_qt/debugger/profiler.ui b/src/citra_qt/debugger/profiler.ui new file mode 100644 index 000000000..d3c9a9a1f --- /dev/null +++ b/src/citra_qt/debugger/profiler.ui @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>Profiler</class> + <widget class="QDockWidget" name="Profiler"> +  <property name="geometry"> +   <rect> +    <x>0</x> +    <y>0</y> +    <width>400</width> +    <height>300</height> +   </rect> +  </property> +  <property name="windowTitle"> +   <string>Profiler</string> +  </property> +  <widget class="QWidget" name="dockWidgetContents"> +   <layout class="QVBoxLayout" name="verticalLayout"> +    <item> +     <widget class="QTreeView" name="treeView"> +      <property name="alternatingRowColors"> +       <bool>true</bool> +      </property> +      <property name="uniformRowHeights"> +       <bool>true</bool> +      </property> +     </widget> +    </item> +   </layout> +  </widget> + </widget> + <resources/> + <connections/> +</ui> | 
