openMSX
HQ3xLiteScaler.cc
Go to the documentation of this file.
1/*
2Original code: Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )
3openMSX adaptation by Wouter Vermaelen
4
5License: LGPL
6
7Visit the HiEnd3D site for info:
8 http://www.hiend3d.com/hq2x.html
9*/
10
11#include "HQ3xLiteScaler.hh"
12#include "HQCommon.hh"
13#include "LineScalers.hh"
14#include "unreachable.hh"
15#include "xrange.hh"
16#include "build-info.hh"
17#include <cstdint>
18
19namespace openmsx {
20
21template<std::unsigned_integral Pixel> struct HQLite_1x1on3x3
22{
23 void operator()(std::span<const Pixel> in0, std::span<const Pixel> in1, std::span<const Pixel> in2,
24 std::span<Pixel> out0, std::span<Pixel> out1, std::span<Pixel> out2,
25 std::span<uint16_t> edgeBuf, EdgeHQLite edgeOp);
26};
27
28template<std::unsigned_integral Pixel>
30 std::span<const Pixel> in0, std::span<const Pixel> in1, std::span<const Pixel> in2,
31 std::span<Pixel> out0, std::span<Pixel> out1, std::span<Pixel> out2,
32 std::span<uint16_t> edgeBuf,
33 EdgeHQLite /*edgeOp*/)
34{
35 auto srcWidth = edgeBuf.size();
36 assert(in0.size() == srcWidth);
37 assert(in1.size() == srcWidth);
38 assert(in2.size() == srcWidth);
39 assert(out0.size() == 3 * srcWidth);
40 assert(out1.size() == 3 * srcWidth);
41 assert(out2.size() == 3 * srcWidth);
42
43 auto c2 = readPixel(in0[0]);
44 auto c5 = readPixel(in1[0]); auto c6 = c5;
45 auto c8 = readPixel(in2[0]); auto c9 = c8;
46
47 unsigned pattern = 0;
48 if (c5 != c8) pattern |= 3 << 6;
49 if (c5 != c2) pattern |= 3 << 9;
50
51 for (auto x : xrange(srcWidth)) {
52 auto c4 = c5;
53 c5 = c6;
54 c8 = c9;
55 if (x != srcWidth - 1) {
56 c6 = readPixel(in1[x + 1]);
57 c9 = readPixel(in2[x + 1]);
58 }
59
60 pattern = (pattern >> 6) & 0x001F; // left overlap
61 // overlaps with left
62 //if (c8 != c4) pattern |= 1 << 0; // B - l: c5-c9 6
63 //if (c5 != c7) pattern |= 1 << 1; // B - l: c6-c8 7
64 //if (c5 != c4) pattern |= 1 << 2; // l: c5-c6 8
65 // overlaps with top and left
66 //if (c5 != c1) pattern |= 1 << 3; // l: c2-c6 9, t: c4-c8 0
67 //if (c4 != c2) pattern |= 1 << 4; // l: c5-c3 10, t: c5-c7 1
68 // non-overlapping pixels
69 if (c5 != c8) pattern |= 1 << 5; // B
70 if (c5 != c9) pattern |= 1 << 6; // BR
71 if (c6 != c8) pattern |= 1 << 7; // BR
72 if (c5 != c6) pattern |= 1 << 8; // R
73 // overlaps with top
74 //if (c2 != c6) pattern |= 1 << 9; // R - t: c5-c9 6
75 //if (c5 != c3) pattern |= 1 << 10; // R - t: c6-c8 7
76 //if (c5 != c2) pattern |= 1 << 11; // t: c5-c8 5
77 pattern |= ((edgeBuf[x] & (1 << 5) ) << 6) |
78 ((edgeBuf[x] & ((1 << 6) | (1 << 7))) << 3);
79 edgeBuf[x] = narrow_cast<uint16_t>(pattern);
80
81 unsigned pixel0, pixel1, pixel2, pixel3, pixel4,
82 pixel5, pixel6, pixel7, pixel8;
83
84#include "HQ3xLiteScaler-1x1to3x3.nn"
85
86 out0[3 * x + 0] = writePixel<Pixel>(pixel0);
87 out0[3 * x + 1] = writePixel<Pixel>(pixel1);
88 out0[3 * x + 2] = writePixel<Pixel>(pixel2);
89 out1[3 * x + 0] = writePixel<Pixel>(pixel3);
90 out1[3 * x + 1] = writePixel<Pixel>(pixel4);
91 out1[3 * x + 2] = writePixel<Pixel>(pixel5);
92 out2[3 * x + 0] = writePixel<Pixel>(pixel6);
93 out2[3 * x + 1] = writePixel<Pixel>(pixel7);
94 out2[3 * x + 2] = writePixel<Pixel>(pixel8);
95 }
96}
97
98
99template<std::unsigned_integral Pixel>
101 : Scaler3<Pixel>(pixelOps_)
102 , pixelOps(pixelOps_)
103{
104}
105
106template<std::unsigned_integral Pixel>
108 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
109 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
110{
111 PolyScale<Pixel, Scale_2on3<Pixel>> postScale(pixelOps);
112 EdgeHQLite edgeOp;
113 doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
114 src, srcStartY, srcEndY, srcWidth,
115 dst, dstStartY, dstEndY);
116}
117
118template<std::unsigned_integral Pixel>
120 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
121 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
122{
124 EdgeHQLite edgeOp;
125 doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
126 src, srcStartY, srcEndY, srcWidth,
127 dst, dstStartY, dstEndY);
128}
129
130template<std::unsigned_integral Pixel>
132 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
133 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
134{
135 PolyScale<Pixel, Scale_4on3<Pixel>> postScale(pixelOps);
136 EdgeHQLite edgeOp;
137 doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
138 src, srcStartY, srcEndY, srcWidth,
139 dst, dstStartY, dstEndY);
140}
141
142template<std::unsigned_integral Pixel>
144 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
145 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
146{
147 PolyScale<Pixel, Scale_2on1<Pixel>> postScale(pixelOps);
148 EdgeHQLite edgeOp;
149 doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
150 src, srcStartY, srcEndY, srcWidth,
151 dst, dstStartY, dstEndY);
152}
153
154template<std::unsigned_integral Pixel>
156 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
157 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
158{
159 PolyScale<Pixel, Scale_8on3<Pixel>> postScale(pixelOps);
160 EdgeHQLite edgeOp;
161 doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
162 src, srcStartY, srcEndY, srcWidth,
163 dst, dstStartY, dstEndY);
164}
165
166template<std::unsigned_integral Pixel>
168 unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
169 ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
170{
171 PolyScale<Pixel, Scale_4on1<Pixel>> postScale(pixelOps);
172 EdgeHQLite edgeOp;
173 doHQScale3<Pixel>(HQLite_1x1on3x3<Pixel>(), edgeOp, postScale,
174 src, srcStartY, srcEndY, srcWidth,
175 dst, dstStartY, dstEndY);
176}
177
178// Force template instantiation.
179#if HAVE_16BPP
180template class HQ3xLiteScaler<uint16_t>;
181#endif
182#if HAVE_32BPP
183template class HQ3xLiteScaler<uint32_t>;
184#endif
185
186} // namespace openmsx
Interface for getting lines from a video frame.
Definition: FrameSource.hh:20
void scale1x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
void scale4x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
void scale4x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
void scale8x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
HQ3xLiteScaler(const PixelOperations< Pixel > &pixelOps)
void scale2x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
void scale2x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Polymorphic wrapper around another line scaler.
Definition: LineScalers.hh:313
Base class for 3x scalers.
Definition: Scaler3.hh:12
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
uint32_t readPixel(Pixel p)
Definition: HQCommon.hh:19
void operator()(std::span< const Pixel > in0, std::span< const Pixel > in1, std::span< const Pixel > in2, std::span< Pixel > out0, std::span< Pixel > out1, std::span< Pixel > out2, std::span< uint16_t > edgeBuf, EdgeHQLite edgeOp)
constexpr auto xrange(T e)
Definition: xrange.hh:132