summaryrefslogtreecommitdiff
path: root/src/yuzu/debugger
diff options
context:
space:
mode:
authorZephyron <zephyron@citron-emu.org>2024-12-31 16:19:25 +1000
committerZephyron <zephyron@citron-emu.org>2024-12-31 16:19:25 +1000
commit9427e27e24a7135880ee2881c3c44988e174b41a (patch)
tree83f0062a35be144f6b162eaa823c5b3c7620146e /src/yuzu/debugger
parentb35ae725d20960411e8588b11c12a2d55f86c9d0 (diff)
chore: update project branding to citron
Diffstat (limited to 'src/yuzu/debugger')
-rw-r--r--src/yuzu/debugger/console.cpp49
-rw-r--r--src/yuzu/debugger/console.h13
-rw-r--r--src/yuzu/debugger/controller.cpp116
-rw-r--r--src/yuzu/debugger/controller.h56
-rw-r--r--src/yuzu/debugger/profiler.cpp229
-rw-r--r--src/yuzu/debugger/profiler.h27
-rw-r--r--src/yuzu/debugger/wait_tree.cpp431
-rw-r--r--src/yuzu/debugger/wait_tree.h188
8 files changed, 0 insertions, 1109 deletions
diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp
deleted file mode 100644
index 1c1342ff1..000000000
--- a/src/yuzu/debugger/console.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#ifdef _WIN32
-#include <windows.h>
-
-#include <wincon.h>
-#endif
-
-#include "common/logging/backend.h"
-#include "yuzu/debugger/console.h"
-#include "yuzu/uisettings.h"
-
-namespace Debugger {
-void ToggleConsole() {
- static bool console_shown = false;
- if (console_shown == UISettings::values.show_console.GetValue()) {
- return;
- } else {
- console_shown = UISettings::values.show_console.GetValue();
- }
-
- using namespace Common::Log;
-#if defined(_WIN32) && !defined(_DEBUG)
- FILE* temp;
- if (UISettings::values.show_console) {
- if (AllocConsole()) {
- // The first parameter for freopen_s is a out parameter, so we can just ignore it
- freopen_s(&temp, "CONIN$", "r", stdin);
- freopen_s(&temp, "CONOUT$", "w", stdout);
- freopen_s(&temp, "CONOUT$", "w", stderr);
- SetConsoleOutputCP(65001);
- SetColorConsoleBackendEnabled(true);
- }
- } else {
- if (FreeConsole()) {
- // In order to close the console, we have to also detach the streams on it.
- // Just redirect them to NUL if there is no console window
- SetColorConsoleBackendEnabled(false);
- freopen_s(&temp, "NUL", "r", stdin);
- freopen_s(&temp, "NUL", "w", stdout);
- freopen_s(&temp, "NUL", "w", stderr);
- }
- }
-#else
- SetColorConsoleBackendEnabled(UISettings::values.show_console.GetValue());
-#endif
-}
-} // namespace Debugger
diff --git a/src/yuzu/debugger/console.h b/src/yuzu/debugger/console.h
deleted file mode 100644
index 2491d1ec1..000000000
--- a/src/yuzu/debugger/console.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-namespace Debugger {
-
-/**
- * Uses the WINAPI to hide or show the stderr console. This function is a placeholder until we can
- * get a real qt logging window which would work for all platforms.
- */
-void ToggleConsole();
-} // namespace Debugger
diff --git a/src/yuzu/debugger/controller.cpp b/src/yuzu/debugger/controller.cpp
deleted file mode 100644
index 216d2974d..000000000
--- a/src/yuzu/debugger/controller.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-// SPDX-FileCopyrightText: 2015 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <QAction>
-#include <QLayout>
-#include <QString>
-#include "common/settings.h"
-#include "hid_core/frontend/emulated_controller.h"
-#include "hid_core/hid_core.h"
-#include "input_common/drivers/tas_input.h"
-#include "input_common/main.h"
-#include "yuzu/configuration/configure_input_player_widget.h"
-#include "yuzu/debugger/controller.h"
-
-ControllerDialog::ControllerDialog(Core::HID::HIDCore& hid_core_,
- std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
- QWidget* parent)
- : QWidget(parent, Qt::Dialog), hid_core{hid_core_}, input_subsystem{input_subsystem_} {
- setObjectName(QStringLiteral("Controller"));
- setWindowTitle(tr("Controller P1"));
- resize(500, 350);
- setMinimumSize(500, 350);
- // Enable the maximize button
- setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
-
- widget = new PlayerControlPreview(this);
- refreshConfiguration();
- QLayout* layout = new QVBoxLayout(this);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->addWidget(widget);
- setLayout(layout);
-
- // Configure focus so that widget is focusable and the dialog automatically forwards focus to
- // it.
- setFocusProxy(widget);
- widget->setFocusPolicy(Qt::StrongFocus);
- widget->setFocus();
-}
-
-void ControllerDialog::refreshConfiguration() {
- UnloadController();
- auto* player_1 = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
- auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
- // Display the correct controller
- controller = handheld->IsConnected() ? handheld : player_1;
-
- Core::HID::ControllerUpdateCallback engine_callback{
- .on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); },
- .is_npad_service = true,
- };
- callback_key = controller->SetCallback(engine_callback);
- widget->SetController(controller);
- is_controller_set = true;
-}
-
-QAction* ControllerDialog::toggleViewAction() {
- if (toggle_view_action == nullptr) {
- toggle_view_action = new QAction(tr("&Controller P1"), this);
- toggle_view_action->setCheckable(true);
- toggle_view_action->setChecked(isVisible());
- connect(toggle_view_action, &QAction::toggled, this, &ControllerDialog::setVisible);
- }
-
- return toggle_view_action;
-}
-
-void ControllerDialog::UnloadController() {
- widget->UnloadController();
- if (is_controller_set) {
- controller->DeleteCallback(callback_key);
- is_controller_set = false;
- }
-}
-
-void ControllerDialog::showEvent(QShowEvent* ev) {
- if (toggle_view_action) {
- toggle_view_action->setChecked(isVisible());
- }
- QWidget::showEvent(ev);
-}
-
-void ControllerDialog::hideEvent(QHideEvent* ev) {
- if (toggle_view_action) {
- toggle_view_action->setChecked(isVisible());
- }
- QWidget::hideEvent(ev);
-}
-
-void ControllerDialog::ControllerUpdate(Core::HID::ControllerTriggerType type) {
- // TODO(german77): Remove TAS from here
- switch (type) {
- case Core::HID::ControllerTriggerType::Button:
- case Core::HID::ControllerTriggerType::Stick: {
- const auto buttons_values = controller->GetButtonsValues();
- const auto stick_values = controller->GetSticks();
- u64 buttons = 0;
- std::size_t index = 0;
- for (const auto& button : buttons_values) {
- buttons |= button.value ? 1LLU << index : 0;
- index++;
- }
- const InputCommon::TasInput::TasAnalog left_axis = {
- .x = stick_values.left.x / 32767.f,
- .y = stick_values.left.y / 32767.f,
- };
- const InputCommon::TasInput::TasAnalog right_axis = {
- .x = stick_values.right.x / 32767.f,
- .y = stick_values.right.y / 32767.f,
- };
- input_subsystem->GetTas()->RecordInput(buttons, left_axis, right_axis);
- break;
- }
- default:
- break;
- }
-}
diff --git a/src/yuzu/debugger/controller.h b/src/yuzu/debugger/controller.h
deleted file mode 100644
index 9651dfaa9..000000000
--- a/src/yuzu/debugger/controller.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// SPDX-FileCopyrightText: 2015 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <QWidget>
-
-class QAction;
-class QHideEvent;
-class QShowEvent;
-class PlayerControlPreview;
-
-namespace InputCommon {
-class InputSubsystem;
-}
-
-namespace Core::HID {
-class HIDCore;
-class EmulatedController;
-enum class ControllerTriggerType;
-} // namespace Core::HID
-
-class ControllerDialog : public QWidget {
- Q_OBJECT
-
-public:
- explicit ControllerDialog(Core::HID::HIDCore& hid_core_,
- std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
- QWidget* parent = nullptr);
-
- /// Returns a QAction that can be used to toggle visibility of this dialog.
- QAction* toggleViewAction();
-
- /// Reloads the widget to apply any changes in the configuration
- void refreshConfiguration();
-
- /// Disables events from the emulated controller
- void UnloadController();
-
-protected:
- void showEvent(QShowEvent* ev) override;
- void hideEvent(QHideEvent* ev) override;
-
-private:
- /// Redirects input from the widget to the TAS driver
- void ControllerUpdate(Core::HID::ControllerTriggerType type);
-
- int callback_key;
- bool is_controller_set{};
- Core::HID::EmulatedController* controller;
-
- QAction* toggle_view_action = nullptr;
- PlayerControlPreview* widget;
- Core::HID::HIDCore& hid_core;
- std::shared_ptr<InputCommon::InputSubsystem> input_subsystem;
-};
diff --git a/src/yuzu/debugger/profiler.cpp b/src/yuzu/debugger/profiler.cpp
deleted file mode 100644
index 493ee0b17..000000000
--- a/src/yuzu/debugger/profiler.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-// SPDX-FileCopyrightText: 2015 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <QAction>
-#include <QLayout>
-#include <QMouseEvent>
-#include <QPainter>
-#include <QString>
-#include <QTimer>
-#include "common/common_types.h"
-#include "common/microprofile.h"
-#include "yuzu/debugger/profiler.h"
-#include "yuzu/util/util.h"
-
-// Include the implementation of the UI in this file. This isn't in microprofile.cpp because the
-// non-Qt frontends don't need it (and don't implement the UI drawing hooks either).
-#if MICROPROFILE_ENABLED
-#define MICROPROFILEUI_IMPL 1
-#include "common/microprofileui.h"
-
-class MicroProfileWidget : public QWidget {
-public:
- MicroProfileWidget(QWidget* parent = nullptr);
-
-protected:
- void paintEvent(QPaintEvent* ev) override;
- void showEvent(QShowEvent* ev) override;
- void hideEvent(QHideEvent* ev) override;
-
- void mouseMoveEvent(QMouseEvent* ev) override;
- void mousePressEvent(QMouseEvent* ev) override;
- void mouseReleaseEvent(QMouseEvent* ev) override;
- void wheelEvent(QWheelEvent* ev) override;
-
- void keyPressEvent(QKeyEvent* ev) override;
- void keyReleaseEvent(QKeyEvent* ev) override;
-
-private:
- /// This timer is used to redraw the widget's contents continuously. To save resources, it only
- /// runs while the widget is visible.
- QTimer update_timer;
- /// Scale the coordinate system appropriately when dpi != 96.
- qreal x_scale = 1.0, y_scale = 1.0;
-};
-
-#endif
-
-MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) {
- setObjectName(QStringLiteral("MicroProfile"));
- setWindowTitle(tr("&MicroProfile"));
- resize(1000, 600);
- // Enable the maximize button
- setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
-
-#if MICROPROFILE_ENABLED
-
- MicroProfileWidget* widget = new MicroProfileWidget(this);
-
- QLayout* layout = new QVBoxLayout(this);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->addWidget(widget);
- setLayout(layout);
-
- // Configure focus so that widget is focusable and the dialog automatically forwards focus to
- // it.
- setFocusProxy(widget);
- widget->setFocusPolicy(Qt::StrongFocus);
- widget->setFocus();
-#endif
-}
-
-QAction* MicroProfileDialog::toggleViewAction() {
- if (toggle_view_action == nullptr) {
- toggle_view_action = new QAction(windowTitle(), this);
- toggle_view_action->setCheckable(true);
- toggle_view_action->setChecked(isVisible());
- connect(toggle_view_action, &QAction::toggled, this, &MicroProfileDialog::setVisible);
- }
-
- return toggle_view_action;
-}
-
-void MicroProfileDialog::showEvent(QShowEvent* ev) {
- if (toggle_view_action) {
- toggle_view_action->setChecked(isVisible());
- }
- QWidget::showEvent(ev);
-}
-
-void MicroProfileDialog::hideEvent(QHideEvent* ev) {
- if (toggle_view_action) {
- toggle_view_action->setChecked(isVisible());
- }
- QWidget::hideEvent(ev);
-}
-
-#if MICROPROFILE_ENABLED
-
-/// There's no way to pass a user pointer to MicroProfile, so this variable is used to make the
-/// QPainter available inside the drawing callbacks.
-static QPainter* mp_painter = nullptr;
-
-MicroProfileWidget::MicroProfileWidget(QWidget* parent) : QWidget(parent) {
- // Send mouse motion events even when not dragging.
- setMouseTracking(true);
-
- MicroProfileSetDisplayMode(1); // Timers screen
- MicroProfileInitUI();
-
- connect(&update_timer, &QTimer::timeout, this, qOverload<>(&MicroProfileWidget::update));
-}
-
-void MicroProfileWidget::paintEvent(QPaintEvent* ev) {
- QPainter painter(this);
-
- // The units used by Microprofile for drawing are based in pixels on a 96 dpi display.
- x_scale = qreal(painter.device()->logicalDpiX()) / 96.0;
- y_scale = qreal(painter.device()->logicalDpiY()) / 96.0;
- painter.scale(x_scale, y_scale);
-
- painter.setBackground(Qt::black);
- painter.eraseRect(rect());
-
- QFont font = GetMonospaceFont();
- font.setPixelSize(MICROPROFILE_TEXT_HEIGHT);
- painter.setFont(font);
-
- mp_painter = &painter;
- MicroProfileDraw(rect().width() / x_scale, rect().height() / y_scale);
- mp_painter = nullptr;
-}
-
-void MicroProfileWidget::showEvent(QShowEvent* ev) {
- update_timer.start(15); // ~60 Hz
- QWidget::showEvent(ev);
-}
-
-void MicroProfileWidget::hideEvent(QHideEvent* ev) {
- update_timer.stop();
- QWidget::hideEvent(ev);
-}
-
-void MicroProfileWidget::mouseMoveEvent(QMouseEvent* ev) {
- const auto mouse_position = ev->pos();
- MicroProfileMousePosition(mouse_position.x() / x_scale, mouse_position.y() / y_scale, 0);
- ev->accept();
-}
-
-void MicroProfileWidget::mousePressEvent(QMouseEvent* ev) {
- const auto mouse_position = ev->pos();
- MicroProfileMousePosition(mouse_position.x() / x_scale, mouse_position.y() / y_scale, 0);
- MicroProfileMouseButton(ev->buttons() & Qt::LeftButton, ev->buttons() & Qt::RightButton);
- ev->accept();
-}
-
-void MicroProfileWidget::mouseReleaseEvent(QMouseEvent* ev) {
- const auto mouse_position = ev->pos();
- MicroProfileMousePosition(mouse_position.x() / x_scale, mouse_position.y() / y_scale, 0);
- MicroProfileMouseButton(ev->buttons() & Qt::LeftButton, ev->buttons() & Qt::RightButton);
- ev->accept();
-}
-
-void MicroProfileWidget::wheelEvent(QWheelEvent* ev) {
- const auto wheel_position = ev->position().toPoint();
- MicroProfileMousePosition(wheel_position.x() / x_scale, wheel_position.y() / y_scale,
- ev->angleDelta().y() / 120);
- ev->accept();
-}
-
-void MicroProfileWidget::keyPressEvent(QKeyEvent* ev) {
- if (ev->key() == Qt::Key_Control) {
- // Inform MicroProfile that the user is holding Ctrl.
- MicroProfileModKey(1);
- }
- QWidget::keyPressEvent(ev);
-}
-
-void MicroProfileWidget::keyReleaseEvent(QKeyEvent* ev) {
- if (ev->key() == Qt::Key_Control) {
- MicroProfileModKey(0);
- }
- QWidget::keyReleaseEvent(ev);
-}
-
-// These functions are called by MicroProfileDraw to draw the interface elements on the screen.
-
-void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 text_length) {
- // hex_color does not include an alpha, so it must be assumed to be 255
- mp_painter->setPen(QColor::fromRgb(hex_color));
-
- // It's impossible to draw a string using a monospaced font with a fixed width per cell in a
- // way that's reliable across different platforms and fonts as far as I (yuriks) can tell, so
- // draw each character individually in order to precisely control the text advance.
- for (u32 i = 0; i < text_length; ++i) {
- // Position the text baseline 1 pixel above the bottom of the text cell, this gives nice
- // vertical alignment of text for a wide range of tested fonts.
- mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QString{QLatin1Char{text[i]}});
- x += MICROPROFILE_TEXT_WIDTH + 1;
- }
-}
-
-void MicroProfileDrawBox(int left, int top, int right, int bottom, u32 hex_color,
- MicroProfileBoxType type) {
- QColor color = QColor::fromRgba(hex_color);
- QBrush brush = color;
- if (type == MicroProfileBoxTypeBar) {
- QLinearGradient gradient(left, top, left, bottom);
- gradient.setColorAt(0.f, color.lighter(125));
- gradient.setColorAt(1.f, color.darker(125));
- brush = gradient;
- }
- mp_painter->fillRect(left, top, right - left, bottom - top, brush);
-}
-
-void MicroProfileDrawLine2D(u32 vertices_length, float* vertices, u32 hex_color) {
- // Temporary vector used to convert between the float array and QPointF. Marked static to reuse
- // the allocation across calls.
- static std::vector<QPointF> point_buf;
-
- for (u32 i = 0; i < vertices_length; ++i) {
- point_buf.emplace_back(vertices[i * 2 + 0], vertices[i * 2 + 1]);
- }
-
- // hex_color does not include an alpha, so it must be assumed to be 255
- mp_painter->setPen(QColor::fromRgb(hex_color));
- mp_painter->drawPolyline(point_buf.data(), vertices_length);
- point_buf.clear();
-}
-#endif
diff --git a/src/yuzu/debugger/profiler.h b/src/yuzu/debugger/profiler.h
deleted file mode 100644
index 4c8ccd3c2..000000000
--- a/src/yuzu/debugger/profiler.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-FileCopyrightText: 2015 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <QWidget>
-
-class QAction;
-class QHideEvent;
-class QShowEvent;
-
-class MicroProfileDialog : public QWidget {
- Q_OBJECT
-
-public:
- explicit MicroProfileDialog(QWidget* parent = nullptr);
-
- /// Returns a QAction that can be used to toggle visibility of this dialog.
- QAction* toggleViewAction();
-
-protected:
- void showEvent(QShowEvent* ev) override;
- void hideEvent(QHideEvent* ev) override;
-
-private:
- QAction* toggle_view_action = nullptr;
-};
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
deleted file mode 100644
index c05a05057..000000000
--- a/src/yuzu/debugger/wait_tree.cpp
+++ /dev/null
@@ -1,431 +0,0 @@
-// SPDX-FileCopyrightText: 2016 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include <array>
-#include <fmt/format.h>
-
-#include "yuzu/debugger/wait_tree.h"
-#include "yuzu/uisettings.h"
-
-#include "core/arm/debug.h"
-#include "core/core.h"
-#include "core/hle/kernel/k_class_token.h"
-#include "core/hle/kernel/k_handle_table.h"
-#include "core/hle/kernel/k_process.h"
-#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/k_scheduler.h"
-#include "core/hle/kernel/k_synchronization_object.h"
-#include "core/hle/kernel/k_thread.h"
-#include "core/hle/kernel/svc_common.h"
-#include "core/hle/kernel/svc_types.h"
-#include "core/memory.h"
-
-namespace {
-
-constexpr std::array<std::array<Qt::GlobalColor, 2>, 10> WaitTreeColors{{
- {Qt::GlobalColor::darkGreen, Qt::GlobalColor::green},
- {Qt::GlobalColor::darkBlue, Qt::GlobalColor::cyan},
- {Qt::GlobalColor::lightGray, Qt::GlobalColor::lightGray},
- {Qt::GlobalColor::lightGray, Qt::GlobalColor::lightGray},
- {Qt::GlobalColor::darkRed, Qt::GlobalColor::red},
- {Qt::GlobalColor::darkYellow, Qt::GlobalColor::yellow},
- {Qt::GlobalColor::red, Qt::GlobalColor::red},
- {Qt::GlobalColor::darkCyan, Qt::GlobalColor::cyan},
- {Qt::GlobalColor::gray, Qt::GlobalColor::gray},
-}};
-
-bool IsDarkTheme() {
- const auto& theme = UISettings::values.theme;
- return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
- theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
-}
-
-} // namespace
-
-WaitTreeItem::WaitTreeItem() = default;
-WaitTreeItem::~WaitTreeItem() = default;
-
-QColor WaitTreeItem::GetColor() const {
- if (IsDarkTheme()) {
- return QColor(Qt::GlobalColor::white);
- } else {
- return QColor(Qt::GlobalColor::black);
- }
-}
-
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeItem::GetChildren() const {
- return {};
-}
-
-void WaitTreeItem::Expand() {
- if (IsExpandable() && !expanded) {
- children = GetChildren();
- for (std::size_t i = 0; i < children.size(); ++i) {
- children[i]->parent = this;
- children[i]->row = i;
- }
- expanded = true;
- }
-}
-
-WaitTreeItem* WaitTreeItem::Parent() const {
- return parent;
-}
-
-const std::vector<std::unique_ptr<WaitTreeItem>>& WaitTreeItem::Children() const {
- return children;
-}
-
-bool WaitTreeItem::IsExpandable() const {
- return false;
-}
-
-std::size_t WaitTreeItem::Row() const {
- return row;
-}
-
-std::vector<std::unique_ptr<WaitTreeThread>> WaitTreeItem::MakeThreadItemList(
- Core::System& system) {
- std::vector<std::unique_ptr<WaitTreeThread>> item_list;
- std::size_t row = 0;
- auto add_threads = [&](const std::vector<Kernel::KThread*>& threads) {
- for (std::size_t i = 0; i < threads.size(); ++i) {
- if (threads[i]->GetThreadType() == Kernel::ThreadType::User) {
- item_list.push_back(std::make_unique<WaitTreeThread>(*threads[i], system));
- item_list.back()->row = row;
- }
- ++row;
- }
- };
-
- add_threads(system.GlobalSchedulerContext().GetThreadList());
-
- return item_list;
-}
-
-WaitTreeText::WaitTreeText(QString t) : text(std::move(t)) {}
-WaitTreeText::~WaitTreeText() = default;
-
-QString WaitTreeText::GetText() const {
- return text;
-}
-
-WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_)
- : thread{thread_}, system{system_} {}
-WaitTreeCallstack::~WaitTreeCallstack() = default;
-
-QString WaitTreeCallstack::GetText() const {
- return tr("Call stack");
-}
-
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list;
-
- if (thread.GetThreadType() != Kernel::ThreadType::User) {
- return list;
- }
-
- if (thread.GetOwnerProcess() == nullptr || !thread.GetOwnerProcess()->Is64Bit()) {
- return list;
- }
-
- auto backtrace = Core::GetBacktraceFromContext(thread.GetOwnerProcess(), thread.GetContext());
-
- for (auto& entry : backtrace) {
- std::string s = fmt::format("{:20}{:016X} {:016X} {:016X} {}", entry.module, entry.address,
- entry.original_address, entry.offset, entry.name);
- list.push_back(std::make_unique<WaitTreeText>(QString::fromStdString(s)));
- }
-
- return list;
-}
-
-WaitTreeSynchronizationObject::WaitTreeSynchronizationObject(
- const Kernel::KSynchronizationObject& object_, Core::System& system_)
- : object{object_}, system{system_} {}
-WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default;
-
-WaitTreeExpandableItem::WaitTreeExpandableItem() = default;
-WaitTreeExpandableItem::~WaitTreeExpandableItem() = default;
-
-bool WaitTreeExpandableItem::IsExpandable() const {
- return true;
-}
-
-QString WaitTreeSynchronizationObject::GetText() const {
- return tr("[%1] %2")
- .arg(object.GetId())
- .arg(QString::fromStdString(object.GetTypeObj().GetName()));
-}
-
-std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::make(
- const Kernel::KSynchronizationObject& object, Core::System& system) {
- const auto type =
- static_cast<Kernel::KClassTokenGenerator::ObjectType>(object.GetTypeObj().GetClassToken());
- switch (type) {
- case Kernel::KClassTokenGenerator::ObjectType::KReadableEvent:
- return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::KReadableEvent&>(object),
- system);
- case Kernel::KClassTokenGenerator::ObjectType::KThread:
- return std::make_unique<WaitTreeThread>(static_cast<const Kernel::KThread&>(object),
- system);
- default:
- return std::make_unique<WaitTreeSynchronizationObject>(object, system);
- }
-}
-
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeSynchronizationObject::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list;
-
- auto threads = object.GetWaitingThreadsForDebugging();
- if (threads.empty()) {
- list.push_back(std::make_unique<WaitTreeText>(tr("waited by no thread")));
- } else {
- list.push_back(std::make_unique<WaitTreeThreadList>(std::move(threads), system));
- }
-
- return list;
-}
-
-WaitTreeThread::WaitTreeThread(const Kernel::KThread& thread, Core::System& system_)
- : WaitTreeSynchronizationObject(thread, system_), system{system_} {}
-WaitTreeThread::~WaitTreeThread() = default;
-
-QString WaitTreeThread::GetText() const {
- const auto& thread = static_cast<const Kernel::KThread&>(object);
- QString status;
- switch (thread.GetState()) {
- case Kernel::ThreadState::Runnable:
- if (!thread.IsSuspended()) {
- status = tr("runnable");
- } else {
- status = tr("paused");
- }
- break;
- case Kernel::ThreadState::Waiting:
- switch (thread.GetWaitReasonForDebugging()) {
- case Kernel::ThreadWaitReasonForDebugging::Sleep:
- status = tr("sleeping");
- break;
- case Kernel::ThreadWaitReasonForDebugging::IPC:
- status = tr("waiting for IPC reply");
- break;
- case Kernel::ThreadWaitReasonForDebugging::Synchronization:
- status = tr("waiting for objects");
- break;
- case Kernel::ThreadWaitReasonForDebugging::ConditionVar:
- status = tr("waiting for condition variable");
- break;
- case Kernel::ThreadWaitReasonForDebugging::Arbitration:
- status = tr("waiting for address arbiter");
- break;
- case Kernel::ThreadWaitReasonForDebugging::Suspended:
- status = tr("waiting for suspend resume");
- break;
- default:
- status = tr("waiting");
- break;
- }
- break;
- case Kernel::ThreadState::Initialized:
- status = tr("initialized");
- break;
- case Kernel::ThreadState::Terminated:
- status = tr("terminated");
- break;
- default:
- status = tr("unknown");
- break;
- }
-
- const auto& context = thread.GetContext();
- const QString pc_info = tr(" PC = 0x%1 LR = 0x%2")
- .arg(context.pc, 8, 16, QLatin1Char{'0'})
- .arg(context.lr, 8, 16, QLatin1Char{'0'});
- return QStringLiteral("%1%2 (%3) ")
- .arg(WaitTreeSynchronizationObject::GetText(), pc_info, status);
-}
-
-QColor WaitTreeThread::GetColor() const {
- const std::size_t color_index = IsDarkTheme() ? 1 : 0;
-
- const auto& thread = static_cast<const Kernel::KThread&>(object);
- switch (thread.GetState()) {
- case Kernel::ThreadState::Runnable:
- if (!thread.IsSuspended()) {
- return QColor(WaitTreeColors[0][color_index]);
- } else {
- return QColor(WaitTreeColors[2][color_index]);
- }
- case Kernel::ThreadState::Waiting:
- switch (thread.GetWaitReasonForDebugging()) {
- case Kernel::ThreadWaitReasonForDebugging::IPC:
- return QColor(WaitTreeColors[4][color_index]);
- case Kernel::ThreadWaitReasonForDebugging::Sleep:
- return QColor(WaitTreeColors[5][color_index]);
- case Kernel::ThreadWaitReasonForDebugging::Synchronization:
- case Kernel::ThreadWaitReasonForDebugging::ConditionVar:
- case Kernel::ThreadWaitReasonForDebugging::Arbitration:
- case Kernel::ThreadWaitReasonForDebugging::Suspended:
- return QColor(WaitTreeColors[6][color_index]);
- break;
- default:
- return QColor(WaitTreeColors[3][color_index]);
- }
- case Kernel::ThreadState::Initialized:
- return QColor(WaitTreeColors[7][color_index]);
- case Kernel::ThreadState::Terminated:
- return QColor(WaitTreeColors[8][color_index]);
- default:
- return WaitTreeItem::GetColor();
- }
-}
-
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list(WaitTreeSynchronizationObject::GetChildren());
-
- const auto& thread = static_cast<const Kernel::KThread&>(object);
-
- QString processor;
- switch (thread.GetActiveCore()) {
- case Kernel::Svc::IdealCoreUseProcessValue:
- processor = tr("ideal");
- break;
- default:
- processor = tr("core %1").arg(thread.GetActiveCore());
- break;
- }
-
- list.push_back(std::make_unique<WaitTreeText>(tr("processor = %1").arg(processor)));
- list.push_back(std::make_unique<WaitTreeText>(
- tr("affinity mask = %1").arg(thread.GetAffinityMask().GetAffinityMask())));
- list.push_back(std::make_unique<WaitTreeText>(tr("thread id = %1").arg(thread.GetThreadId())));
- list.push_back(std::make_unique<WaitTreeText>(tr("priority = %1(current) / %2(normal)")
- .arg(thread.GetPriority())
- .arg(thread.GetBasePriority())));
- list.push_back(std::make_unique<WaitTreeText>(
- tr("last running ticks = %1").arg(thread.GetLastScheduledTick())));
-
- list.push_back(std::make_unique<WaitTreeCallstack>(thread, system));
-
- return list;
-}
-
-WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_)
- : WaitTreeSynchronizationObject(object_, system_) {}
-WaitTreeEvent::~WaitTreeEvent() = default;
-
-WaitTreeThreadList::WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_)
- : thread_list(std::move(list)), system{system_} {}
-WaitTreeThreadList::~WaitTreeThreadList() = default;
-
-QString WaitTreeThreadList::GetText() const {
- return tr("waited by thread");
-}
-
-std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThreadList::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list(thread_list.size());
- std::transform(thread_list.begin(), thread_list.end(), list.begin(),
- [this](const auto& t) { return std::make_unique<WaitTreeThread>(*t, system); });
- return list;
-}
-
-WaitTreeModel::WaitTreeModel(Core::System& system_, QObject* parent)
- : QAbstractItemModel(parent), system{system_} {}
-WaitTreeModel::~WaitTreeModel() = default;
-
-QModelIndex WaitTreeModel::index(int row, int column, const QModelIndex& parent) const {
- if (!hasIndex(row, column, parent))
- return {};
-
- if (parent.isValid()) {
- WaitTreeItem* parent_item = static_cast<WaitTreeItem*>(parent.internalPointer());
- parent_item->Expand();
- return createIndex(row, column, parent_item->Children()[row].get());
- }
-
- return createIndex(row, column, thread_items[row].get());
-}
-
-QModelIndex WaitTreeModel::parent(const QModelIndex& index) const {
- if (!index.isValid())
- return {};
-
- WaitTreeItem* parent_item = static_cast<WaitTreeItem*>(index.internalPointer())->Parent();
- if (!parent_item) {
- return QModelIndex();
- }
- return createIndex(static_cast<int>(parent_item->Row()), 0, parent_item);
-}
-
-int WaitTreeModel::rowCount(const QModelIndex& parent) const {
- if (!parent.isValid())
- return static_cast<int>(thread_items.size());
-
- WaitTreeItem* parent_item = static_cast<WaitTreeItem*>(parent.internalPointer());
- parent_item->Expand();
- return static_cast<int>(parent_item->Children().size());
-}
-
-int WaitTreeModel::columnCount(const QModelIndex&) const {
- return 1;
-}
-
-QVariant WaitTreeModel::data(const QModelIndex& index, int role) const {
- if (!index.isValid())
- return {};
-
- switch (role) {
- case Qt::DisplayRole:
- return static_cast<WaitTreeItem*>(index.internalPointer())->GetText();
- case Qt::ForegroundRole:
- return static_cast<WaitTreeItem*>(index.internalPointer())->GetColor();
- default:
- return {};
- }
-}
-
-void WaitTreeModel::ClearItems() {
- thread_items.clear();
-}
-
-void WaitTreeModel::InitItems() {
- thread_items = WaitTreeItem::MakeThreadItemList(system);
-}
-
-WaitTreeWidget::WaitTreeWidget(Core::System& system_, QWidget* parent)
- : QDockWidget(tr("&Wait Tree"), parent), system{system_} {
- setObjectName(QStringLiteral("WaitTreeWidget"));
- view = new QTreeView(this);
- view->setHeaderHidden(true);
- setWidget(view);
- setEnabled(false);
-}
-
-WaitTreeWidget::~WaitTreeWidget() = default;
-
-void WaitTreeWidget::OnDebugModeEntered() {
- if (!system.IsPoweredOn())
- return;
- model->InitItems();
- view->setModel(model);
- setEnabled(true);
-}
-
-void WaitTreeWidget::OnDebugModeLeft() {
- setEnabled(false);
- view->setModel(nullptr);
- model->ClearItems();
-}
-
-void WaitTreeWidget::OnEmulationStarting(EmuThread* emu_thread) {
- model = new WaitTreeModel(system, this);
- view->setModel(model);
- setEnabled(false);
-}
-
-void WaitTreeWidget::OnEmulationStopping() {
- view->setModel(nullptr);
- delete model;
- setEnabled(false);
-}
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h
deleted file mode 100644
index 23c329fbe..000000000
--- a/src/yuzu/debugger/wait_tree.h
+++ /dev/null
@@ -1,188 +0,0 @@
-// SPDX-FileCopyrightText: 2016 Citra Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include <cstddef>
-#include <memory>
-#include <vector>
-
-#include <QDockWidget>
-#include <QTreeView>
-
-#include "common/common_types.h"
-#include "core/hle/kernel/k_auto_object.h"
-#include "core/hle/kernel/svc_common.h"
-
-class EmuThread;
-
-namespace Core {
-class System;
-}
-
-namespace Kernel {
-class KHandleTable;
-class KReadableEvent;
-class KSynchronizationObject;
-class KThread;
-} // namespace Kernel
-
-class WaitTreeThread;
-
-class WaitTreeItem : public QObject {
- Q_OBJECT
-public:
- WaitTreeItem();
- ~WaitTreeItem() override;
-
- virtual bool IsExpandable() const;
- virtual std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const;
- virtual QString GetText() const = 0;
- virtual QColor GetColor() const;
-
- void Expand();
- WaitTreeItem* Parent() const;
- const std::vector<std::unique_ptr<WaitTreeItem>>& Children() const;
- std::size_t Row() const;
- static std::vector<std::unique_ptr<WaitTreeThread>> MakeThreadItemList(Core::System& system);
-
-private:
- std::size_t row;
- bool expanded = false;
- WaitTreeItem* parent = nullptr;
- std::vector<std::unique_ptr<WaitTreeItem>> children;
-};
-
-class WaitTreeText : public WaitTreeItem {
- Q_OBJECT
-public:
- explicit WaitTreeText(QString text);
- ~WaitTreeText() override;
-
- QString GetText() const override;
-
-private:
- QString text;
-};
-
-class WaitTreeExpandableItem : public WaitTreeItem {
- Q_OBJECT
-public:
- WaitTreeExpandableItem();
- ~WaitTreeExpandableItem() override;
-
- bool IsExpandable() const override;
-};
-
-class WaitTreeCallstack : public WaitTreeExpandableItem {
- Q_OBJECT
-public:
- explicit WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_);
- ~WaitTreeCallstack() override;
-
- QString GetText() const override;
- std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
-
-private:
- const Kernel::KThread& thread;
-
- Core::System& system;
-};
-
-class WaitTreeSynchronizationObject : public WaitTreeExpandableItem {
- Q_OBJECT
-public:
- explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object_,
- Core::System& system_);
- ~WaitTreeSynchronizationObject() override;
-
- static std::unique_ptr<WaitTreeSynchronizationObject> make(
- const Kernel::KSynchronizationObject& object, Core::System& system);
- QString GetText() const override;
- std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
-
-protected:
- const Kernel::KSynchronizationObject& object;
-
-private:
- Core::System& system;
-};
-
-class WaitTreeThread : public WaitTreeSynchronizationObject {
- Q_OBJECT
-public:
- explicit WaitTreeThread(const Kernel::KThread& thread, Core::System& system_);
- ~WaitTreeThread() override;
-
- QString GetText() const override;
- QColor GetColor() const override;
- std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
-
-private:
- Core::System& system;
-};
-
-class WaitTreeEvent : public WaitTreeSynchronizationObject {
- Q_OBJECT
-public:
- explicit WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_);
- ~WaitTreeEvent() override;
-};
-
-class WaitTreeThreadList : public WaitTreeExpandableItem {
- Q_OBJECT
-public:
- explicit WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_);
- ~WaitTreeThreadList() override;
-
- QString GetText() const override;
- std::vector<std::unique_ptr<WaitTreeItem>> GetChildren() const override;
-
-private:
- std::vector<Kernel::KThread*> thread_list;
-
- Core::System& system;
-};
-
-class WaitTreeModel : public QAbstractItemModel {
- Q_OBJECT
-
-public:
- explicit WaitTreeModel(Core::System& system_, QObject* parent = nullptr);
- ~WaitTreeModel() override;
-
- QVariant data(const QModelIndex& index, int role) const override;
- QModelIndex index(int row, int column, const QModelIndex& parent) const override;
- QModelIndex parent(const QModelIndex& index) const override;
- int rowCount(const QModelIndex& parent) const override;
- int columnCount(const QModelIndex& parent) const override;
-
- void ClearItems();
- void InitItems();
-
-private:
- std::vector<std::unique_ptr<WaitTreeThread>> thread_items;
-
- Core::System& system;
-};
-
-class WaitTreeWidget : public QDockWidget {
- Q_OBJECT
-
-public:
- explicit WaitTreeWidget(Core::System& system_, QWidget* parent = nullptr);
- ~WaitTreeWidget() override;
-
-public slots:
- void OnDebugModeEntered();
- void OnDebugModeLeft();
-
- void OnEmulationStarting(EmuThread* emu_thread);
- void OnEmulationStopping();
-
-private:
- QTreeView* view;
- WaitTreeModel* model;
-
- Core::System& system;
-};