openMSX
PostProcessor.hh
Go to the documentation of this file.
1#ifndef GLPOSTPROCESSOR_HH
2#define GLPOSTPROCESSOR_HH
3
4#include "GLUtil.hh"
5#include "RenderSettings.hh"
6#include "VideoLayer.hh"
7
8#include "EmuTime.hh"
9#include "Schedulable.hh"
10
11#include <array>
12#include <memory>
13#include <vector>
14
15namespace openmsx {
16
17class AviRecorder;
18class CliComm;
19class Deflicker;
20class DeinterlacedFrame;
21class Display;
22class DoubledFrame;
23class EventDistributor;
24class FrameSource;
25class GLScaler;
26class MSXMotherBoard;
27class RawFrame;
28class RenderSettings;
29class SuperImposedFrame;
30
34class PostProcessor final : public VideoLayer, private Schedulable
35{
36public:
38 MSXMotherBoard& motherBoard, Display& display,
39 OutputSurface& screen, const std::string& videoSource,
40 unsigned maxWidth, unsigned height, bool canDoInterlace);
41 ~PostProcessor() override;
42
43 // Layer interface:
44 void paint(OutputSurface& output) override;
45
56 [[nodiscard]] std::unique_ptr<RawFrame> rotateFrames(
57 std::unique_ptr<RawFrame> finishedFrame, EmuTime::param time);
58
65 void setSuperimposeVideoFrame(const RawFrame* videoSource) {
66 superImposeVideoFrame = videoSource;
67 }
68
74 void setSuperimposeVdpFrame(const FrameSource* vdpSource) {
75 superImposeVdpFrame = vdpSource;
76 }
77
83 void setRecorder(AviRecorder* recorder_) { recorder = recorder_; }
84
88 [[nodiscard]] bool isRecording() const { return recorder != nullptr; }
89
94 [[nodiscard]] FrameSource* getPaintFrame() const { return paintFrame; }
95
96 // VideoLayer
97 void takeRawScreenShot(unsigned height, const std::string& filename) override;
98
99 [[nodiscard]] CliComm& getCliComm();
100
101private:
102 // Observer<Setting> interface:
103 void update(const Setting& setting) noexcept override;
104
105 // Schedulable
106 void executeUntil(EmuTime::param time) override;
107
110 [[nodiscard]] static unsigned getLineWidth(FrameSource* frame, unsigned y, unsigned step);
111
112 void initBuffers();
113 void createRegions();
114 void uploadFrame();
115 void uploadBlock(unsigned srcStartY, unsigned srcEndY,
116 unsigned lineWidth);
117
118 void preCalcNoise(float factor);
119 void drawNoise() const;
120 void drawGlow(int glow);
121
122 void preCalcMonitor3D(float width);
123 void drawMonitor3D() const;
124
125private:
126 Display& display;
127 RenderSettings& renderSettings;
128 EventDistributor& eventDistributor;
129
131 OutputSurface& screen;
132
134 std::array<std::unique_ptr<RawFrame>, 4> lastFrames;
135
137 std::unique_ptr<DeinterlacedFrame> deinterlacedFrame;
138
140 std::unique_ptr<DoubledFrame> interlacedFrame;
141
143 std::unique_ptr<Deflicker> deflicker;
144
146 std::unique_ptr<SuperImposedFrame> superImposedFrame;
147
152 FrameSource* paintFrame = nullptr;
153
155 AviRecorder* recorder = nullptr;
156
159 const RawFrame* superImposeVideoFrame = nullptr;
160 const FrameSource* superImposeVdpFrame = nullptr;
161
162 int interleaveCount = 0; // for interleave-black-frame
163 int lastFramesCount = 0; // How many items in lastFrames[] are up-to-date
164 unsigned maxWidth; // we lazily create RawFrame objects in lastFrames[]
165 unsigned height; // these two vars remember how big those should be
166
171 const bool canDoInterlace;
172
173 EmuTime lastRotate;
176 std::unique_ptr<GLScaler> currScaler;
177
178 struct StoredFrame {
179 gl::ivec2 size; // (re)allocate when window size changes
180 gl::Texture tex;
182 };
183 std::array<StoredFrame, 2> renderedFrames;
184
185 // Noise effect:
186 gl::Texture noiseTextureA{true, true}; // interpolate + wrap
187 gl::Texture noiseTextureB{true, true};
188 float noiseX = 0.0f, noiseY = 0.0f;
189
190 struct TextureData {
192 [[nodiscard]] unsigned width() const { return tex.getWidth(); }
193 };
194 std::vector<TextureData> textures;
196
197 gl::ColorTexture superImposeTex;
198
199 struct Region {
200 Region(unsigned srcStartY_, unsigned srcEndY_,
201 unsigned dstStartY_, unsigned dstEndY_,
202 unsigned lineWidth_)
203 : srcStartY(srcStartY_)
204 , srcEndY(srcEndY_)
205 , dstStartY(dstStartY_)
206 , dstEndY(dstEndY_)
207 , lineWidth(lineWidth_) {}
208 unsigned srcStartY;
209 unsigned srcEndY;
210 unsigned dstStartY;
211 unsigned dstEndY;
212 unsigned lineWidth;
213 };
214 std::vector<Region> regions;
215
216 unsigned frameCounter = 0;
217
221
222 gl::ShaderProgram monitor3DProg;
223 gl::BufferObject arrayBuffer;
224 gl::BufferObject elementBuffer;
226 gl::BufferObject stretchVBO;
227
228 bool storedFrame = false;
229};
230
231} // namespace openmsx
232
233#endif // GLPOSTPROCESSOR_HH
BaseSetting * setting
GLsizei getWidth() const
Definition GLUtil.hh:117
Wrapper around a pixel buffer.
Definition GLUtil.hh:159
Wrapper around an OpenGL program: a collection of vertex and fragment shaders.
Definition GLUtil.hh:371
Most basic/generic texture: only contains a texture ID.
Definition GLUtil.hh:40
Represents the output window/screen of openMSX.
Definition Display.hh:31
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:16
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:11