openMSX
StretchScalerOutput.cc
Go to the documentation of this file.
1 #include "StretchScalerOutput.hh"
2 #include "DirectScalerOutput.hh"
3 #include "LineScalers.hh"
4 #include "PixelOperations.hh"
5 #include "MemoryOps.hh"
6 #include "build-info.hh"
7 #include <cstdint>
8 #include <memory>
9 #include <vector>
10 
11 namespace openmsx {
12 
13 template<typename Pixel>
15 {
16 public:
19  ~StretchScalerOutputBase() override;
22 
23  [[nodiscard]] unsigned getWidth() const override;
24  [[nodiscard]] unsigned getHeight() const override;
25  [[nodiscard]] Pixel* acquireLine(unsigned y) override;
26  void fillLine(unsigned y, Pixel color) override;
27 
28 protected:
29  [[nodiscard]] Pixel* releasePre(unsigned y, Pixel* buf);
30  void releasePost(unsigned y, Pixel* dstLine);
31 
33 
34 private:
36  std::vector<Pixel*> pool;
37 };
38 
39 template<typename Pixel>
41 {
42 public:
45  unsigned inWidth);
46  void releaseLine(unsigned y, Pixel* buf) override;
47 
48 private:
49  unsigned inWidth;
50 };
51 
52 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
54 {
55 public:
58  void releaseLine(unsigned y, Pixel* buf) override;
59 };
60 
61 template<typename Pixel>
63  : public StretchScalerOutputN<Pixel, 256, Scale_4on5<Pixel>>
64 {
65 public:
68 };
69 
70 template<typename Pixel>
72  : public StretchScalerOutputN<Pixel, 272, Scale_17on20<Pixel>>
73 {
74 public:
77 };
78 
79 template<typename Pixel>
81  : public StretchScalerOutputN<Pixel, 280, Scale_7on8<Pixel>>
82 {
83 public:
86 };
87 
88 template<typename Pixel>
90  : public StretchScalerOutputN<Pixel, 288, Scale_9on10<Pixel>>
91 {
92 public:
95 };
96 
97 
98 // class StretchScalerOutputBase
99 
100 template<typename Pixel>
102  SDLOutputSurface& out,
103  PixelOperations<Pixel> pixelOps_)
104  : pixelOps(std::move(pixelOps_))
105  , output(out)
106 {
107 }
108 
109 template<typename Pixel>
111 {
112  for (auto& p : pool) {
114  }
115 }
116 
117 template<typename Pixel>
119 {
120  return output.getWidth();
121 }
122 
123 template<typename Pixel>
125 {
126  return output.getHeight();
127 }
128 
129 template<typename Pixel>
131 {
132  if (!pool.empty()) {
133  Pixel* buf = pool.back();
134  pool.pop_back();
135  return buf;
136  } else {
137  unsigned size = sizeof(Pixel) * output.getWidth();
138  return static_cast<Pixel*>(MemoryOps::mallocAligned(64, size));
139  }
140 }
141 
142 template<typename Pixel>
144 {
145  pool.push_back(buf);
146  return output.acquireLine(y);
147 }
148 
149 template<typename Pixel>
151 {
152  output.releaseLine(y, dstLine);
153 }
154 
155 template<typename Pixel>
157 {
158  Pixel* dstLine = output.acquireLine(y);
160  memset(dstLine, output.getWidth(), color);
161  output.releaseLine(y, dstLine);
162 }
163 
164 
165 // class StretchScalerOutput
166 
167 template<typename Pixel>
169  SDLOutputSurface& out,
170  PixelOperations<Pixel> pixelOps_,
171  unsigned inWidth_)
172  : StretchScalerOutputBase<Pixel>(out, std::move(pixelOps_))
173  , inWidth(inWidth_)
174 {
175 }
176 
177 template<typename Pixel>
179 {
180  Pixel* dstLine = this->releasePre(y, buf);
181 
182  unsigned dstWidth = StretchScalerOutputBase<Pixel>::getWidth();
183  unsigned srcWidth = (dstWidth / 320) * inWidth;
184  unsigned srcOffset = (dstWidth - srcWidth) / 2;
185  ZoomLine<Pixel> zoom(this->pixelOps);
186  zoom(buf + srcOffset, srcWidth, dstLine, dstWidth);
187 
188  this->releasePost(y, dstLine);
189 }
190 
191 
192 // class StretchScalerOutputN
193 
194 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
196  SDLOutputSurface& out,
197  PixelOperations<Pixel> pixelOps_)
198  : StretchScalerOutputBase<Pixel>(out, std::move(pixelOps_))
199 {
200 }
201 
202 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
204 {
205  Pixel* dstLine = this->releasePre(y, buf);
206 
207  unsigned dstWidth = StretchScalerOutputBase<Pixel>::getWidth();
208  unsigned srcWidth = (dstWidth / 320) * IN_WIDTH;
209  unsigned srcOffset = (dstWidth - srcWidth) / 2;
210  SCALE scale(this->pixelOps);
211  scale(buf + srcOffset, dstLine, dstWidth);
212 
213  this->releasePost(y, dstLine);
214 }
215 
216 
217 // class StretchScalerOutput256
218 
219 template<typename Pixel>
221  SDLOutputSurface& out,
222  PixelOperations<Pixel> pixelOps_)
224  out, std::move(pixelOps_))
225 {
226 }
227 
228 
229 // class StretchScalerOutput272
230 
231 template<typename Pixel>
233  SDLOutputSurface& out,
234  PixelOperations<Pixel> pixelOps_)
236  out, std::move(pixelOps_))
237 {
238 }
239 
240 
241 // class StretchScalerOutput280
242 
243 template<typename Pixel>
245  SDLOutputSurface& out,
246  PixelOperations<Pixel> pixelOps_)
248  out, std::move(pixelOps_))
249 {
250 }
251 
252 
253 // class StretchScalerOutput288
254 
255 template<typename Pixel>
257  SDLOutputSurface& out,
258  PixelOperations<Pixel> pixelOps_)
260  out, std::move(pixelOps_))
261 {
262 }
263 
264 
265 // class StretchScalerOutputFactory
266 
267 template<typename Pixel>
268 std::unique_ptr<ScalerOutput<Pixel>> StretchScalerOutputFactory<Pixel>::create(
269  SDLOutputSurface& output,
270  PixelOperations<Pixel> pixelOps,
271  unsigned inWidth)
272 {
273  switch (inWidth) {
274  case 320:
275  return std::make_unique<DirectScalerOutput<Pixel>>(output);
276  case 288:
277  return std::make_unique<StretchScalerOutput288<Pixel>>(
278  output, std::move(pixelOps));
279  case 280:
280  return std::make_unique<StretchScalerOutput280<Pixel>>(
281  output, std::move(pixelOps));
282  case 272:
283  return std::make_unique<StretchScalerOutput272<Pixel>>(
284  output, std::move(pixelOps));
285  case 256:
286  return std::make_unique<StretchScalerOutput256<Pixel>>(
287  output, std::move(pixelOps));
288  default:
289  return std::make_unique<StretchScalerOutput<Pixel>>(
290  output, std::move(pixelOps), inWidth);
291  }
292 }
293 
294 // Force template instantiation.
295 #if HAVE_16BPP
297 #endif
298 #if HAVE_32BPP
300 #endif
301 
302 } // namespace openmsx
A frame buffer where pixels can be written to.
StretchScalerOutput256(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps)
StretchScalerOutput272(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps)
StretchScalerOutput280(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps)
StretchScalerOutput288(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps)
unsigned getHeight() const override
void fillLine(unsigned y, Pixel color) override
Pixel * acquireLine(unsigned y) override
Pixel * releasePre(unsigned y, Pixel *buf)
StretchScalerOutputBase(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps)
void releasePost(unsigned y, Pixel *dstLine)
unsigned getWidth() const override
const PixelOperations< Pixel > pixelOps
StretchScalerOutputBase(const StretchScalerOutputBase &)=delete
StretchScalerOutputBase & operator=(const StretchScalerOutputBase &)=delete
StretchScalerOutputN(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps)
void releaseLine(unsigned y, Pixel *buf) override
void releaseLine(unsigned y, Pixel *buf) override
StretchScalerOutput(SDLOutputSurface &out, PixelOperations< Pixel > pixelOps, unsigned inWidth)
Stretch (or zoom) a given input line to a wider output line.
Definition: LineScalers.hh:240
constexpr mat4 scale(const vec3 &xyz)
Definition: gl_transform.hh:19
void * mallocAligned(size_t alignment, size_t size)
Definition: MemoryOps.cc:255
void freeAligned(void *)
Definition: MemoryOps.cc:285
This file implemented 3 utility functions:
Definition: Autofire.cc:9
uint32_t Pixel
constexpr int SCALE
Definition: ArkanoidPad.cc:24
size_t size(std::string_view utf8)
static std::unique_ptr< ScalerOutput< Pixel > > create(SDLOutputSurface &output, PixelOperations< Pixel > pixelOps, unsigned inWidth)