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 "narrow.hh"
6#include "xrange.hh"
7#include <algorithm>
8#include <array>
9#include <cassert>
10#include <cstdint>
11#include <span>
12
13namespace openmsx {
14
18{
19public:
20 using Pixel = uint32_t;
21
35
39 void init(FieldType fieldType_) { fieldType = fieldType_; }
40
43 [[nodiscard]] FieldType getField() const {
44 return fieldType;
45 }
46
49 [[nodiscard]] unsigned getHeight() const {
50 return height;
51 }
52
56 [[nodiscard]] virtual unsigned getLineWidth(unsigned line) const = 0;
57
64 [[nodiscard]] unsigned getWidth() const {
65 assert(height > 0);
66 unsigned result = getLineWidth(0);
67 for (auto line : xrange(1u, height)) {
68 assert(result == getLineWidth(line)); (void)line;
69 }
70 return result;
71 }
72
78 [[nodiscard]] inline Pixel getLineColor(unsigned line) const {
79 ALIGNAS_SSE std::array<Pixel, 1280> buf; // large enough for widest line
80 unsigned width; // not used
81 return reinterpret_cast<const Pixel*>(
82 getLineInfo(line, width, buf.data(), 1280))[0];
83 }
84
94 [[nodiscard]] inline std::span<const Pixel> getLine(int line, std::span<Pixel> buf) const
95 {
96 line = std::clamp(line, 0, narrow<int>(getHeight() - 1));
97 unsigned internalWidth;
98 auto* internalData = reinterpret_cast<const Pixel*>(
99 getLineInfo(line, internalWidth, buf.data(), narrow<unsigned>(buf.size())));
100 if (internalWidth == narrow<unsigned>(buf.size())) {
101 return std::span{internalData, buf.size()};
102 } else {
103 // slow path, non-inlined
104 // internalData might be equal to buf
105 scaleLine(std::span{internalData, internalWidth}, buf);
106 return buf;
107 }
108 }
109
123 [[nodiscard]] virtual const void* getLineInfo(
124 unsigned line, unsigned& lineWidth,
125 void* buf, unsigned bufWidth) const = 0;
126
132 [[nodiscard]] std::span<const Pixel, 320> getLinePtr320_240(unsigned line, std::span<Pixel, 320> buf) const;
133
138 [[nodiscard]] std::span<const Pixel, 640> getLinePtr640_480(unsigned line, std::span<Pixel, 640> buf) const;
139
144 [[nodiscard]] std::span<const Pixel, 960> getLinePtr960_720(unsigned line, std::span<Pixel, 960> buf) const;
145
146protected:
147 FrameSource() = default;
148 ~FrameSource() = default;
149
150 void setHeight(unsigned height_) { height = height_; }
151
155 [[nodiscard]] virtual bool hasContiguousStorage() const {
156 return false;
157 }
158
159 void scaleLine(std::span<const Pixel> in, std::span<Pixel> out) const;
160
161private:
164 unsigned height;
165
166 FieldType fieldType;
167};
168
169} // namespace openmsx
170
171#endif // FRAMESOURCE_HH
#define ALIGNAS_SSE
Definition aligned.hh:24
Interface for getting lines from a video frame.
virtual bool hasContiguousStorage() const
Returns true when two consecutive rows are also consecutive in memory.
std::span< const Pixel > getLine(int line, std::span< Pixel > buf) const
Gets a pointer to the pixels of the given line number.
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.
std::span< const Pixel, 320 > getLinePtr320_240(unsigned line, std::span< Pixel, 320 > buf) const
Get a pointer to a given line in this frame, the frame is scaled to 320x240 pixels.
Pixel getLineColor(unsigned line) const
Get the (single) color of the given line.
std::span< const Pixel, 960 > getLinePtr960_720(unsigned line, std::span< Pixel, 960 > buf) const
Get a pointer to a given line in this frame, the frame is scaled to 960x720 pixels.
void scaleLine(std::span< const Pixel > in, std::span< Pixel > out) const
void setHeight(unsigned height_)
unsigned getWidth() const
Get the width of (all) lines in this frame.
virtual const void * getLineInfo(unsigned line, unsigned &lineWidth, void *buf, unsigned bufWidth) const =0
Abstract implementation of getLinePtr().
void init(FieldType fieldType_)
(Re)initialize an existing FrameSource.
std::span< const Pixel, 640 > getLinePtr640_480(unsigned line, std::span< Pixel, 640 > buf) const
Get a pointer to a given line in this frame, the frame is scaled to 640x480 pixels.
unsigned getHeight() const
Gets the number of lines in this frame.
FieldType
What role does this frame play in interlacing?
@ FIELD_NONINTERLACED
Interlacing is off for this frame.
@ FIELD_EVEN
Interlacing is on and this is an even frame.
@ FIELD_ODD
Interlacing is on and this is an odd frame.
This file implemented 3 utility functions:
Definition Autofire.cc:9
constexpr auto xrange(T e)
Definition xrange.hh:132