[UI] Loop thread to main thread WindowedAppContext

This commit is contained in:
Triang3l
2021-08-28 19:38:24 +03:00
parent f540c188bf
commit 6ce5330f5f
95 changed files with 2343 additions and 1235 deletions

View File

@@ -49,7 +49,7 @@ std::string D3D12GraphicsSystem::name() const {
X_STATUS D3D12GraphicsSystem::Setup(cpu::Processor* processor,
kernel::KernelState* kernel_state,
ui::Window* target_window) {
provider_ = xe::ui::d3d12::D3D12Provider::Create(target_window);
provider_ = xe::ui::d3d12::D3D12Provider::Create();
auto d3d12_provider = static_cast<xe::ui::d3d12::D3D12Provider*>(provider());
auto device = d3d12_provider->GetDevice();

View File

@@ -7,8 +7,8 @@
******************************************************************************
*/
#include "xenia/base/console_app_main.h"
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
#include "xenia/gpu/trace_dump.h"
@@ -54,6 +54,6 @@ int trace_dump_main(const std::vector<std::string>& args) {
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-d3d12-trace-dump",
xe::gpu::d3d12::trace_dump_main, "some.trace",
"target_trace_file");
XE_DEFINE_CONSOLE_APP("xenia-gpu-d3d12-trace-dump",
xe::gpu::d3d12::trace_dump_main, "some.trace",
"target_trace_file");

View File

@@ -2,13 +2,15 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <memory>
#include <string>
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/gpu/d3d12/d3d12_command_processor.h"
#include "xenia/gpu/d3d12/d3d12_graphics_system.h"
#include "xenia/gpu/trace_viewer.h"
@@ -17,10 +19,13 @@ namespace xe {
namespace gpu {
namespace d3d12 {
using namespace xe::gpu::xenos;
class D3D12TraceViewer : public TraceViewer {
class D3D12TraceViewer final : public TraceViewer {
public:
static std::unique_ptr<WindowedApp> Create(
xe::ui::WindowedAppContext& app_context) {
return std::unique_ptr<WindowedApp>(new D3D12TraceViewer(app_context));
}
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() override {
return std::unique_ptr<gpu::GraphicsSystem>(new D3D12GraphicsSystem());
}
@@ -45,17 +50,15 @@ class D3D12TraceViewer : public TraceViewer {
// TextureInfo/SamplerInfo which are going away.
return 0;
}
};
int trace_viewer_main(const std::vector<std::string>& args) {
D3D12TraceViewer trace_viewer;
return trace_viewer.Main(args);
}
private:
explicit D3D12TraceViewer(xe::ui::WindowedAppContext& app_context)
: TraceViewer(app_context, "xenia-gpu-d3d12-trace-viewer") {}
};
} // namespace d3d12
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-d3d12-trace-viewer",
xe::gpu::d3d12::trace_viewer_main, "some.trace",
"target_trace_file");
XE_DEFINE_WINDOWED_APP(xenia_gpu_d3d12_trace_viewer,
xe::gpu::d3d12::D3D12TraceViewer::Create);

View File

@@ -54,7 +54,7 @@ project("xenia-gpu-d3d12-trace-viewer")
})
files({
"d3d12_trace_viewer_main.cc",
"../../base/main_"..platform_suffix..".cc",
"../../ui/windowed_app_main_"..platform_suffix..".cc",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-d3d12-trace-viewer.vcxproj.user"
@@ -101,7 +101,7 @@ project("xenia-gpu-d3d12-trace-dump")
})
files({
"d3d12_trace_dump_main.cc",
"../../base/main_"..platform_suffix..".cc",
"../../base/console_app_main_"..platform_suffix..".cc",
})
-- Only create the .user file if it doesn't already exist.
local user_file = project_root.."/build/xenia-gpu-d3d12-trace-dump.vcxproj.user"

View File

@@ -18,7 +18,8 @@
#include "xenia/gpu/command_processor.h"
#include "xenia/gpu/gpu_flags.h"
#include "xenia/ui/graphics_provider.h"
#include "xenia/ui/loop.h"
#include "xenia/ui/window.h"
#include "xenia/ui/windowed_app_context.h"
DEFINE_bool(
store_shaders, true,
@@ -57,22 +58,24 @@ X_STATUS GraphicsSystem::Setup(cpu::Processor* processor,
// This must happen on the UI thread.
std::unique_ptr<xe::ui::GraphicsContext> processor_context = nullptr;
if (provider_) {
if (target_window_) {
target_window_->loop()->PostSynchronous([&]() {
// Create the context used for presentation.
assert_null(target_window->context());
target_window_->set_context(provider_->CreateContext(target_window_));
// Setup the context the command processor will do all its drawing in.
// It's shared with the display context so that we can resolve
// framebuffers from it.
processor_context = provider()->CreateOffscreenContext();
});
// Setup the context the command processor will do all its drawing in.
bool contexts_initialized = true;
processor_context = provider()->CreateOffscreenContext();
if (processor_context) {
if (target_window_) {
if (!target_window_->app_context().CallInUIThreadSynchronous([&]() {
// Create the context used for presentation.
assert_null(target_window->context());
target_window_->set_context(
provider_->CreateContext(target_window_));
})) {
contexts_initialized = false;
}
}
} else {
processor_context = provider()->CreateOffscreenContext();
contexts_initialized = false;
}
if (!processor_context) {
if (!contexts_initialized) {
xe::FatalError(
"Unable to initialize graphics context. Xenia requires Vulkan "
"support.\n"

View File

@@ -26,7 +26,7 @@ X_STATUS NullGraphicsSystem::Setup(cpu::Processor* processor,
ui::Window* target_window) {
// This is a null graphics system, but we still setup vulkan because UI needs
// it through us :|
provider_ = xe::ui::vulkan::VulkanProvider::Create(target_window);
provider_ = xe::ui::vulkan::VulkanProvider::Create();
return GraphicsSystem::Setup(processor, kernel_state, target_window);
}

View File

@@ -45,7 +45,7 @@ project("xenia-gpu-shader-compiler")
})
files({
"shader_compiler_main.cc",
"../base/main_"..platform_suffix..".cc",
"../base/console_app_main_"..platform_suffix..".cc",
})
filter("platforms:Windows")

View File

@@ -13,9 +13,9 @@
#include <vector>
#include "xenia/base/assert.h"
#include "xenia/base/console_app_main.h"
#include "xenia/base/cvar.h"
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/base/platform.h"
#include "xenia/base/string.h"
#include "xenia/base/string_buffer.h"
@@ -229,5 +229,6 @@ int shader_compiler_main(const std::vector<std::string>& args) {
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-shader-compiler", xe::gpu::shader_compiler_main,
"shader.bin", "shader_input");
XE_DEFINE_CONSOLE_APP("xenia-gpu-shader-compiler",
xe::gpu::shader_compiler_main, "shader.bin",
"shader_input");

View File

@@ -100,7 +100,7 @@ bool TraceDump::Setup() {
return false;
}
graphics_system_ = emulator_->graphics_system();
player_ = std::make_unique<TracePlayer>(nullptr, graphics_system_);
player_ = std::make_unique<TracePlayer>(graphics_system_);
return true;
}

View File

@@ -17,9 +17,8 @@
namespace xe {
namespace gpu {
TracePlayer::TracePlayer(xe::ui::Loop* loop, GraphicsSystem* graphics_system)
: loop_(loop),
graphics_system_(graphics_system),
TracePlayer::TracePlayer(GraphicsSystem* graphics_system)
: graphics_system_(graphics_system),
current_frame_index_(0),
current_command_index_(-1) {
// Need to allocate all of physical memory so that we can write to it during

View File

@@ -16,7 +16,6 @@
#include "xenia/base/threading.h"
#include "xenia/gpu/trace_protocol.h"
#include "xenia/gpu/trace_reader.h"
#include "xenia/ui/loop.h"
namespace xe {
namespace gpu {
@@ -30,7 +29,7 @@ enum class TracePlaybackMode {
class TracePlayer : public TraceReader {
public:
TracePlayer(xe::ui::Loop* loop, GraphicsSystem* graphics_system);
TracePlayer(GraphicsSystem* graphics_system);
~TracePlayer() override;
GraphicsSystem* graphics_system() const { return graphics_system_; }
@@ -54,7 +53,6 @@ class TracePlayer : public TraceReader {
void PlayTraceOnThread(const uint8_t* trace_data, size_t trace_size,
TracePlaybackMode playback_mode, bool clear_caches);
xe::ui::Loop* loop_;
GraphicsSystem* graphics_system_;
int current_frame_index_;
int current_command_index_;

View File

@@ -2,7 +2,7 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
@@ -13,10 +13,12 @@
#include "third_party/half/include/half.hpp"
#include "third_party/imgui/imgui.h"
#include "xenia/base/assert.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/string.h"
#include "xenia/base/system.h"
#include "xenia/base/threading.h"
#include "xenia/gpu/command_processor.h"
#include "xenia/gpu/gpu_flags.h"
@@ -30,6 +32,7 @@
#include "xenia/ui/imgui_drawer.h"
#include "xenia/ui/virtual_key.h"
#include "xenia/ui/window.h"
#include "xenia/ui/windowed_app_context.h"
#include "xenia/xbox.h"
DEFINE_path(target_trace_file, "", "Specifies the trace file to load.", "GPU");
@@ -46,22 +49,16 @@ static const ImVec4 kColorComment =
static const ImVec4 kColorIgnored =
ImVec4(100 / 255.0f, 100 / 255.0f, 100 / 255.0f, 255 / 255.0f);
TraceViewer::TraceViewer() = default;
TraceViewer::TraceViewer(xe::ui::WindowedAppContext& app_context,
const std::string_view name)
: xe::ui::WindowedApp(app_context, name, "some.trace") {
AddPositionalOption("target_trace_file");
}
TraceViewer::~TraceViewer() = default;
int TraceViewer::Main(const std::vector<std::string>& args) {
// Grab path from the flag or unnamed argument.
std::filesystem::path path;
if (!cvars::target_trace_file.empty()) {
// Passed as a named argument.
// TODO(benvanik): find something better than gflags that supports
// unicode.
path = cvars::target_trace_file;
} else if (args.size() >= 2) {
// Passed as an unnamed argument.
path = xe::to_path(args[1]);
}
bool TraceViewer::OnInitialize() {
std::filesystem::path path = cvars::target_trace_file;
// If no path passed, ask the user.
if (path.empty()) {
@@ -83,42 +80,37 @@ int TraceViewer::Main(const std::vector<std::string>& args) {
}
if (path.empty()) {
xe::FatalError("No trace file specified");
return 1;
xe::ShowSimpleMessageBox(xe::SimpleMessageBoxType::Warning,
"No trace file specified");
return false;
}
// Normalize the path and make absolute.
auto abs_path = std::filesystem::absolute(path);
if (!Setup()) {
xe::FatalError("Unable to setup trace viewer");
return 1;
xe::ShowSimpleMessageBox(xe::SimpleMessageBoxType::Error,
"Unable to setup trace viewer");
return false;
}
if (!Load(std::move(abs_path))) {
xe::FatalError("Unable to load trace file; not found?");
return 1;
xe::ShowSimpleMessageBox(xe::SimpleMessageBoxType::Error,
"Unable to load trace file; not found?");
return false;
}
Run();
return 0;
return true;
}
bool TraceViewer::Setup() {
// Main display window.
loop_ = ui::Loop::Create();
window_ = xe::ui::Window::Create(loop_.get(), "xenia-gpu-trace-viewer");
loop_->PostSynchronous([&]() {
xe::threading::set_name("Win32 Loop");
if (!window_->Initialize()) {
xe::FatalError("Failed to initialize main window");
return;
}
});
window_->on_closed.AddListener([&](xe::ui::UIEvent* e) {
loop_->Quit();
XELOGI("User-initiated death!");
exit(1);
});
loop_->on_quit.AddListener([&](xe::ui::UIEvent* e) { window_.reset(); });
assert_true(app_context().IsInUIThread());
window_ = xe::ui::Window::Create(app_context(), "xenia-gpu-trace-viewer");
if (!window_->Initialize()) {
XELOGE("Failed to initialize main window");
return false;
}
window_->on_closed.AddListener(
[this](xe::ui::UIEvent* e) { app_context().QuitFromUIThread(); });
window_->Resize(1920, 1200);
// Create the emulator but don't initialize so we can setup the window.
@@ -142,9 +134,9 @@ bool TraceViewer::Setup() {
}
});
player_ = std::make_unique<TracePlayer>(loop_.get(), graphics_system_);
player_ = std::make_unique<TracePlayer>(graphics_system_);
window_->on_painting.AddListener([&](xe::ui::UIEvent* e) {
window_->on_painting.AddListener([this](xe::ui::UIEvent* e) {
DrawUI();
// Continuous paint.
@@ -167,16 +159,6 @@ bool TraceViewer::Load(const std::filesystem::path& trace_file_path) {
return true;
}
void TraceViewer::Run() {
// Wait until we are exited.
loop_->AwaitQuit();
player_.reset();
emulator_.reset();
window_.reset();
loop_.reset();
}
void TraceViewer::DrawMultilineString(const std::string_view str) {
size_t i = 0;
bool done = false;

View File

@@ -2,7 +2,7 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
@@ -18,13 +18,8 @@
#include "xenia/gpu/trace_protocol.h"
#include "xenia/gpu/xenos.h"
#include "xenia/memory.h"
namespace xe {
namespace ui {
class Loop;
class Window;
} // namespace ui
} // namespace xe
#include "xenia/ui/window.h"
#include "xenia/ui/windowed_app.h"
namespace xe {
namespace gpu {
@@ -32,14 +27,15 @@ namespace gpu {
struct SamplerInfo;
struct TextureInfo;
class TraceViewer {
class TraceViewer : public xe::ui::WindowedApp {
public:
virtual ~TraceViewer();
int Main(const std::vector<std::string>& args);
bool OnInitialize() override;
protected:
TraceViewer();
explicit TraceViewer(xe::ui::WindowedAppContext& app_context,
const std::string_view name);
virtual std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() = 0;
@@ -60,7 +56,6 @@ class TraceViewer {
virtual bool Setup();
std::unique_ptr<xe::ui::Loop> loop_;
std::unique_ptr<xe::ui::Window> window_;
std::unique_ptr<Emulator> emulator_;
Memory* memory_ = nullptr;
@@ -75,7 +70,6 @@ class TraceViewer {
};
bool Load(const std::filesystem::path& trace_file_path);
void Run();
void DrawUI();
void DrawControllerUI();

View File

@@ -62,7 +62,7 @@ project("xenia-gpu-vulkan-trace-viewer")
})
files({
"vulkan_trace_viewer_main.cc",
"../../base/main_"..platform_suffix..".cc",
"../../ui/windowed_app_main_"..platform_suffix..".cc",
})
filter("platforms:Linux")
@@ -128,7 +128,7 @@ project("xenia-gpu-vulkan-trace-dump")
})
files({
"vulkan_trace_dump_main.cc",
"../../base/main_"..platform_suffix..".cc",
"../../base/console_app_main_"..platform_suffix..".cc",
})
filter("platforms:Linux")

View File

@@ -37,7 +37,7 @@ X_STATUS VulkanGraphicsSystem::Setup(cpu::Processor* processor,
kernel::KernelState* kernel_state,
ui::Window* target_window) {
// Must create the provider so we can create contexts.
auto provider = xe::ui::vulkan::VulkanProvider::Create(target_window);
auto provider = xe::ui::vulkan::VulkanProvider::Create();
device_ = provider->device();
provider_ = std::move(provider);

View File

@@ -7,8 +7,8 @@
******************************************************************************
*/
#include "xenia/base/console_app_main.h"
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/gpu/trace_dump.h"
#include "xenia/gpu/vulkan/vulkan_command_processor.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
@@ -55,6 +55,6 @@ int trace_dump_main(const std::vector<std::string>& args) {
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-vulkan-trace-dump",
xe::gpu::vulkan::trace_dump_main, "some.trace",
"target_trace_file");
XE_DEFINE_CONSOLE_APP("xenia-gpu-vulkan-trace-dump",
xe::gpu::vulkan::trace_dump_main, "some.trace",
"target_trace_file");

View File

@@ -2,13 +2,15 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include <memory>
#include <string>
#include "xenia/base/logging.h"
#include "xenia/base/main.h"
#include "xenia/gpu/trace_viewer.h"
#include "xenia/gpu/vulkan/vulkan_command_processor.h"
#include "xenia/gpu/vulkan/vulkan_graphics_system.h"
@@ -19,8 +21,13 @@ namespace vulkan {
using namespace xe::gpu::xenos;
class VulkanTraceViewer : public TraceViewer {
class VulkanTraceViewer final : public TraceViewer {
public:
static std::unique_ptr<WindowedApp> Create(
xe::ui::WindowedAppContext& app_context) {
return std::unique_ptr<WindowedApp>(new VulkanTraceViewer(app_context));
}
std::unique_ptr<gpu::GraphicsSystem> CreateGraphicsSystem() override {
return std::unique_ptr<gpu::GraphicsSystem>(new VulkanGraphicsSystem());
}
@@ -60,17 +67,15 @@ class VulkanTraceViewer : public TraceViewer {
// return static_cast<uintptr_t>(texture->handle);
return 0;
}
};
int trace_viewer_main(const std::vector<std::string>& args) {
VulkanTraceViewer trace_viewer;
return trace_viewer.Main(args);
}
private:
explicit VulkanTraceViewer(xe::ui::WindowedAppContext& app_context)
: TraceViewer(app_context, "xenia-gpu-vulkan-trace-viewer") {}
};
} // namespace vulkan
} // namespace gpu
} // namespace xe
DEFINE_ENTRY_POINT("xenia-gpu-vulkan-trace-viewer",
xe::gpu::vulkan::trace_viewer_main, "some.trace",
"target_trace_file");
XE_DEFINE_WINDOWED_APP(xenia_gpu_vulkan_trace_viewer,
xe::gpu::vulkan::VulkanTraceViewer::Create);