openMSX
FrameSource.hh
Go to the documentation of this file.
1 #ifndef FRAMESOURCE_HH
2 #define FRAMESOURCE_HH
3 
4 #include "PixelFormat.hh"
5 #include "aligned.hh"
6 #include <algorithm>
7 #include <cassert>
8 
9 namespace openmsx {
10 
14 {
15 public:
18  enum FieldType {
28  };
29 
33  void init(FieldType fieldType_) { fieldType = fieldType_; }
34 
37  FieldType getField() const {
38  return fieldType;
39  }
40 
43  unsigned getHeight() const {
44  return height;
45  }
46 
50  virtual unsigned getLineWidth(unsigned line) const = 0;
51 
58  unsigned getWidth() const {
59  assert(height > 0);
60  unsigned result = getLineWidth(0);
61  for (unsigned line = 1; line < height; ++line) {
62  assert(result == getLineWidth(line));
63  }
64  return result;
65  }
66 
72  template <typename Pixel>
73  inline Pixel getLineColor(unsigned line) const {
74  alignas(SSE_ALIGNMENT) Pixel buf[1280]; // large enough for widest line
75  unsigned width; // not used
76  return reinterpret_cast<const Pixel*>(
77  getLineInfo(line, width, buf, 1280))[0];
78  }
79 
89  template <typename Pixel>
90  inline const Pixel* getLinePtr(int line, unsigned width, Pixel* buf) const
91  {
92  line = std::min<unsigned>(std::max(0, line), getHeight() - 1);
93  unsigned internalWidth;
94  auto* internalData = reinterpret_cast<const Pixel*>(
95  getLineInfo(line, internalWidth, buf, width));
96  if (internalWidth == width) {
97  return internalData;
98  } else {
99  // slow path, non-inlined
100  // internalData might be equal to buf
101  scaleLine(internalData, buf, internalWidth, width);
102  return buf;
103  }
104  }
105 
111  template <typename Pixel>
112  inline const Pixel* getMultiLinePtr(
113  int line, unsigned numLines, unsigned& actualLines,
114  unsigned width, Pixel* buf) const
115  {
116  actualLines = 1;
117  if ((line < 0) || (int(height) <= line)) {
118  return getLinePtr(line, width, buf);
119  }
120  unsigned internalWidth;
121  auto* internalData = reinterpret_cast<const Pixel*>(
122  getLineInfo(line, internalWidth, buf, width));
123  if (internalWidth != width) {
124  scaleLine(internalData, buf, internalWidth, width);
125  return buf;
126  }
127  if (!hasContiguousStorage()) {
128  return internalData;
129  }
130  while (--numLines) {
131  ++line;
132  if ((line == int(height)) || (getLineWidth(line) != width)) {
133  break;
134  }
135  ++actualLines;
136  }
137  return internalData;
138  }
139 
153  virtual const void* getLineInfo(
154  unsigned line, unsigned& lineWidth,
155  void* buf, unsigned bufWidth) const = 0;
156 
162  template <typename Pixel>
163  const Pixel* getLinePtr320_240(unsigned line, Pixel* buf) const;
164 
169  template <typename Pixel>
170  const Pixel* getLinePtr640_480(unsigned line, Pixel* buf) const;
171 
176  template <typename Pixel>
177  const Pixel* getLinePtr960_720(unsigned line, Pixel* buf) const;
178 
185  virtual unsigned getRowLength() const {
186  return 0;
187  }
188 
189  const PixelFormat& getPixelFormat() const {
190  return pixelFormat;
191  }
192 
193 protected:
194  explicit FrameSource(const PixelFormat& format);
195  ~FrameSource() = default;
196 
197  void setHeight(unsigned height_) { height = height_; }
198 
202  virtual bool hasContiguousStorage() const {
203  return false;
204  }
205 
206  template <typename Pixel> void scaleLine(
207  const Pixel* in, Pixel* out,
208  unsigned inWidth, unsigned outWidth) const;
209 
210 private:
213  const PixelFormat& pixelFormat;
214 
217  unsigned height;
218 
219  FieldType fieldType;
220 };
221 
222 } // namespace openmsx
223 
224 #endif // FRAMESOURCE_HH
SSE_ALIGNMENT
constexpr auto SSE_ALIGNMENT
Definition: aligned.hh:13
aligned.hh
openmsx::FrameSource::getLineWidth
virtual unsigned getLineWidth(unsigned line) const =0
Gets the number of display pixels on the given line.
openmsx::FrameSource::~FrameSource
~FrameSource()=default
openmsx::FrameSource::getLinePtr320_240
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
openmsx::FrameSource::getLinePtr
const Pixel * getLinePtr(int line, unsigned width, Pixel *buf) const
Gets a pointer to the pixels of the given line number.
Definition: FrameSource.hh:90
openmsx::FrameSource::hasContiguousStorage
virtual bool hasContiguousStorage() const
Returns true when two consecutive rows are also consecutive in memory.
Definition: FrameSource.hh:202
openmsx::PixelFormat
Definition: PixelFormat.hh:8
openmsx::FrameSource::getRowLength
virtual unsigned getRowLength() const
Returns the distance (in pixels) between two consecutive lines.
Definition: FrameSource.hh:185
openmsx::FrameSource::FIELD_EVEN
Interlacing is on and this is an even frame.
Definition: FrameSource.hh:24
openmsx::Pixel
uint32_t Pixel
Definition: GLHQLiteScaler.cc:93
openmsx::FrameSource::setHeight
void setHeight(unsigned height_)
Definition: FrameSource.hh:197
openmsx::FrameSource::getLineInfo
virtual const void * getLineInfo(unsigned line, unsigned &lineWidth, void *buf, unsigned bufWidth) const =0
Abstract implementation of getLinePtr().
openmsx::FrameSource::FIELD_NONINTERLACED
Interlacing is off for this frame.
Definition: FrameSource.hh:21
openmsx::FrameSource::getField
FieldType getField() const
Gets the role this frame plays in interlacing.
Definition: FrameSource.hh:37
openmsx::FrameSource::getLineColor
Pixel getLineColor(unsigned line) const
Get the (single) color of the given line.
Definition: FrameSource.hh:73
openmsx::FrameSource::getLinePtr960_720
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
openmsx::FrameSource::getPixelFormat
const PixelFormat & getPixelFormat() const
Definition: FrameSource.hh:189
openmsx::FrameSource::init
void init(FieldType fieldType_)
(Re)initialize an existing FrameSource.
Definition: FrameSource.hh:33
openmsx::FrameSource::getLinePtr640_480
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
openmsx::FrameSource::FieldType
FieldType
What role does this frame play in interlacing?
Definition: FrameSource.hh:18
openmsx::FrameSource::getHeight
unsigned getHeight() const
Gets the number of lines in this frame.
Definition: FrameSource.hh:43
openmsx::FrameSource
Interface for getting lines from a video frame.
Definition: FrameSource.hh:13
gl::max
vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:292
openmsx::FrameSource::FrameSource
FrameSource(const PixelFormat &format)
Definition: FrameSource.cc:15
openmsx::FrameSource::scaleLine
void scaleLine(const Pixel *in, Pixel *out, unsigned inWidth, unsigned outWidth) const
Definition: FrameSource.cc:70
openmsx::FrameSource::getWidth
unsigned getWidth() const
Get the width of (all) lines in this frame.
Definition: FrameSource.hh:58
PixelFormat.hh
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
openmsx::FrameSource::FIELD_ODD
Interlacing is on and this is an odd frame.
Definition: FrameSource.hh:27
openmsx::FrameSource::getMultiLinePtr
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:112