13 template <
typename Pixel>
14 static inline unsigned readPixel(
Pixel p)
17 if (
sizeof(
Pixel) == 2) {
18 return ((p & 0xF800) << 8) |
22 return p & 0xF8F8F8F8;
26 template <
typename Pixel>
27 static inline Pixel writePixel(
unsigned p)
30 if (
sizeof(
Pixel) == 2) {
31 return ((p & 0xF80000) >> 8) |
32 ((p & 0x00FC00) >> 5) |
33 ((p & 0x0000F8) >> 3);
35 return (p & 0xF8F8F8F8) | ((p & 0xE0E0E0E0) >> 5);
42 EdgeHQ(
unsigned shiftR_,
unsigned shiftG_,
unsigned shiftB_)
43 : shiftR(shiftR_), shiftG(shiftG_), shiftB(shiftB_)
49 if (c1 == c2)
return false;
51 unsigned r1 = (c1 >> shiftR) & 0xFF;
52 unsigned g1 = (c1 >> shiftG) & 0xFF;
53 unsigned b1 = (c1 >> shiftB) & 0xFF;
55 unsigned r2 = (c2 >> shiftR) & 0xFF;
56 unsigned g2 = (c2 >> shiftG) & 0xFF;
57 unsigned b2 = (c2 >> shiftB) & 0xFF;
63 int dy = dr + dg + db;
64 if (dy < -0xC0 || dy > 0xC0)
return true;
67 if (du < -0x1C || du > 0x1C)
return true;
70 if (dv < -0x30 || dv > 0x30)
return true;
75 const unsigned shiftR;
76 const unsigned shiftG;
77 const unsigned shiftB;
80 template<
typename Pixel>
83 if (
sizeof(
Pixel) == 2) {
100 template <
typename EdgeOp>
101 void calcEdgesGL(
const unsigned* __restrict curr,
const unsigned* __restrict next,
102 unsigned* __restrict edges2, EdgeOp edgeOp)
104 typedef unsigned Pixel;
105 if (OPENMSX_BIGENDIAN) {
106 unsigned pattern = 0;
109 if (edgeOp(c5, c8)) pattern |= 0x1400;
111 for (
unsigned xx = 0; xx < (320 - 2) / 2; ++xx) {
112 pattern = (pattern << (16 + 1)) & 0xA8000000;
113 pattern |= ((edges2[xx] >> 5) & 0x01F001F0);
115 if (edgeOp(c5, c8)) pattern |= 0x02000000;
116 Pixel c6 = curr[2 * xx + 1];
117 if (edgeOp(c6, c8)) pattern |= 0x10002000;
118 if (edgeOp(c5, c6)) pattern |= 0x40008000;
119 Pixel c9 = next[2 * xx + 1];
120 if (edgeOp(c5, c9)) pattern |= 0x04000800;
122 if (edgeOp(c6, c9)) pattern |= 0x0200;
123 c5 = curr[2 * xx + 2];
124 if (edgeOp(c5, c9)) pattern |= 0x1000;
125 if (edgeOp(c6, c5)) pattern |= 0x4000;
126 c8 = next[2 * xx + 2];
127 if (edgeOp(c6, c8)) pattern |= 0x0400;
129 edges2[xx] = pattern;
132 pattern = (pattern << (16 + 1)) & 0xA8000000;
133 pattern |= ((edges2[159] >> 5) & 0x01F001F0);
135 if (edgeOp(c5, c8)) pattern |= 0x02000000;
136 Pixel c6 = curr[319];
137 if (edgeOp(c6, c8)) pattern |= 0x10002000;
138 if (edgeOp(c5, c6)) pattern |= 0x40008000;
139 Pixel c9 = next[319];
140 if (edgeOp(c5, c9)) pattern |= 0x04000800;
142 if (edgeOp(c6, c9)) pattern |= 0x1600;
144 edges2[159] = pattern;
146 unsigned pattern = 0;
149 if (edgeOp(c5, c8)) pattern |= 0x14000000;
151 for (
unsigned xx = 0; xx < (320 - 2) / 2; ++xx) {
152 pattern = (pattern >> (16 -1)) & 0xA800;
153 pattern |= ((edges2[xx] >> 5) & 0x01F001F0);
155 if (edgeOp(c5, c8)) pattern |= 0x0200;
156 Pixel c6 = curr[2 * xx + 1];
157 if (edgeOp(c6, c8)) pattern |= 0x20001000;
158 if (edgeOp(c5, c6)) pattern |= 0x80004000;
159 Pixel c9 = next[2 * xx + 1];
160 if (edgeOp(c5, c9)) pattern |= 0x08000400;
162 if (edgeOp(c6, c9)) pattern |= 0x02000000;
163 c5 = curr[2 * xx + 2];
164 if (edgeOp(c5, c9)) pattern |= 0x10000000;
165 if (edgeOp(c6, c5)) pattern |= 0x40000000;
166 c8 = next[2 * xx + 2];
167 if (edgeOp(c6, c8)) pattern |= 0x04000000;
169 edges2[xx] = pattern;
172 pattern = (pattern >> (16 -1)) & 0xA800;
173 pattern |= ((edges2[159] >> 5) & 0x01F001F0);
175 if (edgeOp(c5, c8)) pattern |= 0x0200;
176 Pixel c6 = curr[319];
177 if (edgeOp(c6, c8)) pattern |= 0x20001000;
178 if (edgeOp(c5, c6)) pattern |= 0x80004000;
179 Pixel c9 = next[319];
180 if (edgeOp(c5, c9)) pattern |= 0x08000400;
182 if (edgeOp(c6, c9)) pattern |= 0x16000000;
184 edges2[159] = pattern;
188 template <
typename Pixel,
typename EdgeOp>
189 static void calcInitialEdges(
190 const Pixel* __restrict srcPrev,
const Pixel* __restrict srcCurr,
191 unsigned srcWidth,
unsigned* __restrict edgeBuf, EdgeOp edgeOp)
194 unsigned c1 = readPixel(srcPrev[x]);
195 unsigned c2 = readPixel(srcCurr[x]);
196 unsigned pattern = edgeOp(c1, c2) ? ((1 << 6) | (1 << 7)) : 0;
197 for (; x < (srcWidth - 1); ++x) {
199 unsigned n1 = readPixel(srcPrev[x + 1]);
200 unsigned n2 = readPixel(srcCurr[x + 1]);
201 if (edgeOp(c1, c2)) pattern |= (1 << 5);
202 if (edgeOp(c1, n2)) pattern |= (1 << 6);
203 if (edgeOp(c2, n1)) pattern |= (1 << 7);
204 edgeBuf[x] = pattern;
208 if (edgeOp(c1, c2)) pattern |= (1 << 5) | (1 << 6) | (1 << 7);
209 edgeBuf[x] = pattern;
212 template <
typename Pixel,
typename HQScale,
typename EdgeOp>
213 static void doHQScale2(HQScale hqScale, EdgeOp edgeOp, PolyLineScaler<Pixel>& postScale,
214 FrameSource& src,
unsigned srcStartY,
unsigned ,
unsigned srcWidth,
215 ScalerOutput<Pixel>& dst,
unsigned dstStartY,
unsigned dstEndY,
unsigned dstWidth)
217 int srcY = srcStartY;
218 const Pixel* srcPrev = src.getLinePtr<
Pixel>(srcY - 1, srcWidth);
219 const Pixel* srcCurr = src.getLinePtr<
Pixel>(srcY + 0, srcWidth);
221 assert(srcWidth <= 1024);
222 unsigned edgeBuf[1024];
223 calcInitialEdges(srcPrev, srcCurr, srcWidth, edgeBuf, edgeOp);
225 bool isCopy = postScale.isCopy();
226 for (
unsigned dstY = dstStartY; dstY < dstEndY; srcY += 1, dstY += 2) {
227 Pixel buf0[2 * 1024], buf1[2 * 1024];
228 const Pixel* srcNext = src.getLinePtr<
Pixel>(srcY + 1, srcWidth);
229 Pixel* dst0 = dst.acquireLine(dstY + 0);
230 Pixel* dst1 = dst.acquireLine(dstY + 1);
232 hqScale(srcPrev, srcCurr, srcNext, dst0, dst1,
233 srcWidth, edgeBuf, edgeOp);
235 hqScale(srcPrev, srcCurr, srcNext, buf0, buf1,
236 srcWidth, edgeBuf, edgeOp);
237 postScale(buf0, dst0, dstWidth);
238 postScale(buf1, dst1, dstWidth);
240 dst.releaseLine(dstY + 0, dst0);
241 dst.releaseLine(dstY + 1, dst1);
247 template <
typename Pixel,
typename HQScale,
typename EdgeOp>
248 static void doHQScale3(HQScale hqScale, EdgeOp edgeOp, PolyLineScaler<Pixel>& postScale,
249 FrameSource& src,
unsigned srcStartY,
unsigned ,
unsigned srcWidth,
250 ScalerOutput<Pixel>& dst,
unsigned dstStartY,
unsigned dstEndY,
unsigned dstWidth)
252 int srcY = srcStartY;
253 const Pixel* srcPrev = src.getLinePtr<
Pixel>(srcY - 1, srcWidth);
254 const Pixel* srcCurr = src.getLinePtr<
Pixel>(srcY + 0, srcWidth);
256 assert(srcWidth <= 1024);
257 unsigned edgeBuf[1024];
258 calcInitialEdges(srcPrev, srcCurr, srcWidth, edgeBuf, edgeOp);
260 bool isCopy = postScale.isCopy();
261 for (
unsigned dstY = dstStartY; dstY < dstEndY; srcY += 1, dstY += 3) {
262 Pixel buf0[3 * 1024], buf1[3 * 1024], buf2[3 * 1024];
263 const Pixel* srcNext = src.getLinePtr<
Pixel>(srcY + 1, srcWidth);
264 Pixel* dst0 = dst.acquireLine(dstY + 0);
265 Pixel* dst1 = dst.acquireLine(dstY + 1);
266 Pixel* dst2 = dst.acquireLine(dstY + 2);
268 hqScale(srcPrev, srcCurr, srcNext, dst0, dst1, dst2,
269 srcWidth, edgeBuf, edgeOp);
271 hqScale(srcPrev, srcCurr, srcNext, buf0, buf1, buf2,
272 srcWidth, edgeBuf, edgeOp);
273 postScale(buf0, dst0, dstWidth);
274 postScale(buf1, dst1, dstWidth);
275 postScale(buf2, dst2, dstWidth);
277 dst.releaseLine(dstY + 0, dst0);
278 dst.releaseLine(dstY + 1, dst1);
279 dst.releaseLine(dstY + 2, dst2);