aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorMax Horn2003-09-29 18:38:51 +0000
committerMax Horn2003-09-29 18:38:51 +0000
commitc40e7d68a5e814cc8b8e49d92f26c9814657bb0f (patch)
treee6516a5f94c45bd8160c72f49f9f15035a9aa666 /common
parent4a7385b4e742b283045021b1760a1fbf4d6979ac (diff)
downloadscummvm-rg350-c40e7d68a5e814cc8b8e49d92f26c9814657bb0f.tar.gz
scummvm-rg350-c40e7d68a5e814cc8b8e49d92f26c9814657bb0f.tar.bz2
scummvm-rg350-c40e7d68a5e814cc8b8e49d92f26c9814657bb0f.zip
templatized more of the scalers; also introduced template struct ColorMasks (shortens/simplifies other code a bit)
svn-id: r10489
Diffstat (limited to 'common')
-rw-r--r--common/scaler.cpp30
-rw-r--r--common/scaler/2xsai.cpp25
-rw-r--r--common/scaler/aspect.cpp39
-rw-r--r--common/scaler/hq2x.cpp7
-rw-r--r--common/scaler/hq3x.cpp7
-rw-r--r--common/scaler/intern.h62
6 files changed, 91 insertions, 79 deletions
diff --git a/common/scaler.cpp b/common/scaler.cpp
index 8f618c472c..4bb51cc84e 100644
--- a/common/scaler.cpp
+++ b/common/scaler.cpp
@@ -23,24 +23,8 @@
#include "common/scaler/intern.h"
-// TODO: get rid of the colorMask etc. variables and instead use templates.
-// This should give a respectable boost, since variable access (i.e. memory reads)
-// in the innermost loops of our operations would work with constant data instead.
-// That should help the inliner; reduce memory access; thus improve cache efficeny
-// etc. The drawback will be that each scaler will exist twice, once for 555 and
-// once for 555, resulting in the object file being twice as big (but thanks to
-// templates, no source code would be duplicated.
-
-
int gBitFormat = 565;
-uint32 colorMask = 0xF7DEF7DE;
-uint32 lowPixelMask = 0x08210821;
-uint32 qcolorMask = 0xE79CE79C;
-uint32 qlowpixelMask = 0x18631863;
-static uint32 redblueMask = redblueMask_565;
-static uint32 greenMask = greenMask_565;
-
// RGB-to-YUV lookup table
int RGBtoYUV[65536];
@@ -62,20 +46,8 @@ static void InitLUT(uint32 BitFormat);
void InitScalers(uint32 BitFormat) {
if (BitFormat == 565) {
- colorMask = 0xF7DEF7DE;
- lowPixelMask = 0x08210821;
- qcolorMask = 0xE79CE79C;
- qlowpixelMask = 0x18631863;
- redblueMask = redblueMask_565;
- greenMask = greenMask_565;
dotmatrix = dotmatrix_565;
} else if (BitFormat == 555) {
- colorMask = 0x7BDE7BDE;
- lowPixelMask = 0x04210421;
- qcolorMask = 0x739C739C;
- qlowpixelMask = 0x0C630C63;
- redblueMask = redblueMask_555;
- greenMask = greenMask_555;
dotmatrix = dotmatrix_555;
} else {
error("Unknwon bit format %d\n", BitFormat);
@@ -261,6 +233,7 @@ void AdvMame3x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPi
}
}
+template<int bitFormat>
void TV2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
int width, int height) {
const uint32 nextlineSrc = srcPitch / sizeof(uint16);
@@ -286,6 +259,7 @@ void TV2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
q += nextlineDst << 1;
}
}
+MAKE_WRAPPER(TV2x)
static inline uint16 DOT_16(uint16 c, int j, int i) {
return c - ((c >> 2) & *(dotmatrix + ((j & 3) << 2) + (i & 3)));
diff --git a/common/scaler/2xsai.cpp b/common/scaler/2xsai.cpp
index c40c08ffcc..7cf02bba47 100644
--- a/common/scaler/2xsai.cpp
+++ b/common/scaler/2xsai.cpp
@@ -22,6 +22,8 @@
#include "common/scaler/intern.h"
+
+
static inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D) {
const bool ac = (A==C);
const bool bc = (B==C);
@@ -41,18 +43,25 @@ static inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D) {
return rmap[y][x];
}
+template<int bitFormat>
static inline uint32 INTERPOLATE(uint32 A, uint32 B) {
- return (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask));
+
+ return (((A & highBits) >> 1) + ((B & highBits) >> 1) + (A & B & lowBits));
}
+template<int bitFormat>
static inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) {
- register uint32 x = ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) + ((C & qcolorMask) >> 2) + ((D & qcolorMask) >> 2);
- register uint32 y = ((A & qlowpixelMask) + (B & qlowpixelMask) + (C & qlowpixelMask) + (D & qlowpixelMask)) >> 2;
+ register uint32 x = ((A & qhighBits) >> 2) + ((B & qhighBits) >> 2) + ((C & qhighBits) >> 2) + ((D & qhighBits) >> 2);
+ register uint32 y = ((A & qlowBits) + (B & qlowBits) + (C & qlowBits) + (D & qlowBits)) >> 2;
- y &= qlowpixelMask;
+ y &= qlowBits;
return x + y;
}
+#define INTERPOLATE INTERPOLATE<bitFormat>
+#define Q_INTERPOLATE Q_INTERPOLATE<bitFormat>
+
+template<int bitFormat>
void Super2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
const uint16 *bP;
uint16 *dP;
@@ -159,6 +168,9 @@ void Super2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstP
}
}
+MAKE_WRAPPER(Super2xSaI)
+
+template<int bitFormat>
void SuperEagle(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
const uint16 *bP;
uint16 *dP;
@@ -267,6 +279,9 @@ void SuperEagle(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstP
}
}
+MAKE_WRAPPER(SuperEagle)
+
+template<int bitFormat>
void _2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
const uint16 *bP;
uint16 *dP;
@@ -399,3 +414,5 @@ void _2xSaI(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch
dstPtr += dstPitch * 2;
}
}
+
+MAKE_WRAPPER(_2xSaI)
diff --git a/common/scaler/aspect.cpp b/common/scaler/aspect.cpp
index f337a7fb47..7a7dc492b2 100644
--- a/common/scaler/aspect.cpp
+++ b/common/scaler/aspect.cpp
@@ -32,7 +32,7 @@
#if ASPECT_MODE == kSlowAndPerfectAspectMode
-template<int scale>
+template<int bitFormat, int scale>
static inline uint16 interpolate5(uint16 A, uint16 B) {
uint16 r = (uint16)(((A & redblueMask & 0xFF00) * scale + (B & redblueMask & 0xFF00) * (5 - scale)) / 5);
uint16 g = (uint16)(((A & greenMask) * scale + (B & greenMask) * (5 - scale)) / 5);
@@ -42,30 +42,32 @@ static inline uint16 interpolate5(uint16 A, uint16 B) {
}
-template<int scale>
+template<int bitFormat, int scale>
static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int width) {
// Accurate but slightly slower code
while (width--) {
- *dst++ = interpolate5<scale>(*srcA++, *srcB++);
+ *dst++ = interpolate5<bitFormat, scale>(*srcA++, *srcB++);
}
}
#endif
#if ASPECT_MODE == kFastAndNiceAspectMode
+template<int bitFormat>
static inline uint32 INTERPOLATE_1_1(uint32 A, uint32 B) {
- return (((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask));
+ return (((A & highBits) >> 1) + ((B & highBits) >> 1) + (A & B & lowBits));
}
+template<int bitFormat>
static inline uint32 INTERPOLATE_1_3(uint32 A, uint32 B) {
- register uint32 x = ((A & qcolorMask) >> 2) + ((B & qcolorMask) >> 2) * 3;
- register uint32 y = ((A & qlowpixelMask) + (B & qlowpixelMask) * 3) >> 2;
+ register uint32 x = ((A & qhighBits) >> 2) + ((B & qhighBits) >> 2) * 3;
+ register uint32 y = ((A & qlowBits) + (B & qlowBits) * 3) >> 2;
- y &= qlowpixelMask;
+ y &= qlowBits;
return x + y;
}
-template<int scale>
+template<int bitFormat, int scale>
static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint16 *srcB, int width) {
// For efficiency reasons we blit two pixels at a time, so it is important
// that makeRectStretchable() guarantees that the width is even and that
@@ -86,11 +88,11 @@ static inline void interpolate5Line(uint16 *dst, const uint16 *srcA, const uint1
uint32 *d = (uint32 *)dst;
if (scale == 1) {
while (width--) {
- *d++ = INTERPOLATE_1_3(*sA++, *sB++);
+ *d++ = INTERPOLATE_1_3<bitFormat>(*sA++, *sB++);
}
} else {
while (width--) {
- *d++ = INTERPOLATE_1_1(*sA++, *sB++);
+ *d++ = INTERPOLATE_1_1<bitFormat>(*sA++, *sB++);
}
}
}
@@ -141,6 +143,7 @@ void makeRectStretchable(int &x, int &y, int &w, int &h) {
* srcY + height - 1, and it should be stretched to Y coordinates srcY
* through real2Aspect(srcY + height - 1).
*/
+template<int bitFormat>
int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) {
int maxDstY = real2Aspect(origSrcY + height - 1);
int y;
@@ -163,16 +166,16 @@ int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, i
memcpy(dstPtr, srcPtr, width * 2);
break;
case 1:
- interpolate5Line<1>((uint16 *)dstPtr, (const uint16 *)(srcPtr - pitch), (const uint16 *)srcPtr, width);
+ interpolate5Line<bitFormat, 1>((uint16 *)dstPtr, (const uint16 *)(srcPtr - pitch), (const uint16 *)srcPtr, width);
break;
case 2:
- interpolate5Line<2>((uint16 *)dstPtr, (const uint16 *)(srcPtr - pitch), (const uint16 *)srcPtr, width);
+ interpolate5Line<bitFormat, 2>((uint16 *)dstPtr, (const uint16 *)(srcPtr - pitch), (const uint16 *)srcPtr, width);
break;
case 3:
- interpolate5Line<2>((uint16 *)dstPtr, (const uint16 *)srcPtr, (const uint16 *)(srcPtr - pitch), width);
+ interpolate5Line<bitFormat, 2>((uint16 *)dstPtr, (const uint16 *)srcPtr, (const uint16 *)(srcPtr - pitch), width);
break;
case 4:
- interpolate5Line<1>((uint16 *)dstPtr, (const uint16 *)srcPtr, (const uint16 *)(srcPtr - pitch), width);
+ interpolate5Line<bitFormat, 1>((uint16 *)dstPtr, (const uint16 *)srcPtr, (const uint16 *)(srcPtr - pitch), width);
break;
}
#endif
@@ -181,3 +184,11 @@ int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, i
return 1 + maxDstY - srcY;
}
+
+int stretch200To240(uint8 *buf, uint32 pitch, int width, int height, int srcX, int srcY, int origSrcY) {
+ if (gBitFormat == 565)
+ return stretch200To240<565>(buf, pitch, width, height, srcX, srcY, origSrcY);
+ else // gBitFormat == 555
+ return stretch200To240<555>(buf, pitch, width, height, srcX, srcY, origSrcY);
+}
+
diff --git a/common/scaler/hq2x.cpp b/common/scaler/hq2x.cpp
index 2505914c26..de134373dd 100644
--- a/common/scaler/hq2x.cpp
+++ b/common/scaler/hq2x.cpp
@@ -1929,9 +1929,4 @@ void HQ2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
}
}
-void HQ2x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
- if (gBitFormat == 565)
- HQ2x<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
- else // gBitFormat == 555
- HQ2x<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
-}
+MAKE_WRAPPER(HQ2x)
diff --git a/common/scaler/hq3x.cpp b/common/scaler/hq3x.cpp
index f484e2eabb..6b40f676e2 100644
--- a/common/scaler/hq3x.cpp
+++ b/common/scaler/hq3x.cpp
@@ -2927,9 +2927,4 @@ void HQ3x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch,
}
}
-void HQ3x(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) {
- if (gBitFormat == 565)
- HQ3x<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
- else // gBitFormat == 555
- HQ3x<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height);
-}
+MAKE_WRAPPER(HQ3x)
diff --git a/common/scaler/intern.h b/common/scaler/intern.h
index 5c24a2ce53..e65e6f311a 100644
--- a/common/scaler/intern.h
+++ b/common/scaler/intern.h
@@ -30,17 +30,36 @@
#include "common/util.h"
-static const uint32 redblueMask_565 = 0xF81F;
-static const uint32 greenMask_565 = 0x07E0;
-static const uint32 redblueMask_555 = 0x7C1F;
-static const uint32 greenMask_555 = 0x03E0;
+template<int bitFormat>
+struct ColorMasks {
+};
+
+struct ColorMasks<565> {
+ static const int highBits = 0xF7DEF7DE;
+ static const int lowBits = 0x08210821;
+ static const int qhighBits = 0xE79CE79C;
+ static const int qlowBits = 0x18631863;
+ static const int redblueMask = 0xF81F;
+ static const int greenMask = 0x07E0;
+};
+
+struct ColorMasks<555> {
+ static const int highBits = 0x04210421;
+ static const int lowBits = 0x04210421;
+ static const int qhighBits = 0x739C739C;
+ static const int qlowBits = 0x0C630C63;
+ static const int redblueMask = 0x7C1F;
+ static const int greenMask = 0x03E0;
+};
+
+#define highBits ColorMasks<bitFormat>::highBits
+#define lowBits ColorMasks<bitFormat>::lowBits
+#define qhighBits ColorMasks<bitFormat>::qhighBits
+#define qlowBits ColorMasks<bitFormat>::qlowBits
+#define redblueMask ColorMasks<bitFormat>::redblueMask
+#define greenMask ColorMasks<bitFormat>::greenMask
-extern uint32 colorMask;
-extern uint32 lowPixelMask;
-extern uint32 qcolorMask;
-extern uint32 qlowpixelMask;
-
extern int gBitFormat;
@@ -50,12 +69,8 @@ extern int gBitFormat;
*/
template<int bitFormat, int w1, int w2>
static inline uint16 interpolate16_2(uint16 p1, uint16 p2) {
- if (bitFormat == 565)
- return ((((p1 & redblueMask_565) * w1 + (p2 & redblueMask_565) * w2) / (w1 + w2)) & redblueMask_565) |
- ((((p1 & greenMask_565) * w1 + (p2 & greenMask_565) * w2) / (w1 + w2)) & greenMask_565);
- else // bitFormat == 555
- return ((((p1 & redblueMask_555) * w1 + (p2 & redblueMask_555) * w2) / (w1 + w2)) & redblueMask_555) |
- ((((p1 & greenMask_555) * w1 + (p2 & greenMask_555) * w2) / (w1 + w2)) & greenMask_555);
+ return ((((p1 & redblueMask) * w1 + (p2 & redblueMask) * w2) / (w1 + w2)) & redblueMask) |
+ ((((p1 & greenMask) * w1 + (p2 & greenMask) * w2) / (w1 + w2)) & greenMask);
}
/**
@@ -64,12 +79,8 @@ static inline uint16 interpolate16_2(uint16 p1, uint16 p2) {
*/
template<int bitFormat, int w1, int w2, int w3>
static inline uint16 interpolate16_3(uint16 p1, uint16 p2, uint16 p3) {
- if (bitFormat == 565)
- return ((((p1 & redblueMask_565) * w1 + (p2 & redblueMask_565) * w2 + (p3 & redblueMask_565) * w3) / (w1 + w2 + w3)) & redblueMask_565) |
- ((((p1 & greenMask_565) * w1 + (p2 & greenMask_565) * w2 + (p3 & greenMask_565) * w3) / (w1 + w2 + w3)) & greenMask_565);
- else // bitFormat == 555
- return ((((p1 & redblueMask_555) * w1 + (p2 & redblueMask_555) * w2 + (p3 & redblueMask_555) * w3) / (w1 + w2 + w3)) & redblueMask_555) |
- ((((p1 & greenMask_555) * w1 + (p2 & greenMask_555) * w2 + (p3 & greenMask_555) * w3) / (w1 + w2 + w3)) & greenMask_555);
+ return ((((p1 & redblueMask) * w1 + (p2 & redblueMask) * w2 + (p3 & redblueMask) * w3) / (w1 + w2 + w3)) & redblueMask) |
+ ((((p1 & greenMask) * w1 + (p2 & greenMask) * w2 + (p3 & greenMask) * w3) / (w1 + w2 + w3)) & greenMask);
}
@@ -97,4 +108,13 @@ static inline bool diffYUV(int yuv1, int yuv2) {
*/
extern int RGBtoYUV[65536];
+/** Auxiliary macro to simplify creating those template function wrappers. */
+#define MAKE_WRAPPER(FUNC) \
+ void FUNC(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { \
+ if (gBitFormat == 565) \
+ FUNC<565>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); \
+ else \
+ FUNC<555>(srcPtr, srcPitch, dstPtr, dstPitch, width, height); \
+ }
+
#endif