OXYGENHUB
◆ main openmsx / src / video / Display.hh
4.2 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef DISPLAY_HH
2
#define DISPLAY_HH
3
4
#include "RenderSettings.hh"
5
6
#include "Command.hh"
7
#include "EventListener.hh"
8
#include "InfoTopic.hh"
9
#include "OSDGUI.hh"
10
#include "RTSchedulable.hh"
11
12
#include "CircularBuffer.hh"
13
#include "Observer.hh"
14
15
#include <cstdint>
16
#include <memory>
17
#include <optional>
18
#include <vector>
19
20
namespace openmsx {
21
22
class Layer;
23
class Reactor;
24
class VideoSystem;
25
class CliComm;
26
class VideoSystemChangeListener;
27
class Setting;
28
class OutputSurface;
29
30
/** Represents the output window/screen of openMSX.
31
  * A display contains several layers.
32
  */
33
class Display final : public EventListener, private Observer<Setting>
34
                    , private RTSchedulable
35
{
36
public:
37
	static constexpr std::string_view SCREENSHOT_DIR = "screenshots";
38
	static constexpr std::string_view SCREENSHOT_EXTENSION = ".png";
39
40
public:
41
	using Layers = std::vector<Layer*>;
42
43
	explicit Display(Reactor& reactor);
44
	~Display();
45
46
	void createVideoSystem();
47
	[[nodiscard]] VideoSystem& getVideoSystem();
48
49
	[[nodiscard]] CliComm& getCliComm() const;
50
	[[nodiscard]] RenderSettings& getRenderSettings() { return renderSettings; }
51
	[[nodiscard]] auto getRenderer() const { return currentRenderer; }
52
	[[nodiscard]] OSDGUI& getOSDGUI() { return osdGui; }
53
54
	/** Redraw the display.
55
	  * The repaintImpl() methods are for internal and VideoSystem/VisibleSurface use only.
56
	  */
57
	void repaint();
58
	void repaintDelayed(uint64_t delta);
59
	void repaintImpl();
60
	void repaintImpl(OutputSurface& surface);
61
62
	void addLayer(Layer& layer);
63
	void removeLayer(Layer& layer);
64
	void updateZ(Layer& layer);
65
66
	void attach(VideoSystemChangeListener& listener);
67
	void detach(VideoSystemChangeListener& listener);
68
69
	[[nodiscard]] Layer* findActiveLayer() const;
70
	[[nodiscard]] const Layers& getAllLayers() const { return layers; }
71
72
	[[nodiscard]] OutputSurface* getOutputSurface();
73
74
	/** Returns the size of a single MSX pixel as it is currently drawn on
75
	  * screen, expressed in the same units as the host mouse coordinates.
76
	  * Returns std::nullopt when there's no window to draw on. */
77
	[[nodiscard]] std::optional<gl::vec2> getMsxPixelSize();
78
79
	[[nodiscard]] std::string getWindowTitle();
80
81
	/** Get/set x,y coordinates of top-left window corner.
82
	    Either the actual, or the last known coordinates. */
83
	[[nodiscard]] gl::ivec2 getWindowPosition();
84
	void setWindowPosition(gl::ivec2 pos);
85
	// should only be called from VisibleSurface
86
	void storeWindowPosition(gl::ivec2 pos);
87
	[[nodiscard]] gl::ivec2 retrieveWindowPosition();
88
89
	[[nodiscard]] gl::ivec2 getWindowSize() const;
90
91
	// Get the latest fps value
92
	[[nodiscard]] float getFps() const;
93
94
private:
95
	void resetVideoSystem();
96
97
	// EventListener interface
98
	bool signalEvent(const Event& event) override;
99
100
	// RTSchedulable
101
	void executeRT() override;
102
103
	// Observer<Setting> interface
104
	void update(const Setting& setting) noexcept override;
105
106
	void checkRendererSwitch();
107
	void doRendererSwitch(RenderSettings::RendererID newRenderer);
108
	void doRendererSwitch2(RenderSettings::RendererID newRenderer);
109
110
	/** Find front most opaque layer.
111
	  */
112
	[[nodiscard]] Layers::iterator baseLayer();
113
114
private:
115
	Layers layers; // sorted on z
116
	std::unique_ptr<VideoSystem> videoSystem;
117
118
	std::vector<VideoSystemChangeListener*> listeners; // unordered
119
120
	// fps related data
121
	static constexpr unsigned NUM_FRAME_DURATIONS = 50;
122
	CircularBuffer<uint64_t, NUM_FRAME_DURATIONS> frameDurations;
123
	uint64_t frameDurationSum;
124
	uint64_t prevTimeStamp;
125
126
	struct ScreenShotCmd final : Command {
127
		explicit ScreenShotCmd(CommandController& commandController);
128
		void execute(std::span<const TclObject> tokens, TclObject& result) override;
129
		[[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
130
	} screenShotCmd;
131
132
	struct FpsInfoTopic final : InfoTopic {
133
		explicit FpsInfoTopic(InfoCommand& openMSXInfoCommand);
134
		void execute(std::span<const TclObject> tokens,
135
			     TclObject& result) const override;
136
		[[nodiscard]] std::string help(std::span<const TclObject> tokens) const override;
137
	} fpsInfo;
138
139
	OSDGUI osdGui;
140
141
	Reactor& reactor;
142
	RenderSettings renderSettings;
143
144
	// the current renderer
145
	RenderSettings::RendererID currentRenderer = RenderSettings::RendererID::UNINITIALIZED;
146
147
	bool renderFrozen = false;
148
	bool switchInProgress = false;
149
};
150
151
} // namespace openmsx
152
153
#endif