openMSX
SuperImposedVideoFrame.cc
Go to the documentation of this file.
2#include "LineScalers.hh"
3#include "MemoryOps.hh"
4#include "vla.hh"
5#include "build-info.hh"
6#include <cstdint>
7
8namespace openmsx {
9
10template<std::unsigned_integral Pixel>
12 const FrameSource& src_, const FrameSource& super_,
13 const PixelOperations<Pixel>& pixelOps_)
14 : FrameSource(pixelOps_.getPixelFormat())
15 , src(src_), super(super_), pixelOps(pixelOps_)
16{
17 setHeight(src.getHeight());
18}
19
20template<std::unsigned_integral Pixel>
22{
23 unsigned width = src.getLineWidth(line);
24 return (width == 1) ? 320 : width;
25}
26
27template<std::unsigned_integral Pixel>
29 unsigned line, unsigned& width, void* buf1_, unsigned bufWidth) const
30{
31 auto* buf1 = static_cast<Pixel*>(buf1_);
32 // Return minimum line width of 320.
33 // We could check whether both inputs have width=1 and in that case
34 // also return a line of width=1. But for now (laserdisc) this will
35 // never happen.
36 auto* srcLine = static_cast<const Pixel*>(
37 src.getLineInfo(line, width, buf1, bufWidth));
38 if (width == 1) {
39 width = 320;
41 memset(std::span{buf1, 320}, srcLine[0]);
42 srcLine = buf1;
43 }
44 // (possibly) srcLine == buf1
45
46 // Adjust the two inputs to the same height.
47 VLA_SSE_ALIGNED(Pixel, buf2, width);
48 assert(super.getHeight() == 480); // TODO possibly extend in the future
49 auto supLine = [&] {
50 if (src.getHeight() == 240) {
51 VLA_SSE_ALIGNED(Pixel, buf3, width);
52 auto sup0 = super.getLine(2 * line + 0, buf2);
53 auto sup1 = super.getLine(2 * line + 1, buf3);
54 BlendLines<Pixel> blend(pixelOps);
55 blend(sup0, sup1, buf2); // possibly sup0 == buf2
56 return std::span<const Pixel>(buf2);
57 } else {
58 assert(src.getHeight() == super.getHeight());
59 return super.getLine(line, buf2); // scale line
60 }
61 }();
62 // (possibly) supLine == buf2
63
64 // Actually blend the lines of both frames.
65 AlphaBlendLines<Pixel> blend(pixelOps);
66 blend(std::span{srcLine, width}, supLine, std::span{buf1, width}); // possibly srcLine == buf1
67 return buf1;
68}
69
70// Force template instantiation.
71#if HAVE_16BPP
73#endif
74#if HAVE_32BPP
76#endif
77
78} // namespace openmsx
AlphaBlendLines functor Generate an output line that is a per-pixel-alpha-blend of the two input line...
Definition: LineScalers.hh:260
BlendLines functor Generate an output line that is an interpolation of two input lines.
Definition: LineScalers.hh:230
Interface for getting lines from a video frame.
Definition: FrameSource.hh:20
void setHeight(unsigned height_)
Definition: FrameSource.hh:159
unsigned getHeight() const
Gets the number of lines in this frame.
Definition: FrameSource.hh:49
This class represents a frame that is the (per-pixel) alpha-blend of a (laser-disc) video frame and a...
SuperImposedVideoFrame(const FrameSource &src, const FrameSource &super, const PixelOperations< Pixel > &pixelOps)
const void * getLineInfo(unsigned line, unsigned &width, void *buf, unsigned bufWidth) const override
Abstract implementation of getLinePtr().
unsigned getLineWidth(unsigned line) const override
Gets the number of display pixels on the given line.
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
#define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH)
Definition: vla.hh:50