summaryrefslogtreecommitdiff
path: root/src/citra_qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/citra_qt')
-rw-r--r--src/citra_qt/CMakeLists.txt3
-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
-rw-r--r--src/citra_qt/main.cpp6
-rw-r--r--src/citra_qt/main.h2
6 files changed, 232 insertions, 0 deletions
diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt
index 586bc84b0..a1ad00f57 100644
--- a/src/citra_qt/CMakeLists.txt
+++ b/src/citra_qt/CMakeLists.txt
@@ -13,6 +13,7 @@ set(SRCS
13 debugger/graphics_cmdlists.cpp 13 debugger/graphics_cmdlists.cpp
14 debugger/graphics_framebuffer.cpp 14 debugger/graphics_framebuffer.cpp
15 debugger/graphics_vertex_shader.cpp 15 debugger/graphics_vertex_shader.cpp
16 debugger/profiler.cpp
16 debugger/ramview.cpp 17 debugger/ramview.cpp
17 debugger/registers.cpp 18 debugger/registers.cpp
18 util/spinbox.cpp 19 util/spinbox.cpp
@@ -35,6 +36,7 @@ set(HEADERS
35 debugger/graphics_cmdlists.h 36 debugger/graphics_cmdlists.h
36 debugger/graphics_framebuffer.h 37 debugger/graphics_framebuffer.h
37 debugger/graphics_vertex_shader.h 38 debugger/graphics_vertex_shader.h
39 debugger/profiler.h
38 debugger/ramview.h 40 debugger/ramview.h
39 debugger/registers.h 41 debugger/registers.h
40 util/spinbox.h 42 util/spinbox.h
@@ -48,6 +50,7 @@ set(UIS
48 config/controller_config.ui 50 config/controller_config.ui
49 debugger/callstack.ui 51 debugger/callstack.ui
50 debugger/disassembler.ui 52 debugger/disassembler.ui
53 debugger/profiler.ui
51 debugger/registers.ui 54 debugger/registers.ui
52 hotkeys.ui 55 hotkeys.ui
53 main.ui 56 main.ui
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 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "profiler.h"
6
7#include "common/profiler_reporting.h"
8
9using namespace Common::Profiling;
10
11static QVariant GetDataForColumn(int col, const AggregatedDuration& duration)
12{
13 static auto duration_to_float = [](Duration dur) -> float {
14 using FloatMs = std::chrono::duration<float, std::chrono::milliseconds::period>;
15 return std::chrono::duration_cast<FloatMs>(dur).count();
16 };
17
18 switch (col) {
19 case 1: return duration_to_float(duration.avg);
20 case 2: return duration_to_float(duration.min);
21 case 3: return duration_to_float(duration.max);
22 default: return QVariant();
23 }
24}
25
26static const TimingCategoryInfo* GetCategoryInfo(int id)
27{
28 const auto& categories = GetProfilingManager().GetTimingCategoriesInfo();
29 if (id >= categories.size()) {
30 return nullptr;
31 } else {
32 return &categories[id];
33 }
34}
35
36ProfilerModel::ProfilerModel(QObject* parent) : QAbstractItemModel(parent)
37{
38 updateProfilingInfo();
39 const auto& categories = GetProfilingManager().GetTimingCategoriesInfo();
40 results.time_per_category.resize(categories.size());
41}
42
43QVariant ProfilerModel::headerData(int section, Qt::Orientation orientation, int role) const
44{
45 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
46 switch (section) {
47 case 0: return tr("Category");
48 case 1: return tr("Avg");
49 case 2: return tr("Min");
50 case 3: return tr("Max");
51 }
52 }
53
54 return QVariant();
55}
56
57QModelIndex ProfilerModel::index(int row, int column, const QModelIndex& parent) const
58{
59 return createIndex(row, column);
60}
61
62QModelIndex ProfilerModel::parent(const QModelIndex& child) const
63{
64 return QModelIndex();
65}
66
67int ProfilerModel::columnCount(const QModelIndex& parent) const
68{
69 return 4;
70}
71
72int ProfilerModel::rowCount(const QModelIndex& parent) const
73{
74 if (parent.isValid()) {
75 return 0;
76 } else {
77 return results.time_per_category.size() + 2;
78 }
79}
80
81QVariant ProfilerModel::data(const QModelIndex& index, int role) const
82{
83 if (role == Qt::DisplayRole) {
84 if (index.row() == 0) {
85 if (index.column() == 0) {
86 return tr("Frame");
87 } else {
88 return GetDataForColumn(index.column(), results.frame_time);
89 }
90 } else if (index.row() == 1) {
91 if (index.column() == 0) {
92 return tr("Frame (with swapping)");
93 } else {
94 return GetDataForColumn(index.column(), results.interframe_time);
95 }
96 } else {
97 if (index.column() == 0) {
98 const TimingCategoryInfo* info = GetCategoryInfo(index.row() - 2);
99 return info != nullptr ? QString(info->name) : QVariant();
100 } else {
101 if (index.row() - 2 < results.time_per_category.size()) {
102 return GetDataForColumn(index.column(), results.time_per_category[index.row() - 2]);
103 } else {
104 return QVariant();
105 }
106 }
107 }
108 }
109
110 return QVariant();
111}
112
113void ProfilerModel::updateProfilingInfo()
114{
115 results = GetTimingResultsAggregator()->GetAggregatedResults();
116 emit dataChanged(createIndex(0, 1), createIndex(rowCount() - 1, 3));
117}
118
119ProfilerWidget::ProfilerWidget(QWidget* parent) : QDockWidget(parent)
120{
121 ui.setupUi(this);
122
123 model = new ProfilerModel(this);
124 ui.treeView->setModel(model);
125
126 connect(this, SIGNAL(visibilityChanged(bool)), SLOT(setProfilingInfoUpdateEnabled(bool)));
127 connect(&update_timer, SIGNAL(timeout()), model, SLOT(updateProfilingInfo()));
128}
129
130void ProfilerWidget::setProfilingInfoUpdateEnabled(bool enable)
131{
132 if (enable) {
133 update_timer.start(100);
134 model->updateProfilingInfo();
135 } else {
136 update_timer.stop();
137 }
138}
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 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <QAbstractItemModel>
8#include <QDockWidget>
9#include <QTimer>
10#include "ui_profiler.h"
11
12#include "common/profiler_reporting.h"
13
14class ProfilerModel : public QAbstractItemModel
15{
16 Q_OBJECT
17
18public:
19 ProfilerModel(QObject* parent);
20
21 QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
22 QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
23 QModelIndex parent(const QModelIndex& child) const override;
24 int columnCount(const QModelIndex& parent = QModelIndex()) const override;
25 int rowCount(const QModelIndex& parent = QModelIndex()) const override;
26 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
27
28public slots:
29 void updateProfilingInfo();
30
31private:
32 Common::Profiling::AggregatedFrameResult results;
33};
34
35class ProfilerWidget : public QDockWidget
36{
37 Q_OBJECT
38
39public:
40 ProfilerWidget(QWidget* parent = 0);
41
42private slots:
43 void setProfilingInfoUpdateEnabled(bool enable);
44
45private:
46 Ui::Profiler ui;
47 ProfilerModel* model;
48
49 QTimer update_timer;
50};
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 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>Profiler</class>
4 <widget class="QDockWidget" name="Profiler">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>400</width>
10 <height>300</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Profiler</string>
15 </property>
16 <widget class="QWidget" name="dockWidgetContents">
17 <layout class="QVBoxLayout" name="verticalLayout">
18 <item>
19 <widget class="QTreeView" name="treeView">
20 <property name="alternatingRowColors">
21 <bool>true</bool>
22 </property>
23 <property name="uniformRowHeights">
24 <bool>true</bool>
25 </property>
26 </widget>
27 </item>
28 </layout>
29 </widget>
30 </widget>
31 <resources/>
32 <connections/>
33</ui>
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 881c7d337..e3db3c20a 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -35,6 +35,7 @@
35#include "debugger/graphics_cmdlists.h" 35#include "debugger/graphics_cmdlists.h"
36#include "debugger/graphics_framebuffer.h" 36#include "debugger/graphics_framebuffer.h"
37#include "debugger/graphics_vertex_shader.h" 37#include "debugger/graphics_vertex_shader.h"
38#include "debugger/profiler.h"
38 39
39#include "core/settings.h" 40#include "core/settings.h"
40#include "core/system.h" 41#include "core/system.h"
@@ -57,6 +58,10 @@ GMainWindow::GMainWindow()
57 render_window = new GRenderWindow; 58 render_window = new GRenderWindow;
58 render_window->hide(); 59 render_window->hide();
59 60
61 profilerWidget = new ProfilerWidget(this);
62 addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
63 profilerWidget->hide();
64
60 disasmWidget = new DisassemblerWidget(this, render_window->GetEmuThread()); 65 disasmWidget = new DisassemblerWidget(this, render_window->GetEmuThread());
61 addDockWidget(Qt::BottomDockWidgetArea, disasmWidget); 66 addDockWidget(Qt::BottomDockWidgetArea, disasmWidget);
62 disasmWidget->hide(); 67 disasmWidget->hide();
@@ -90,6 +95,7 @@ GMainWindow::GMainWindow()
90 graphicsVertexShaderWidget->hide(); 95 graphicsVertexShaderWidget->hide();
91 96
92 QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging")); 97 QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
98 debug_menu->addAction(profilerWidget->toggleViewAction());
93 debug_menu->addAction(disasmWidget->toggleViewAction()); 99 debug_menu->addAction(disasmWidget->toggleViewAction());
94 debug_menu->addAction(registersWidget->toggleViewAction()); 100 debug_menu->addAction(registersWidget->toggleViewAction());
95 debug_menu->addAction(callstackWidget->toggleViewAction()); 101 debug_menu->addAction(callstackWidget->toggleViewAction());
diff --git a/src/citra_qt/main.h b/src/citra_qt/main.h
index dd53489dd..9b57c5772 100644
--- a/src/citra_qt/main.h
+++ b/src/citra_qt/main.h
@@ -11,6 +11,7 @@
11 11
12class GImageInfo; 12class GImageInfo;
13class GRenderWindow; 13class GRenderWindow;
14class ProfilerWidget;
14class DisassemblerWidget; 15class DisassemblerWidget;
15class RegistersWidget; 16class RegistersWidget;
16class CallstackWidget; 17class CallstackWidget;
@@ -54,6 +55,7 @@ private:
54 55
55 GRenderWindow* render_window; 56 GRenderWindow* render_window;
56 57
58 ProfilerWidget* profilerWidget;
57 DisassemblerWidget* disasmWidget; 59 DisassemblerWidget* disasmWidget;
58 RegistersWidget* registersWidget; 60 RegistersWidget* registersWidget;
59 CallstackWidget* callstackWidget; 61 CallstackWidget* callstackWidget;