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 
9 namespace openmsx {
10 
11 class PixelFormat;
12 
16 {
17 public:
20  enum FieldType {
29  FIELD_ODD
30  };
31 
35  void init(FieldType fieldType_) { fieldType = fieldType_; }
36 
39  [[nodiscard]] FieldType getField() const {
40  return fieldType;
41  }
42 
45  [[nodiscard]] unsigned getHeight() const {
46  return height;
47  }
48 
52  [[nodiscard]] virtual unsigned getLineWidth(unsigned line) const = 0;
53 
60  [[nodiscard]] unsigned getWidth() const {
61  assert(height > 0);
62  unsigned result = getLineWidth(0);
63  for (auto line : xrange(1u, height)) {
64  assert(result == getLineWidth(line)); (void)line;
65  }
66  return result;
67  }
68 
74  template<typename Pixel>
75  [[nodiscard]] inline Pixel getLineColor(unsigned line) const {
76  ALIGNAS_SSE Pixel buf[1280]; // large enough for widest line
77  unsigned width; // not used
78  return reinterpret_cast<const Pixel*>(
79  getLineInfo(line, width, buf, 1280))[0];
80  }
81 
91  template<typename Pixel>
92  [[nodiscard]] inline const Pixel* getLinePtr(int line, unsigned width, Pixel* buf) const
93  {
94  line = std::min<unsigned>(std::max(0, line), getHeight() - 1);
95  unsigned internalWidth;
96  auto* internalData = reinterpret_cast<const Pixel*>(
97  getLineInfo(line, internalWidth, buf, width));
98  if (internalWidth == width) {
99  return internalData;
100  } else {
101  // slow path, non-inlined
102  // internalData might be equal to buf
103  scaleLine(internalData, buf, internalWidth, width);
104  return buf;
105  }
106  }
107 
113  template<typename Pixel>
114  [[nodiscard]] inline const Pixel* getMultiLinePtr(
115  int line, unsigned numLines, unsigned& actualLines,
116  unsigned width, Pixel* buf) const
117  {
118  actualLines = 1;
119  if ((line < 0) || (int(height) <= line)) {
120  return getLinePtr(line, width, buf);
121  }
122  unsigned internalWidth;
123  auto* internalData = reinterpret_cast<const Pixel*>(
124  getLineInfo(line, internalWidth, buf, width));
125  if (internalWidth != width) {
126  scaleLine(internalData, buf, internalWidth, width);
127  return buf;
128  }
129  if (!hasContiguousStorage()) {
130  return internalData;
131  }
132  while (--numLines) {
133  ++line;
134  if ((line == int(height)) || (getLineWidth(line) != width)) {
135  break;
136  }
137  ++actualLines;
138  }
139  return internalData;
140  }
141 
155  [[nodiscard]] virtual const void* getLineInfo(
156  unsigned line, unsigned& lineWidth,
157  void* buf, unsigned bufWidth) const = 0;
158 
164  template<typename Pixel>
165  [[nodiscard]] const Pixel* getLinePtr320_240(unsigned line, Pixel* buf) const;
166 
171  template<typename Pixel>
172  [[nodiscard]] const Pixel* getLinePtr640_480(unsigned line, Pixel* buf) const;
173 
178  template<typename Pixel>
179  [[nodiscard]] const Pixel* getLinePtr960_720(unsigned line, Pixel* buf) const;
180 
187  [[nodiscard]] virtual unsigned getRowLength() const {
188  return 0;
189  }
190 
191  [[nodiscard]] const PixelFormat& getPixelFormat() const {
192  return pixelFormat;
193  }
194 
195 protected:
196  explicit FrameSource(const PixelFormat& format);
197  ~FrameSource() = default;
198 
199  void setHeight(unsigned height_) { height = height_; }
200 
204  [[nodiscard]] virtual bool hasContiguousStorage() const {
205  return false;
206  }
207 
208  template<typename Pixel> void scaleLine(
209  const Pixel* in, Pixel* out,
210  unsigned inWidth, unsigned outWidth) const;
211 
212 private:
215  const PixelFormat& pixelFormat;
216 
219  unsigned height;
220 
221  FieldType fieldType;
222 };
223 
224 } // namespace openmsx
225 
226 #endif // FRAMESOURCE_HH
#define ALIGNAS_SSE
Definition: aligned.hh:24
Interface for getting lines from a video frame.
Definition: FrameSource.hh:16
virtual bool hasContiguousStorage() const
Returns true when two consecutive rows are also consecutive in memory.
Definition: FrameSource.hh:204
Pixel getLineColor(unsigned line) const
Get the (single) color of the given line.
Definition: FrameSource.hh:75
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:49
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:39
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:21
FrameSource(const PixelFormat &format)
Definition: FrameSource.cc:15
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:191
void setHeight(unsigned height_)
Definition: FrameSource.hh:199
unsigned getWidth() const
Get the width of (all) lines in this frame.
Definition: FrameSource.hh:60
void scaleLine(const Pixel *in, Pixel *out, unsigned inWidth, unsigned outWidth) const
Definition: FrameSource.cc:70
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:114
void init(FieldType fieldType_)
(Re)initialize an existing FrameSource.
Definition: FrameSource.hh:35
virtual unsigned getRowLength() const
Returns the distance (in pixels) between two consecutive lines.
Definition: FrameSource.hh:187
unsigned getHeight() const
Gets the number of lines in this frame.
Definition: FrameSource.hh:45
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:38
const Pixel * getLinePtr(int line, unsigned width, Pixel *buf) const
Gets a pointer to the pixels of the given line number.
Definition: FrameSource.hh:92
FieldType
What role does this frame play in interlacing?
Definition: FrameSource.hh:20
@ FIELD_NONINTERLACED
Interlacing is off for this frame.
Definition: FrameSource.hh:23
@ FIELD_EVEN
Interlacing is on and this is an even frame.
Definition: FrameSource.hh:26
@ FIELD_ODD
Interlacing is on and this is an odd frame.
Definition: FrameSource.hh:29
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:287
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
constexpr auto xrange(T e)
Definition: xrange.hh:155