openMSX
PostProcessor.hh
Go to the documentation of this file.
1#ifndef GLPOSTPROCESSOR_HH
2#define GLPOSTPROCESSOR_HH
3
4#include "EmuTime.hh"
5#include "GLUtil.hh"
6#include "RenderSettings.hh"
7#include "Schedulable.hh"
8#include "VideoLayer.hh"
9#include <array>
10#include <memory>
11#include <vector>
12
13namespace openmsx {
14
15class AviRecorder;
16class CliComm;
17class Deflicker;
18class DeinterlacedFrame;
19class Display;
20class DoubledFrame;
21class EventDistributor;
22class FrameSource;
23class GLScaler;
24class MSXMotherBoard;
25class RawFrame;
26class RenderSettings;
27class SuperImposedFrame;
28
32class PostProcessor final : public VideoLayer, private Schedulable
33{
34public:
36 MSXMotherBoard& motherBoard, Display& display,
37 OutputSurface& screen, const std::string& videoSource,
38 unsigned maxWidth, unsigned height, bool canDoInterlace);
39 ~PostProcessor() override;
40
41 // Layer interface:
42 void paint(OutputSurface& output) override;
43
54 [[nodiscard]] std::unique_ptr<RawFrame> rotateFrames(
55 std::unique_ptr<RawFrame> finishedFrame, EmuTime::param time);
56
63 void setSuperimposeVideoFrame(const RawFrame* videoSource) {
64 superImposeVideoFrame = videoSource;
65 }
66
72 void setSuperimposeVdpFrame(const FrameSource* vdpSource) {
73 superImposeVdpFrame = vdpSource;
74 }
75
81 void setRecorder(AviRecorder* recorder_) { recorder = recorder_; }
82
86 [[nodiscard]] bool isRecording() const { return recorder != nullptr; }
87
92 [[nodiscard]] FrameSource* getPaintFrame() const { return paintFrame; }
93
94 // VideoLayer
95 void takeRawScreenShot(unsigned height, const std::string& filename) override;
96
97 [[nodiscard]] CliComm& getCliComm();
98
99private:
100 // Observer<Setting> interface:
101 void update(const Setting& setting) noexcept override;
102
103 // Schedulable
104 void executeUntil(EmuTime::param time) override;
105
108 [[nodiscard]] static unsigned getLineWidth(FrameSource* frame, unsigned y, unsigned step);
109
110 void initBuffers();
111 void createRegions();
112 void uploadFrame();
113 void uploadBlock(unsigned srcStartY, unsigned srcEndY,
114 unsigned lineWidth);
115
116 void preCalcNoise(float factor);
117 void drawNoise();
118 void drawGlow(int glow);
119
120 void preCalcMonitor3D(float width);
121 void drawMonitor3D();
122
123private:
124 Display& display;
125 RenderSettings& renderSettings;
126 EventDistributor& eventDistributor;
127
129 OutputSurface& screen;
130
132 std::array<std::unique_ptr<RawFrame>, 4> lastFrames;
133
135 std::unique_ptr<DeinterlacedFrame> deinterlacedFrame;
136
138 std::unique_ptr<DoubledFrame> interlacedFrame;
139
141 std::unique_ptr<Deflicker> deflicker;
142
144 std::unique_ptr<SuperImposedFrame> superImposedFrame;
145
150 FrameSource* paintFrame = nullptr;
151
153 AviRecorder* recorder = nullptr;
154
157 const RawFrame* superImposeVideoFrame = nullptr;
158 const FrameSource* superImposeVdpFrame = nullptr;
159
160 int interleaveCount = 0; // for interleave-black-frame
161 int lastFramesCount = 0; // How many items in lastFrames[] are up-to-date
162 unsigned maxWidth; // we lazily create RawFrame objects in lastFrames[]
163 unsigned height; // these two vars remember how big those should be
164
169 const bool canDoInterlace;
170
171 EmuTime lastRotate;
174 std::unique_ptr<GLScaler> currScaler;
175
176 struct StoredFrame {
177 gl::ivec2 size; // (re)allocate when window size changes
178 gl::Texture tex;
180 };
181 std::array<StoredFrame, 2> renderedFrames;
182
183 // Noise effect:
184 gl::Texture noiseTextureA{true, true}; // interpolate + wrap
185 gl::Texture noiseTextureB{true, true};
186 float noiseX = 0.0f, noiseY = 0.0f;
187
188 struct TextureData {
191 [[nodiscard]] unsigned width() const { return tex.getWidth(); }
192 };
193 std::vector<TextureData> textures;
194
195 gl::ColorTexture superImposeTex;
196
197 struct Region {
198 Region(unsigned srcStartY_, unsigned srcEndY_,
199 unsigned dstStartY_, unsigned dstEndY_,
200 unsigned lineWidth_)
201 : srcStartY(srcStartY_)
202 , srcEndY(srcEndY_)
203 , dstStartY(dstStartY_)
204 , dstEndY(dstEndY_)
205 , lineWidth(lineWidth_) {}
206 unsigned srcStartY;
207 unsigned srcEndY;
208 unsigned dstStartY;
209 unsigned dstEndY;
210 unsigned lineWidth;
211 };
212 std::vector<Region> regions;
213
214 unsigned frameCounter = 0;
215
219
220 gl::ShaderProgram monitor3DProg;
221 gl::BufferObject arrayBuffer;
222 gl::BufferObject elementBuffer;
224 gl::BufferObject stretchVBO;
225
226 bool storedFrame = false;
227};
228
229} // namespace openmsx
230
231#endif // GLPOSTPROCESSOR_HH
BaseSetting * setting
GLsizei getWidth() const
Definition GLUtil.hh:106
Wrapper around a pixel buffer.
Definition GLUtil.hh:148
Wrapper around an OpenGL program: a collection of vertex and fragment shaders.
Definition GLUtil.hh:383
Most basic/generic texture: only contains a texture ID.
Definition GLUtil.hh:36
Represents the output window/screen of openMSX.
Definition Display.hh:32
Interface for getting lines from a video frame.
A frame buffer where pixels can be written to.
A post processor builds the frame that is displayed from the MSX frame, while applying effects such a...
std::unique_ptr< RawFrame > rotateFrames(std::unique_ptr< RawFrame > finishedFrame, EmuTime::param time)
Sets up the "abcdFrame" variables for a new frame.
void takeRawScreenShot(unsigned height, const std::string &filename) override
Create a raw (=non-post-processed) screenshot.
void paint(OutputSurface &output) override
Paint this layer.
void setRecorder(AviRecorder *recorder_)
Start/stop recording.
void setSuperimposeVdpFrame(const FrameSource *vdpSource)
Set the VDP frame on which to superimpose the 'normal' output of this PostProcessor.
bool isRecording() const
Is recording active.
FrameSource * getPaintFrame() const
Get the frame that would be displayed.
void setSuperimposeVideoFrame(const RawFrame *videoSource)
Set the Video frame on which to superimpose the 'normal' output of this PostProcessor.
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
Definition RawFrame.hh:15
Class containing all settings for renderers.
ScaleAlgorithm
Scaler algorithm.
Every class that wants to get scheduled at some point must inherit from this class.
This file implemented 3 utility functions:
Definition Autofire.cc:9