openMSX
FrameSource.hh
Go to the documentation of this file.
1#ifndef FRAMESOURCE_HH
2#define FRAMESOURCE_HH
3
4#include "aligned.hh"
5#include "xrange.hh"
6#include <algorithm>
7#include <cassert>
8#include <concepts>
9
10namespace openmsx {
11
12class PixelFormat;
13
17{
18public:
21 enum FieldType {
31 };
32
36 void init(FieldType fieldType_) { fieldType = fieldType_; }
37
40 [[nodiscard]] FieldType getField() const {
41 return fieldType;
42 }
43
46 [[nodiscard]] unsigned getHeight() const {
47 return height;
48 }
49
53 [[nodiscard]] virtual unsigned getLineWidth(unsigned line) const = 0;
54
61 [[nodiscard]] unsigned getWidth() const {
62 assert(height > 0);
63 unsigned result = getLineWidth(0);
64 for (auto line : xrange(1u, height)) {
65 assert(result == getLineWidth(line)); (void)line;
66 }
67 return result;
68 }
69
75 template<std::unsigned_integral Pixel>
76 [[nodiscard]] inline Pixel getLineColor(unsigned line) const {
77 ALIGNAS_SSE Pixel buf[1280]; // large enough for widest line
78 unsigned width; // not used
79 return reinterpret_cast<const Pixel*>(
80 getLineInfo(line, width, buf, 1280))[0];
81 }
82
92 template<std::unsigned_integral Pixel>
93 [[nodiscard]] inline const Pixel* getLinePtr(int line, unsigned width, Pixel* buf) const
94 {
95 line = std::min<unsigned>(std::max(0, line), getHeight() - 1);
96 unsigned internalWidth;
97 auto* internalData = reinterpret_cast<const Pixel*>(
98 getLineInfo(line, internalWidth, buf, width));
99 if (internalWidth == width) {
100 return internalData;
101 } else {
102 // slow path, non-inlined
103 // internalData might be equal to buf
104 scaleLine(internalData, buf, internalWidth, width);
105 return buf;
106 }
107 }
108
114 template<std::unsigned_integral Pixel>
115 [[nodiscard]] inline const Pixel* getMultiLinePtr(
116 int line, unsigned numLines, unsigned& actualLines,
117 unsigned width, Pixel* buf) const
118 {
119 actualLines = 1;
120 if ((line < 0) || (int(height) <= line)) {
121 return getLinePtr(line, width, buf);
122 }
123 unsigned internalWidth;
124 auto* internalData = reinterpret_cast<const Pixel*>(
125 getLineInfo(line, internalWidth, buf, width));
126 if (internalWidth != width) {
127 scaleLine(internalData, buf, internalWidth, width);
128 return buf;
129 }
130 if (!hasContiguousStorage()) {
131 return internalData;
132 }
133 while (--numLines) {
134 ++line;
135 if ((line == int(height)) || (getLineWidth(line) != width)) {
136 break;
137 }
138 ++actualLines;
139 }
140 return internalData;
141 }
142
156 [[nodiscard]] virtual const void* getLineInfo(
157 unsigned line, unsigned& lineWidth,
158 void* buf, unsigned bufWidth) const = 0;
159
165 template<std::unsigned_integral Pixel>
166 [[nodiscard]] const Pixel* getLinePtr320_240(unsigned line, Pixel* buf) const;
167
172 template<std::unsigned_integral Pixel>
173 [[nodiscard]] const Pixel* getLinePtr640_480(unsigned line, Pixel* buf) const;
174
179 template<std::unsigned_integral Pixel>
180 [[nodiscard]] const Pixel* getLinePtr960_720(unsigned line, Pixel* buf) const;
181
188 [[nodiscard]] virtual unsigned getRowLength() const {
189 return 0;
190 }
191
192 [[nodiscard]] const PixelFormat& getPixelFormat() const {
193 return pixelFormat;
194 }
195
196protected:
197 explicit FrameSource(const PixelFormat& format);
198 ~FrameSource() = default;
199
200 void setHeight(unsigned height_) { height = height_; }
201
205 [[nodiscard]] virtual bool hasContiguousStorage() const {
206 return false;
207 }
208
209 template<std::unsigned_integral Pixel> void scaleLine(
210 const Pixel* in, Pixel* out,
211 unsigned inWidth, unsigned outWidth) const;
212
213private:
216 const PixelFormat& pixelFormat;
217
220 unsigned height;
221
222 FieldType fieldType;
223};
224
225} // namespace openmsx
226
227#endif // FRAMESOURCE_HH
#define ALIGNAS_SSE
Definition: aligned.hh:24
Interface for getting lines from a video frame.
Definition: FrameSource.hh:17
virtual bool hasContiguousStorage() const
Returns true when two consecutive rows are also consecutive in memory.
Definition: FrameSource.hh:205
Pixel getLineColor(unsigned line) const
Get the (single) color of the given line.
Definition: FrameSource.hh:76
const Pixel * getLinePtr(int line, unsigned width, Pixel *buf) const
Gets a pointer to the pixels of the given line number.
Definition: FrameSource.hh:93
const Pixel * getMultiLinePtr(int line, unsigned numLines, unsigned &actualLines, unsigned width, Pixel *buf) const
Similar to the above getLinePtr() method, but now tries to get multiple lines at once.
Definition: FrameSource.hh:115
const Pixel * getLinePtr960_720(unsigned line, Pixel *buf) const
Get a pointer to a given line in this frame, the frame is scaled to 960x720 pixels.
Definition: FrameSource.cc:48
virtual unsigned getLineWidth(unsigned line) const =0
Gets the number of display pixels on the given line.
FieldType getField() const
Gets the role this frame plays in interlacing.
Definition: FrameSource.hh:40
const Pixel * getLinePtr320_240(unsigned line, Pixel *buf) const
Get a pointer to a given line in this frame, the frame is scaled to 320x240 pixels.
Definition: FrameSource.cc:20
FrameSource(const PixelFormat &format)
Definition: FrameSource.cc:14
void setHeight(unsigned height_)
Definition: FrameSource.hh:200
unsigned getWidth() const
Get the width of (all) lines in this frame.
Definition: FrameSource.hh:61
virtual const void * getLineInfo(unsigned line, unsigned &lineWidth, void *buf, unsigned bufWidth) const =0
Abstract implementation of getLinePtr().
void scaleLine(const Pixel *in, Pixel *out, unsigned inWidth, unsigned outWidth) const
Definition: FrameSource.cc:69
void init(FieldType fieldType_)
(Re)initialize an existing FrameSource.
Definition: FrameSource.hh:36
virtual unsigned getRowLength() const
Returns the distance (in pixels) between two consecutive lines.
Definition: FrameSource.hh:188
unsigned getHeight() const
Gets the number of lines in this frame.
Definition: FrameSource.hh:46
const Pixel * getLinePtr640_480(unsigned line, Pixel *buf) const
Get a pointer to a given line in this frame, the frame is scaled to 640x480 pixels.
Definition: FrameSource.cc:37
FieldType
What role does this frame play in interlacing?
Definition: FrameSource.hh:21
@ FIELD_NONINTERLACED
Interlacing is off for this frame.
Definition: FrameSource.hh:24
@ FIELD_EVEN
Interlacing is on and this is an even frame.
Definition: FrameSource.hh:27
@ FIELD_ODD
Interlacing is on and this is an odd frame.
Definition: FrameSource.hh:30
const PixelFormat & getPixelFormat() const
Definition: FrameSource.hh:192
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:283
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
constexpr auto xrange(T e)
Definition: xrange.hh:133