aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/citra_qt/debugger
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner <yuriks@yuriks.net>2015-02-05 14:53:25 -0200
committerGravatar Yuri Kunde Schlesner <yuriks@yuriks.net>2015-03-01 21:47:13 -0300
commitcd1fbfcf1b70e365d81480ec0f56db19ed02454f (patch)
treeb220b105d1b8016bb258047683bf2d03795c8881 /src/citra_qt/debugger
parentc1d29ac20240ad92a49b84409b92ed1d326720a9 (diff)
Add profiling infrastructure and widget
Diffstat (limited to 'src/citra_qt/debugger')
-rw-r--r--src/citra_qt/debugger/profiler.cpp138
-rw-r--r--src/citra_qt/debugger/profiler.h50
-rw-r--r--src/citra_qt/debugger/profiler.ui33
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 00000000..ae0568b6
--- /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 00000000..a6d87aa0
--- /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 00000000..d3c9a9a1
--- /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>