openMSX
SuperImposeScalerOutput.cc
Go to the documentation of this file.
2#include "RawFrame.hh"
3#include "LineScalers.hh"
4#include "MemoryOps.hh"
5#include "unreachable.hh"
6#include "vla.hh"
7#include "build-info.hh"
8#include <cstdint>
9
10namespace openmsx {
11
12template<std::unsigned_integral Pixel>
14 ScalerOutput<Pixel>& output_,
15 const RawFrame& superImpose_,
16 const PixelOperations<Pixel>& pixelOps_)
17 : output(output_)
18 , superImpose(superImpose_)
19 , pixelOps(pixelOps_)
20{
21}
22
23template<std::unsigned_integral Pixel>
25{
26 return output.getWidth();
27}
28
29template<std::unsigned_integral Pixel>
31{
32 return output.getHeight();
33}
34
35template<std::unsigned_integral Pixel>
37{
38 return output.acquireLine(y);
39}
40
41template<std::unsigned_integral Pixel>
42void SuperImposeScalerOutput<Pixel>::releaseLine(unsigned y, std::span<Pixel> buf)
43{
44 unsigned width = output.getWidth();
45 assert(buf.size() == width);
46
47 VLA_SSE_ALIGNED(Pixel, buf2, width);
48 auto srcLine = getSrcLine(y, buf2);
49 AlphaBlendLines<Pixel> alphaBlend(pixelOps);
50 alphaBlend(buf, srcLine, buf);
51 output.releaseLine(y, buf);
52}
53
54template<std::unsigned_integral Pixel>
56{
57 auto dstLine = output.acquireLine(y);
58 if (pixelOps.isFullyOpaque(color)) {
60 memset(dstLine, color);
61 } else {
62 auto srcLine = getSrcLine(y, dstLine);
63 if (pixelOps.isFullyTransparent(color)) {
64 // optimization: use destination as work buffer, in case
65 // that buffer got used, we don't need to make a copy
66 // anymore
67 if (srcLine.data() != dstLine.data()) {
69 copy(srcLine, dstLine);
70 }
71 } else {
72 AlphaBlendLines<Pixel> alphaBlend(pixelOps);
73 alphaBlend(color, srcLine, dstLine); // possibly srcLine == dstLine
74 }
75 }
76 output.releaseLine(y, dstLine);
77}
78
79template<std::unsigned_integral Pixel>
80std::span<const Pixel> SuperImposeScalerOutput<Pixel>::getSrcLine(unsigned y, std::span<Pixel> buf)
81{
82 auto width = buf.size();
83 if (width == 320) {
84 return superImpose.getLinePtr320_240(y, std::span<Pixel, 320>(buf));
85 } else if (width == 640) {
86 return superImpose.getLinePtr640_480(y, std::span<Pixel, 640>(buf));
87 } else if (width == 960) {
88 return superImpose.getLinePtr960_720(y, std::span<Pixel, 960>(buf));
89 } else {
90 UNREACHABLE; return {};
91 }
92}
93
94
95// Force template instantiation.
96#if HAVE_16BPP
97template class SuperImposeScalerOutput<uint16_t>;
98#endif
99#if HAVE_32BPP
100template class SuperImposeScalerOutput<uint32_t>;
101#endif
102
103} // namespace openmsx
AlphaBlendLines functor Generate an output line that is a per-pixel-alpha-blend of the two input line...
Definition: LineScalers.hh:260
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
Definition: RawFrame.hh:15
std::span< Pixel > acquireLine(unsigned y) override
void fillLine(unsigned y, Pixel color) override
void releaseLine(unsigned y, std::span< Pixel > buf) override
SuperImposeScalerOutput(ScalerOutput< Pixel > &output, const RawFrame &superImpose_, const PixelOperations< Pixel > &pixelOps_)
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:232
#define UNREACHABLE
Definition: unreachable.hh:38
#define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH)
Definition: vla.hh:50