[UI] Image post-processing and full presentation/window rework

[GPU] Add FXAA post-processing
[UI] Add FidelityFX FSR and CAS post-processing
[UI] Add blue noise dithering from 10bpc to 8bpc
[GPU] Apply the DC PWL gamma ramp closer to the spec, supporting fully white color
[UI] Allow the GPU CP thread to present on the host directly, bypassing the UI thread OS paint event
[UI] Allow variable refresh rate (or tearing)
[UI] Present the newest frame (restart) on DXGI
[UI] Replace GraphicsContext with a far more advanced Presenter with more coherent surface connection and UI overlay state management
[UI] Connect presentation to windows via the Surface class, not native window handles
[Vulkan] Switch to simpler Vulkan setup with no instance/device separation due to interdependencies and to pass fewer objects around
[Vulkan] Lower the minimum required Vulkan version to 1.0
[UI/GPU] Various cleanup, mainly ComPtr usage
[UI] Support per-monitor DPI awareness v2 on Windows
[UI] DPI-scale Dear ImGui
[UI] Replace the remaining non-detachable window delegates with unified window event and input listeners
[UI] Allow listeners to safely destroy or close the window, and to register/unregister listeners without use-after-free and the ABA problem
[UI] Explicit Z ordering of input listeners and UI overlays, top-down for input, bottom-up for drawing
[UI] Add explicit window lifecycle phases
[UI] Replace Window virtual functions with explicit desired state, its application, actual state, its feedback
[UI] GTK: Apply the initial size to the drawing area
[UI] Limit internal UI frame rate to that of the monitor
[UI] Hide the cursor using a timer instead of polling due to no repeated UI thread paints with GPU CP thread presentation, and only within the window
This commit is contained in:
Triang3l
2022-01-29 13:22:03 +03:00
parent 372bdd3ec9
commit fe3f0f26e4
428 changed files with 75942 additions and 18360 deletions

View File

@@ -2,7 +2,7 @@
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Copyright 2022 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
@@ -13,42 +13,124 @@
#include <memory>
#include <string>
#include "xenia/emulator.h"
#include "xenia/gpu/command_processor.h"
#include "xenia/ui/imgui_dialog.h"
#include "xenia/ui/imgui_drawer.h"
#include "xenia/ui/immediate_drawer.h"
#include "xenia/ui/menu_item.h"
#include "xenia/ui/presenter.h"
#include "xenia/ui/window.h"
#include "xenia/ui/window_listener.h"
#include "xenia/ui/windowed_app_context.h"
#include "xenia/xbox.h"
namespace xe {
class Emulator;
} // namespace xe
namespace xe {
namespace app {
class EmulatorWindow {
public:
enum : size_t {
// The UI is on top of the game and is open in special cases, so
// lowest-priority.
kZOrderHidInput,
kZOrderImGui,
kZOrderProfiler,
// Emulator window controls are expected to be always accessible by the
// user, so highest-priority.
kZOrderEmulatorWindowInput,
};
virtual ~EmulatorWindow();
static std::unique_ptr<EmulatorWindow> Create(
Emulator* emulator, ui::WindowedAppContext& app_context);
Emulator* emulator() const { return emulator_; }
ui::WindowedAppContext& app_context() const { return app_context_; }
ui::Window* window() const { return window_.get(); }
ui::ImGuiDrawer* imgui_drawer() const { return imgui_drawer_.get(); }
ui::Presenter* GetGraphicsSystemPresenter() const;
void SetupGraphicsSystemPresenterPainting();
void ShutdownGraphicsSystemPresenterPainting();
void OnEmulatorInitialized();
void UpdateTitle();
void SetFullscreen(bool fullscreen);
void ToggleFullscreen();
void SetInitializingShaderStorage(bool initializing);
private:
class EmulatorWindowListener final : public ui::WindowListener,
public ui::WindowInputListener {
public:
explicit EmulatorWindowListener(EmulatorWindow& emulator_window)
: emulator_window_(emulator_window) {}
void OnClosing(ui::UIEvent& e) override;
void OnFileDrop(ui::FileDropEvent& e) override;
void OnKeyDown(ui::KeyEvent& e) override;
private:
EmulatorWindow& emulator_window_;
};
class DisplayConfigGameConfigLoadCallback
: public Emulator::GameConfigLoadCallback {
public:
DisplayConfigGameConfigLoadCallback(Emulator& emulator,
EmulatorWindow& emulator_window)
: Emulator::GameConfigLoadCallback(emulator),
emulator_window_(emulator_window) {}
void PostGameConfigLoad() override;
private:
EmulatorWindow& emulator_window_;
};
class DisplayConfigDialog final : public ui::ImGuiDialog {
public:
DisplayConfigDialog(ui::ImGuiDrawer* imgui_drawer,
EmulatorWindow& emulator_window)
: ui::ImGuiDialog(imgui_drawer), emulator_window_(emulator_window) {}
protected:
void OnDraw(ImGuiIO& io) override;
private:
EmulatorWindow& emulator_window_;
};
explicit EmulatorWindow(Emulator* emulator,
ui::WindowedAppContext& app_context);
bool Initialize();
// For comparisons, use GetSwapPostEffectForCvarValue instead as the default
// fallback may be used for multiple values.
static const char* GetCvarValueForSwapPostEffect(
gpu::CommandProcessor::SwapPostEffect effect);
static gpu::CommandProcessor::SwapPostEffect GetSwapPostEffectForCvarValue(
const std::string& cvar_value);
// For comparisons, use GetGuestOutputPaintEffectForCvarValue instead as the
// default fallback may be used for multiple values.
static const char* GetCvarValueForGuestOutputPaintEffect(
ui::Presenter::GuestOutputPaintConfig::Effect effect);
static ui::Presenter::GuestOutputPaintConfig::Effect
GetGuestOutputPaintEffectForCvarValue(const std::string& cvar_value);
static ui::Presenter::GuestOutputPaintConfig
GetGuestOutputPaintConfigForCvars();
void ApplyDisplayConfigForCvars();
void OnKeyDown(ui::KeyEvent& e);
void FileDrop(const std::filesystem::path& filename);
void FileOpen();
void FileClose();
void ShowContentDirectory();
void CheckHideCursor();
void CpuTimeScalarReset();
void CpuTimeScalarSetHalf();
void CpuTimeScalarSetDouble();
@@ -56,15 +138,26 @@ class EmulatorWindow {
void CpuBreakIntoHostDebugger();
void GpuTraceFrame();
void GpuClearCaches();
void ToggleDisplayConfigDialog();
void ShowHelpWebsite();
void ShowCommitID();
Emulator* emulator_;
ui::WindowedAppContext& app_context_;
EmulatorWindowListener window_listener_;
std::unique_ptr<ui::Window> window_;
std::unique_ptr<ui::ImGuiDrawer> imgui_drawer_;
std::unique_ptr<DisplayConfigGameConfigLoadCallback>
display_config_game_config_load_callback_;
// Creation may fail, in this case immediate drawer UI must not be drawn.
std::unique_ptr<ui::ImmediateDrawer> immediate_drawer_;
bool emulator_initialized_ = false;
std::string base_title_;
uint64_t cursor_hide_time_ = 0;
bool initializing_shader_storage_ = false;
std::unique_ptr<DisplayConfigDialog> display_config_dialog_;
};
} // namespace app