openMSX
HQ3xScaler.cc
Go to the documentation of this file.
1 /*
2 Original code: Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )
3 openMSX adaptation by Wouter Vermaelen
4 
5 License: LGPL
6 
7 Visit the HiEnd3D site for info:
8  http://www.hiend3d.com/hq2x.html
9 */
10 
11 #include "HQ3xScaler.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 
19 namespace openmsx {
20 
21 template<typename Pixel> struct HQ_1x1on3x3
22 {
23  void operator()(const Pixel* in0, const Pixel* in1, const Pixel* in2,
24  Pixel* out0, Pixel* out1, Pixel* out2,
25  unsigned srcWidth, unsigned* edgeBuf, EdgeHQ edgeOp)
26  __restrict;
27 };
28 
29 template<typename Pixel>
31  const Pixel* __restrict in0, const Pixel* __restrict in1,
32  const Pixel* __restrict in2,
33  Pixel* __restrict out0, Pixel* __restrict out1,
34  Pixel* __restrict out2,
35  unsigned srcWidth, unsigned* __restrict edgeBuf,
36  EdgeHQ edgeOp) __restrict
37 {
38  unsigned c2 = readPixel(in0[0]); unsigned c3 = c2;
39  unsigned c5 = readPixel(in1[0]); unsigned c6 = c5;
40  unsigned c8 = readPixel(in2[0]); unsigned c9 = c8;
41 
42  unsigned pattern = 0;
43  if (edgeOp(c5, c8)) pattern |= 3 << 6;
44  if (edgeOp(c5, c2)) pattern |= 3 << 9;
45 
46  for (auto x : xrange(srcWidth)) {
47  unsigned c1 = c2;
48  unsigned c4 = c5;
49  unsigned c7 = c8;
50  c2 = c3;
51  c5 = c6;
52  c8 = c9;
53  if (x != srcWidth - 1) {
54  c3 = readPixel(in0[x + 1]);
55  c6 = readPixel(in1[x + 1]);
56  c9 = readPixel(in2[x + 1]);
57  }
58 
59  pattern = (pattern >> 6) & 0x001F; // left overlap
60  // overlaps with left
61  //if (edgeOp(c8, c4)) pattern |= 1 << 0; // B - l: c5-c9 6
62  //if (edgeOp(c5, c7)) pattern |= 1 << 1; // B - l: c6-c8 7
63  //if (edgeOp(c5, c4)) pattern |= 1 << 2; // l: c5-c6 8
64  // overlaps with top and left
65  //if (edgeOp(c5, c1)) pattern |= 1 << 3; // l: c2-c6 9, t: c4-c8 0
66  //if (edgeOp(c4, c2)) pattern |= 1 << 4; // l: c5-c3 10, t: c5-c7 1
67  // non-overlapping pixels
68  if (edgeOp(c5, c8)) pattern |= 1 << 5; // B
69  if (edgeOp(c5, c9)) pattern |= 1 << 6; // BR
70  if (edgeOp(c6, c8)) pattern |= 1 << 7; // BR
71  if (edgeOp(c5, c6)) pattern |= 1 << 8; // R
72  // overlaps with top
73  //if (edgeOp(c2, c6)) pattern |= 1 << 9; // R - t: c5-c9 6
74  //if (edgeOp(c5, c3)) pattern |= 1 << 10; // R - t: c6-c8 7
75  //if (edgeOp(c5, c2)) pattern |= 1 << 11; // t: c5-c8 5
76  pattern |= ((edgeBuf[x] & (1 << 5) ) << 6) |
77  ((edgeBuf[x] & ((1 << 6) | (1 << 7))) << 3);
78  edgeBuf[x] = pattern;
79 
80  unsigned pixel0, pixel1, pixel2, pixel3, pixel4,
81  pixel5, pixel6, pixel7, pixel8;
82 
83 #include "HQ3xScaler-1x1to3x3.nn"
84 
85  out0[3 * x + 0] = writePixel<Pixel>(pixel0);
86  out0[3 * x + 1] = writePixel<Pixel>(pixel1);
87  out0[3 * x + 2] = writePixel<Pixel>(pixel2);
88  out1[3 * x + 0] = writePixel<Pixel>(pixel3);
89  out1[3 * x + 1] = writePixel<Pixel>(pixel4);
90  out1[3 * x + 2] = writePixel<Pixel>(pixel5);
91  out2[3 * x + 0] = writePixel<Pixel>(pixel6);
92  out2[3 * x + 1] = writePixel<Pixel>(pixel7);
93  out2[3 * x + 2] = writePixel<Pixel>(pixel8);
94  }
95 }
96 
97 
98 
99 template<typename Pixel>
101  : Scaler3<Pixel>(pixelOps_)
102  , pixelOps(pixelOps_)
103 {
104 }
105 
106 template<typename 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  EdgeHQ edgeOp = createEdgeHQ(pixelOps);
113  doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
114  src, srcStartY, srcEndY, srcWidth,
115  dst, dstStartY, dstEndY, (srcWidth * 9) / 2);
116 }
117 
118 template<typename Pixel>
120  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
121  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
122 {
124  EdgeHQ edgeOp = createEdgeHQ(pixelOps);
125  doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
126  src, srcStartY, srcEndY, srcWidth,
127  dst, dstStartY, dstEndY, srcWidth * 3);
128 }
129 
130 template<typename 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  EdgeHQ edgeOp = createEdgeHQ(pixelOps);
137  doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
138  src, srcStartY, srcEndY, srcWidth,
139  dst, dstStartY, dstEndY, (srcWidth * 9) / 4);
140 }
141 
142 template<typename 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  EdgeHQ edgeOp = createEdgeHQ(pixelOps);
149  doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
150  src, srcStartY, srcEndY, srcWidth,
151  dst, dstStartY, dstEndY, (srcWidth * 3) / 2);
152 }
153 
154 template<typename 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  EdgeHQ edgeOp = createEdgeHQ(pixelOps);
161  doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
162  src, srcStartY, srcEndY, srcWidth,
163  dst, dstStartY, dstEndY, (srcWidth * 9) / 8);
164 }
165 
166 template<typename 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  EdgeHQ edgeOp = createEdgeHQ(pixelOps);
173  doHQScale3<Pixel>(HQ_1x1on3x3<Pixel>(), edgeOp, postScale,
174  src, srcStartY, srcEndY, srcWidth,
175  dst, dstStartY, dstEndY, (srcWidth * 3) / 4);
176 }
177 
178 // Force template instantiation.
179 #if HAVE_16BPP
180 template class HQ3xScaler<uint16_t>;
181 #endif
182 #if HAVE_32BPP
183 template class HQ3xScaler<uint32_t>;
184 #endif
185 
186 } // namespace openmsx
Interface for getting lines from a video frame.
Definition: FrameSource.hh:15
Runs the hq3x scaler algorithm.
Definition: HQ3xScaler.hh:13
void scale1x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:119
void scale4x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:167
void scale4x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:131
void scale2x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:107
void scale2x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:143
HQ3xScaler(const PixelOperations< Pixel > &pixelOps)
Definition: HQ3xScaler.cc:100
void scale8x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Definition: HQ3xScaler.cc:155
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
EdgeHQ createEdgeHQ(const PixelOperations< Pixel > &pixelOps)
Definition: HQCommon.hh:86
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:124
uint32_t readPixel(Pixel p)
Definition: HQCommon.hh:19
void operator()(const Pixel *in0, const Pixel *in1, const Pixel *in2, Pixel *out0, Pixel *out1, Pixel *out2, unsigned srcWidth, unsigned *edgeBuf, EdgeHQ edgeOp)
Definition: HQ3xScaler.cc:30
constexpr auto xrange(T e)
Definition: xrange.hh:155