-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
HostDisplay.h
169 lines (133 loc) · 6.04 KB
/
HostDisplay.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/Pcsx2Defs.h"
#include "common/WindowInfo.h"
#include <memory>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>
#include "Host.h"
#include "Config.h"
/// An abstracted RGBA8 texture.
class HostDisplayTexture
{
public:
virtual ~HostDisplayTexture();
virtual void* GetHandle() const = 0;
virtual u32 GetWidth() const = 0;
virtual u32 GetHeight() const = 0;
};
/// Interface to the frontend's renderer.
class HostDisplay
{
public:
enum class RenderAPI
{
None,
D3D11,
Vulkan,
OpenGL,
OpenGLES
};
enum class Alignment
{
LeftOrTop,
Center,
RightOrBottom
};
struct AdapterAndModeList
{
std::vector<std::string> adapter_names;
std::vector<std::string> fullscreen_modes;
};
virtual ~HostDisplay();
/// Returns a string representing the specified API.
static const char* RenderAPIToString(RenderAPI api);
/// Creates a display for the specified API.
static std::unique_ptr<HostDisplay> CreateDisplayForAPI(RenderAPI api);
/// Parses a fullscreen mode into its components (width * height @ refresh hz)
static bool ParseFullscreenMode(const std::string_view& mode, u32* width, u32* height, float* refresh_rate);
/// Converts a fullscreen mode to a string.
static std::string GetFullscreenModeString(u32 width, u32 height, float refresh_rate);
__fi const WindowInfo& GetWindowInfo() const { return m_window_info; }
__fi s32 GetWindowWidth() const { return static_cast<s32>(m_window_info.surface_width); }
__fi s32 GetWindowHeight() const { return static_cast<s32>(m_window_info.surface_height); }
__fi float GetWindowScale() const { return m_window_info.surface_scale; }
/// Changes the alignment for this display (screen positioning).
__fi Alignment GetDisplayAlignment() const { return m_display_alignment; }
__fi void SetDisplayAlignment(Alignment alignment) { m_display_alignment = alignment; }
virtual RenderAPI GetRenderAPI() const = 0;
virtual void* GetRenderDevice() const = 0;
virtual void* GetRenderContext() const = 0;
virtual void* GetRenderSurface() const = 0;
virtual bool HasRenderDevice() const = 0;
virtual bool HasRenderSurface() const = 0;
virtual bool CreateRenderDevice(const WindowInfo& wi, std::string_view adapter_name, bool threaded_presentation, bool debug_device) = 0;
virtual bool InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device) = 0;
virtual bool MakeRenderContextCurrent() = 0;
virtual bool DoneRenderContextCurrent() = 0;
virtual void DestroyRenderDevice() = 0;
virtual void DestroyRenderSurface() = 0;
virtual bool ChangeRenderWindow(const WindowInfo& wi) = 0;
virtual bool SupportsFullscreen() const = 0;
virtual bool IsFullscreen() = 0;
virtual bool SetFullscreen(bool fullscreen, u32 width, u32 height, float refresh_rate) = 0;
virtual AdapterAndModeList GetAdapterAndModeList() = 0;
virtual std::string GetDriverInfo() const = 0;
/// Call when the window size changes externally to recreate any resources.
virtual void ResizeRenderWindow(s32 new_window_width, s32 new_window_height, float new_window_scale) = 0;
/// Creates an abstracted RGBA8 texture. If dynamic, the texture can be updated with UpdateTexture() below.
virtual std::unique_ptr<HostDisplayTexture> CreateTexture(u32 width, u32 height, const void* data, u32 data_stride, bool dynamic = false) = 0;
virtual void UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, u32 width, u32 height, const void* data, u32 data_stride) = 0;
/// Returns false if the window was completely occluded. If frame_skip is set, the frame won't be
/// displayed, but the GPU command queue will still be flushed.
virtual bool BeginPresent(bool frame_skip) = 0;
/// Presents the frame to the display, and renders OSD elements.
virtual void EndPresent() = 0;
/// Changes vsync mode for this display.
virtual void SetVSync(VsyncMode mode) = 0;
/// ImGui context management, usually called by derived classes.
virtual bool CreateImGuiContext() = 0;
virtual void DestroyImGuiContext() = 0;
virtual bool UpdateImGuiFontTexture() = 0;
/// Returns the effective refresh rate of this display.
virtual bool GetHostRefreshRate(float* refresh_rate);
/// Returns true if it's an OpenGL-based renderer.
bool UsesLowerLeftOrigin() const;
protected:
WindowInfo m_window_info;
Alignment m_display_alignment = Alignment::Center;
};
namespace Host
{
/// Creates the host display. This may create a new window. The API used depends on the current configuration.
HostDisplay* AcquireHostDisplay(HostDisplay::RenderAPI api);
/// Destroys the host display. This may close the display window.
void ReleaseHostDisplay();
/// Returns a pointer to the current host display abstraction. Assumes AcquireHostDisplay() has been caled.
HostDisplay* GetHostDisplay();
/// Returns false if the window was completely occluded. If frame_skip is set, the frame won't be
/// displayed, but the GPU command queue will still be flushed.
bool BeginPresentFrame(bool frame_skip);
/// Presents the frame to the display, and renders OSD elements.
void EndPresentFrame();
/// Called on the MTGS thread when a resize request is received.
void ResizeHostDisplay(u32 new_window_width, u32 new_window_height, float new_window_scale);
/// Called on the MTGS thread when a request to update the display is received.
/// This could be a fullscreen transition, for example.
void UpdateHostDisplay();
} // namespace Host