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 using std::unique_ptr;
12 
13 namespace openmsx {
14 
15 template<typename Pixel>
17 {
18 public:
21  ~StretchScalerOutputBase() override;
24 
25  [[nodiscard]] unsigned getWidth() const override;
26  [[nodiscard]] unsigned getHeight() const override;
27  [[nodiscard]] Pixel* acquireLine(unsigned y) override;
28  void fillLine(unsigned y, Pixel color) override;
29 
30 protected:
31  [[nodiscard]] Pixel* releasePre(unsigned y, Pixel* buf);
32  void releasePost(unsigned y, Pixel* dstLine);
33 
35 
36 private:
38  std::vector<Pixel*> pool;
39 };
40 
41 template<typename Pixel>
43 {
44 public:
47  unsigned inWidth);
48  void releaseLine(unsigned y, Pixel* buf) override;
49 
50 private:
51  unsigned inWidth;
52 };
53 
54 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
56 {
57 public:
60  void releaseLine(unsigned y, Pixel* buf) override;
61 };
62 
63 template<typename Pixel>
65  : public StretchScalerOutputN<Pixel, 256, Scale_4on5<Pixel>>
66 {
67 public:
70 };
71 
72 template<typename Pixel>
74  : public StretchScalerOutputN<Pixel, 272, Scale_17on20<Pixel>>
75 {
76 public:
79 };
80 
81 template<typename Pixel>
83  : public StretchScalerOutputN<Pixel, 280, Scale_7on8<Pixel>>
84 {
85 public:
88 };
89 
90 template<typename Pixel>
92  : public StretchScalerOutputN<Pixel, 288, Scale_9on10<Pixel>>
93 {
94 public:
97 };
98 
99 
100 // class StretchScalerOutputBase
101 
102 template<typename Pixel>
104  SDLOutputSurface& out,
105  PixelOperations<Pixel> pixelOps_)
106  : pixelOps(std::move(pixelOps_))
107  , output(out)
108 {
109 }
110 
111 template<typename Pixel>
113 {
114  for (auto& p : pool) {
116  }
117 }
118 
119 template<typename Pixel>
121 {
122  return output.getWidth();
123 }
124 
125 template<typename Pixel>
127 {
128  return output.getHeight();
129 }
130 
131 template<typename Pixel>
133 {
134  if (!pool.empty()) {
135  Pixel* buf = pool.back();
136  pool.pop_back();
137  return buf;
138  } else {
139  unsigned size = sizeof(Pixel) * output.getWidth();
140  return static_cast<Pixel*>(MemoryOps::mallocAligned(64, size));
141  }
142 }
143 
144 template<typename Pixel>
146 {
147  pool.push_back(buf);
148  return output.acquireLine(y);
149 }
150 
151 template<typename Pixel>
153 {
154  output.releaseLine(y, dstLine);
155 }
156 
157 template<typename Pixel>
159 {
160  Pixel* dstLine = output.acquireLine(y);
162  memset(dstLine, output.getWidth(), color);
163  output.releaseLine(y, dstLine);
164 }
165 
166 
167 // class StretchScalerOutput
168 
169 template<typename Pixel>
171  SDLOutputSurface& out,
172  PixelOperations<Pixel> pixelOps_,
173  unsigned inWidth_)
174  : StretchScalerOutputBase<Pixel>(out, std::move(pixelOps_))
175  , inWidth(inWidth_)
176 {
177 }
178 
179 template<typename Pixel>
181 {
182  Pixel* dstLine = this->releasePre(y, buf);
183 
184  unsigned dstWidth = StretchScalerOutputBase<Pixel>::getWidth();
185  unsigned srcWidth = (dstWidth / 320) * inWidth;
186  unsigned srcOffset = (dstWidth - srcWidth) / 2;
187  ZoomLine<Pixel> zoom(this->pixelOps);
188  zoom(buf + srcOffset, srcWidth, dstLine, dstWidth);
189 
190  this->releasePost(y, dstLine);
191 }
192 
193 
194 // class StretchScalerOutputN
195 
196 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
198  SDLOutputSurface& out,
199  PixelOperations<Pixel> pixelOps_)
200  : StretchScalerOutputBase<Pixel>(out, std::move(pixelOps_))
201 {
202 }
203 
204 template<typename Pixel, unsigned IN_WIDTH, typename SCALE>
206 {
207  Pixel* dstLine = this->releasePre(y, buf);
208 
209  unsigned dstWidth = StretchScalerOutputBase<Pixel>::getWidth();
210  unsigned srcWidth = (dstWidth / 320) * IN_WIDTH;
211  unsigned srcOffset = (dstWidth - srcWidth) / 2;
212  SCALE scale(this->pixelOps);
213  scale(buf + srcOffset, dstLine, dstWidth);
214 
215  this->releasePost(y, dstLine);
216 }
217 
218 
219 // class StretchScalerOutput256
220 
221 template<typename Pixel>
223  SDLOutputSurface& out,
224  PixelOperations<Pixel> pixelOps_)
226  out, std::move(pixelOps_))
227 {
228 }
229 
230 
231 // class StretchScalerOutput272
232 
233 template<typename Pixel>
235  SDLOutputSurface& out,
236  PixelOperations<Pixel> pixelOps_)
238  out, std::move(pixelOps_))
239 {
240 }
241 
242 
243 // class StretchScalerOutput280
244 
245 template<typename Pixel>
247  SDLOutputSurface& out,
248  PixelOperations<Pixel> pixelOps_)
250  out, std::move(pixelOps_))
251 {
252 }
253 
254 
255 // class StretchScalerOutput288
256 
257 template<typename Pixel>
259  SDLOutputSurface& out,
260  PixelOperations<Pixel> pixelOps_)
262  out, std::move(pixelOps_))
263 {
264 }
265 
266 
267 // class StretchScalerOutputFactory
268 
269 template<typename Pixel>
270 unique_ptr<ScalerOutput<Pixel>> StretchScalerOutputFactory<Pixel>::create(
271  SDLOutputSurface& output,
272  PixelOperations<Pixel> pixelOps,
273  unsigned inWidth)
274 {
275  switch (inWidth) {
276  case 320:
277  return std::make_unique<DirectScalerOutput<Pixel>>(output);
278  case 288:
279  return std::make_unique<StretchScalerOutput288<Pixel>>(
280  output, std::move(pixelOps));
281  case 280:
282  return std::make_unique<StretchScalerOutput280<Pixel>>(
283  output, std::move(pixelOps));
284  case 272:
285  return std::make_unique<StretchScalerOutput272<Pixel>>(
286  output, std::move(pixelOps));
287  case 256:
288  return std::make_unique<StretchScalerOutput256<Pixel>>(
289  output, std::move(pixelOps));
290  default:
291  return std::make_unique<StretchScalerOutput<Pixel>>(
292  output, std::move(pixelOps), inWidth);
293  }
294 }
295 
296 // Force template instantiation.
297 #if HAVE_16BPP
299 #endif
300 #if HAVE_32BPP
302 #endif
303 
304 } // 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:254
void freeAligned(void *)
Definition: MemoryOps.cc:284
This file implemented 3 utility functions:
Definition: Autofire.cc:5
uint32_t Pixel
constexpr int SCALE
Definition: ArkanoidPad.cc:29
size_t size(std::string_view utf8)
static std::unique_ptr< ScalerOutput< Pixel > > create(SDLOutputSurface &output, PixelOperations< Pixel > pixelOps, unsigned inWidth)