citra_qt: Add record dialog

This 'View Record' dialog shows all relevant information on a record as well as the command buffers.
This commit is contained in:
zhupengfei 2019-07-22 20:47:47 +08:00
parent f40232adc9
commit 45930e0621
4 changed files with 384 additions and 0 deletions

View file

@ -90,6 +90,9 @@ add_executable(citra-qt
debugger/graphics/graphics_tracing.h debugger/graphics/graphics_tracing.h
debugger/graphics/graphics_vertex_shader.cpp debugger/graphics/graphics_vertex_shader.cpp
debugger/graphics/graphics_vertex_shader.h debugger/graphics/graphics_vertex_shader.h
debugger/ipc/record_dialog.cpp
debugger/ipc/record_dialog.h
debugger/ipc/record_dialog.ui
debugger/lle_service_modules.cpp debugger/lle_service_modules.cpp
debugger/lle_service_modules.h debugger/lle_service_modules.h
debugger/profiler.cpp debugger/profiler.cpp

View file

@ -0,0 +1,64 @@
// Copyright 2019 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <fmt/format.h>
#include "citra_qt/debugger/ipc/record_dialog.h"
#include "common/assert.h"
#include "core/hle/kernel/ipc_debugger/recorder.h"
#include "ui_record_dialog.h"
QString RecordDialog::FormatObject(const IPCDebugger::ObjectInfo& object) const {
if (object.id == -1) {
return tr("null");
}
return QStringLiteral("%1 (0x%2)")
.arg(QString::fromStdString(object.name))
.arg(object.id, 8, 16, QLatin1Char('0'));
}
QString RecordDialog::FormatCmdbuf(const std::vector<u32>& cmdbuf) const {
QString result;
for (std::size_t i = 0; i < cmdbuf.size(); ++i) {
result.append(
QStringLiteral("[%1]: 0x%2\n").arg(i).arg(cmdbuf[i], 8, 16, QLatin1Char('0')));
}
return result;
}
RecordDialog::RecordDialog(QWidget* parent, const IPCDebugger::RequestRecord& record,
const QString& service, const QString& function)
: QDialog(parent), ui(std::make_unique<Ui::RecordDialog>()) {
ui->setupUi(this);
ui->clientProcess->setText(FormatObject(record.client_process));
ui->clientThread->setText(FormatObject(record.client_thread));
ui->clientSession->setText(FormatObject(record.client_session));
ui->serverProcess->setText(FormatObject(record.server_process));
ui->serverThread->setText(FormatObject(record.server_thread));
ui->serverSession->setText(FormatObject(record.server_session));
ui->clientPort->setText(FormatObject(record.client_port));
ui->service->setText(std::move(service));
ui->function->setText(std::move(function));
cmdbufs = {record.untranslated_request_cmdbuf, record.translated_request_cmdbuf,
record.untranslated_reply_cmdbuf, record.translated_reply_cmdbuf};
UpdateCmdbufDisplay();
connect(ui->cmdbufSelection, qOverload<int>(&QComboBox::currentIndexChanged), this,
&RecordDialog::UpdateCmdbufDisplay);
}
RecordDialog::~RecordDialog() = default;
void RecordDialog::UpdateCmdbufDisplay() {
int index = ui->cmdbufSelection->currentIndex();
ASSERT_MSG(0 <= index && index <= 3, "Index out of bound");
ui->cmdbuf->setPlainText(FormatCmdbuf(cmdbufs[index]));
}

View file

@ -0,0 +1,36 @@
// Copyright 2019 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <array>
#include <memory>
#include <string>
#include <vector>
#include <QDialog>
#include "common/common_types.h"
namespace IPCDebugger {
struct ObjectInfo;
struct RequestRecord;
} // namespace IPCDebugger
namespace Ui {
class RecordDialog;
}
class RecordDialog : public QDialog {
Q_OBJECT
public:
explicit RecordDialog(QWidget* parent, const IPCDebugger::RequestRecord& record,
const QString& service, const QString& function);
~RecordDialog() override;
private:
QString FormatObject(const IPCDebugger::ObjectInfo& object) const;
QString FormatCmdbuf(const std::vector<u32>& cmdbuf) const;
void UpdateCmdbufDisplay();
std::unique_ptr<Ui::RecordDialog> ui;
std::array<std::vector<u32>, 4> cmdbufs;
};

View file

@ -0,0 +1,281 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RecordDialog</class>
<widget class="QDialog" name="RecordDialog">
<property name="windowTitle">
<string>View Record</string>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>500</height>
</rect>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QGroupBox">
<property name="title">
<string>Client</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Process:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="clientProcess">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Thread:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="clientThread">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Session:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="clientSession">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox">
<property name="title">
<string>Server</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Process:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="serverProcess">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Thread:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="serverThread">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Session:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="serverSession">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox">
<property name="title">
<string>General</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Client Port:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="clientPort">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Service:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="service">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Function:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="function">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox">
<property name="title">
<string>Command Buffer</string>
</property>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel">
<property name="text">
<string>Select:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmdbufSelection">
<item>
<property name="text">
<string>Request Untranslated</string>
</property>
</item>
<item>
<property name="text">
<string>Request Translated</string>
</property>
</item>
<item>
<property name="text">
<string>Reply Untranslated</string>
</property>
</item>
<item>
<property name="text">
<string>Reply Translated</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QPlainTextEdit" name="cmdbuf">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="okButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</ui>