diff options
author | Max Horn | 2003-09-29 18:38:51 +0000 |
---|---|---|
committer | Max Horn | 2003-09-29 18:38:51 +0000 |
commit | c40e7d68a5e814cc8b8e49d92f26c9814657bb0f (patch) | |
tree | e6516a5f94c45bd8160c72f49f9f15035a9aa666 /common | |
parent | 4a7385b4e742b283045021b1760a1fbf4d6979ac (diff) | |
download | scummvm-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.cpp | 30 | ||||
-rw-r--r-- | common/scaler/2xsai.cpp | 25 | ||||
-rw-r--r-- | common/scaler/aspect.cpp | 39 | ||||
-rw-r--r-- | common/scaler/hq2x.cpp | 7 | ||||
-rw-r--r-- | common/scaler/hq3x.cpp | 7 | ||||
-rw-r--r-- | common/scaler/intern.h | 62 |
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 |