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 
10 namespace openmsx {
11 
12 class PixelFormat;
13 
17 {
18 public:
21  enum FieldType {
30  FIELD_ODD
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 
196 protected:
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 
213 private:
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 * 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
virtual const void * getLineInfo(unsigned line, unsigned &lineWidth, void *buf, unsigned bufWidth) const =0
Abstract implementation of getLinePtr().
const PixelFormat & getPixelFormat() const
Definition: FrameSource.hh:192
void setHeight(unsigned height_)
Definition: FrameSource.hh:200
unsigned getWidth() const
Get the width of (all) lines in this frame.
Definition: FrameSource.hh:61
void scaleLine(const Pixel *in, Pixel *out, unsigned inWidth, unsigned outWidth) const
Definition: FrameSource.cc:69
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
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
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
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
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:276
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
constexpr auto xrange(T e)
Definition: xrange.hh:133