openMSX
Scaler3.cc
Go to the documentation of this file.
1 #include "Scaler3.hh"
2 #include "LineScalers.hh"
3 #include "FrameSource.hh"
5 #include "unreachable.hh"
6 #include "vla.hh"
7 #include "xrange.hh"
8 #include "build-info.hh"
9 #include <cstdint>
10 
11 namespace openmsx {
12 
13 template<typename Pixel>
15  : pixelOps(pixelOps_)
16 {
17 }
18 
19 template<typename Pixel>
21  FrameSource& src, unsigned srcStartY, unsigned /*srcEndY*/,
22  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
23 {
24  for (unsigned srcY = srcStartY, dstY = dstStartY;
25  dstY < dstEndY; srcY += 1, dstY += 3) {
26  auto color = src.getLineColor<Pixel>(srcY);
27  for (auto i : xrange(3)) {
28  dst.fillLine(dstY + i, color);
29  }
30  }
31 }
32 
33 template<typename Pixel>
35  FrameSource& src, unsigned srcStartY, unsigned /*srcEndY*/,
36  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
37 {
38  for (unsigned srcY = srcStartY, dstY = dstStartY;
39  dstY < dstEndY; srcY += 2, dstY += 3) {
40  auto color0 = src.getLineColor<Pixel>(srcY + 0);
41  auto color1 = src.getLineColor<Pixel>(srcY + 1);
42  Pixel color01 = pixelOps.template blend<1, 1>(color0, color1);
43  dst.fillLine(dstY + 0, color0);
44  dst.fillLine(dstY + 1, color01);
45  dst.fillLine(dstY + 2, color1);
46  }
47 }
48 
49 template<typename Pixel>
50 static void doScale1(FrameSource& src,
51  unsigned srcStartY, unsigned /*srcEndY*/, unsigned srcWidth,
52  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY,
54 {
55  VLA_SSE_ALIGNED(Pixel, buf, srcWidth);
57  unsigned dstWidth = dst.getWidth();
58  for (unsigned dstY = dstStartY; dstY < dstEndY; dstY += 3, ++srcStartY) {
59  auto* srcLine = src.getLinePtr(srcStartY, srcWidth, buf);
60  auto* dstLine0 = dst.acquireLine(dstY + 0);
61  scale(srcLine, dstLine0, dstWidth);
62 
63  auto* dstLine1 = dst.acquireLine(dstY + 1);
64  copy(dstLine0, dstLine1, dstWidth);
65 
66  auto* dstLine2 = dst.acquireLine(dstY + 2);
67  copy(dstLine0, dstLine2, dstWidth);
68 
69  dst.releaseLine(dstY + 0, dstLine0);
70  dst.releaseLine(dstY + 1, dstLine1);
71  dst.releaseLine(dstY + 2, dstLine2);
72  }
73 }
74 
75 template<typename Pixel>
76 static void doScaleDV(FrameSource& src,
77  unsigned srcStartY, unsigned /*srcEndY*/, unsigned srcWidth,
78  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY,
79  PixelOperations<Pixel> ops, PolyLineScaler<Pixel>& scale)
80 {
81  VLA_SSE_ALIGNED(Pixel, buf, srcWidth);
82  BlendLines<Pixel> blend(ops);
83  unsigned dstWidth = dst.getWidth();
84  for (unsigned srcY = srcStartY, dstY = dstStartY; dstY < dstEndY;
85  srcY += 2, dstY += 3) {
86  auto* srcLine0 = src.getLinePtr(srcY + 0, srcWidth, buf);
87  auto* dstLine0 = dst.acquireLine(dstY + 0);
88  scale(srcLine0, dstLine0, dstWidth);
89 
90  auto* srcLine1 = src.getLinePtr(srcY + 1, srcWidth, buf);
91  auto* dstLine2 = dst.acquireLine(dstY + 2);
92  scale(srcLine1, dstLine2, dstWidth);
93 
94  auto* dstLine1 = dst.acquireLine(dstY + 1);
95  blend(dstLine0, dstLine2, dstLine1, dstWidth);
96 
97  dst.releaseLine(dstY + 0, dstLine0);
98  dst.releaseLine(dstY + 1, dstLine1);
99  dst.releaseLine(dstY + 2, dstLine2);
100  }
101 }
102 
103 template<typename Pixel>
105  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
106  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
107 {
109  doScale1<Pixel>(src, srcStartY, srcEndY, srcWidth,
110  dst, dstStartY, dstEndY, op);
111 }
112 
113 template<typename Pixel>
115  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
116  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
117 {
119  doScaleDV<Pixel>(src, srcStartY, srcEndY, srcWidth,
120  dst, dstStartY, dstEndY, pixelOps, op);
121 }
122 
123 template<typename Pixel>
125  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
126  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
127 {
129  doScale1<Pixel>(src, srcStartY, srcEndY, srcWidth,
130  dst, dstStartY, dstEndY, op);
131 }
132 
133 template<typename Pixel>
135  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
136  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
137 {
139  doScaleDV<Pixel>(src, srcStartY, srcEndY, srcWidth,
140  dst, dstStartY, dstEndY, pixelOps, op);
141 }
142 
143 template<typename Pixel>
145  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
146  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
147 {
149  doScale1<Pixel>(src, srcStartY, srcEndY, srcWidth,
150  dst, dstStartY, dstEndY, op);
151 }
152 
153 template<typename Pixel>
155  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
156  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
157 {
159  doScaleDV<Pixel>(src, srcStartY, srcEndY, srcWidth,
160  dst, dstStartY, dstEndY, pixelOps, op);
161 }
162 
163 template<typename Pixel>
165  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
166  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
167 {
169  doScale1<Pixel>(src, srcStartY, srcEndY, srcWidth,
170  dst, dstStartY, dstEndY, op);
171 }
172 
173 template<typename Pixel>
175  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
176  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
177 {
179  doScaleDV<Pixel>(src, srcStartY, srcEndY, srcWidth,
180  dst, dstStartY, dstEndY, pixelOps, op);
181 }
182 
183 template<typename Pixel>
185  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
186  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
187 {
189  doScale1<Pixel>(src, srcStartY, srcEndY, srcWidth,
190  dst, dstStartY, dstEndY, op);
191 }
192 
193 template<typename Pixel>
195  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
196  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
197 {
199  doScaleDV<Pixel>(src, srcStartY, srcEndY, srcWidth,
200  dst, dstStartY, dstEndY, pixelOps, op);
201 }
202 
203 template<typename Pixel>
205  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
206  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
207 {
209  doScale1<Pixel>(src, srcStartY, srcEndY, srcWidth,
210  dst, dstStartY, dstEndY, op);
211 }
212 
213 template<typename Pixel>
215  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
216  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
217 {
219  doScaleDV<Pixel>(src, srcStartY, srcEndY, srcWidth,
220  dst, dstStartY, dstEndY, pixelOps, op);
221 }
222 
223 template<typename Pixel>
225  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
226  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
227 {
228  if (src.getHeight() == 240) {
229  switch (srcWidth) {
230  case 1:
231  scaleBlank1to3(src, srcStartY, srcEndY,
232  dst, dstStartY, dstEndY);
233  break;
234  case 213:
235  scale2x1to9x3(src, srcStartY, srcEndY, srcWidth,
236  dst, dstStartY, dstEndY);
237  break;
238  case 320:
239  scale1x1to3x3(src, srcStartY, srcEndY, srcWidth,
240  dst, dstStartY, dstEndY);
241  break;
242  case 426:
243  scale4x1to9x3(src, srcStartY, srcEndY, srcWidth,
244  dst, dstStartY, dstEndY);
245  break;
246  case 640:
247  scale2x1to3x3(src, srcStartY, srcEndY, srcWidth,
248  dst, dstStartY, dstEndY);
249  break;
250  case 853:
251  scale8x1to9x3(src, srcStartY, srcEndY, srcWidth,
252  dst, dstStartY, dstEndY);
253  break;
254  case 1280:
255  scale4x1to3x3(src, srcStartY, srcEndY, srcWidth,
256  dst, dstStartY, dstEndY);
257  break;
258  default:
259  UNREACHABLE;
260  }
261  } else {
262  assert(src.getHeight() == 480);
263  switch (srcWidth) {
264  case 1:
265  scaleBlank2to3(src, srcStartY, srcEndY,
266  dst, dstStartY, dstEndY);
267  break;
268  case 213:
269  scale2x2to9x3(src, srcStartY, srcEndY, srcWidth,
270  dst, dstStartY, dstEndY);
271  break;
272  case 320:
273  scale1x2to3x3(src, srcStartY, srcEndY, srcWidth,
274  dst, dstStartY, dstEndY);
275  break;
276  case 426:
277  scale4x2to9x3(src, srcStartY, srcEndY, srcWidth,
278  dst, dstStartY, dstEndY);
279  break;
280  case 640:
281  scale2x2to3x3(src, srcStartY, srcEndY, srcWidth,
282  dst, dstStartY, dstEndY);
283  break;
284  case 853:
285  scale8x2to9x3(src, srcStartY, srcEndY, srcWidth,
286  dst, dstStartY, dstEndY);
287  break;
288  case 1280:
289  scale4x2to3x3(src, srcStartY, srcEndY, srcWidth,
290  dst, dstStartY, dstEndY);
291  break;
292  default:
293  UNREACHABLE;
294  }
295  }
296 }
297 
298 template<typename Pixel>
299 void Scaler3<Pixel>::scaleImage(FrameSource& src, const RawFrame* superImpose,
300  unsigned srcStartY, unsigned srcEndY, unsigned srcWidth,
301  ScalerOutput<Pixel>& dst, unsigned dstStartY, unsigned dstEndY)
302 {
303  if (superImpose) {
305  dst, *superImpose, pixelOps);
306  dispatchScale(src, srcStartY, srcEndY, srcWidth,
307  dst2, dstStartY, dstEndY);
308  } else {
309  dispatchScale(src, srcStartY, srcEndY, srcWidth,
310  dst, dstStartY, dstEndY);
311  }
312 }
313 
314 // Force template instantiation.
315 #if HAVE_16BPP
316 template class Scaler3<uint16_t>;
317 #endif
318 #if HAVE_32BPP
319 template class Scaler3<uint32_t>;
320 #endif
321 
322 } // namespace openmsx
Interface for getting lines from a video frame.
Definition: FrameSource.hh:16
Pixel getLineColor(unsigned line) const
Get the (single) color of the given line.
Definition: FrameSource.hh:75
unsigned getHeight() const
Gets the number of lines in this frame.
Definition: FrameSource.hh:45
const Pixel * getLinePtr(int line, unsigned width, Pixel *buf) const
Gets a pointer to the pixels of the given line number.
Definition: FrameSource.hh:92
Polymorphic line scaler.
Definition: LineScalers.hh:285
Polymorphic wrapper around another line scaler.
Definition: LineScalers.hh:313
A video frame as output by the VDP scanline conversion unit, before any postprocessing filters are ap...
Definition: RawFrame.hh:14
Base class for 3x scalers.
Definition: Scaler3.hh:12
virtual void scale2x2to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:114
virtual void scale1x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:124
void scaleImage(FrameSource &src, const RawFrame *superImpose, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY) override
Scales the image in the given area, which must consist of lines which are all equally wide.
Definition: Scaler3.cc:299
virtual void scale4x2to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:154
virtual void scaleBlank1to3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:20
virtual void scale4x2to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:214
virtual void scale2x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:104
virtual void scale1x2to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:134
Scaler3(const PixelOperations< Pixel > &pixelOps)
Definition: Scaler3.cc:14
virtual void scale4x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:204
virtual void scale2x1to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:164
virtual void scale4x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:144
virtual void scale2x2to3x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:174
virtual void scale8x1to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:184
virtual void scaleBlank2to3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:34
virtual void scale8x2to9x3(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:194
void dispatchScale(FrameSource &src, unsigned srcStartY, unsigned srcEndY, unsigned srcWidth, ScalerOutput< Pixel > &dst, unsigned dstStartY, unsigned dstEndY)
Definition: Scaler3.cc:224
virtual Pixel * acquireLine(unsigned y)=0
virtual unsigned getWidth() const =0
virtual void fillLine(unsigned y, Pixel color)=0
virtual void releaseLine(unsigned y, Pixel *buf)=0
constexpr mat4 scale(const vec3 &xyz)
Definition: gl_transform.hh:19
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:179
#define UNREACHABLE
Definition: unreachable.hh:38
#define VLA_SSE_ALIGNED(TYPE, NAME, LENGTH)
Definition: vla.hh:44
constexpr auto xrange(T e)
Definition: xrange.hh:155