diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-14 15:02:35 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-14 15:02:35 +0000 |
commit | 567f519b942664582b268bf223e744fafcd11fa1 (patch) | |
tree | b427a985c015a8b1157e90c55b2edb24ff3e03f4 | |
parent | 5d0b150257f9a630154a39ab6aa5cffc850d4622 (diff) |
use templates instead of macros to build blitters
BUG=
R=mtklein@google.com
Author: reed@google.com
Review URL: https://codereview.chromium.org/120633004
git-svn-id: http://skia.googlecode.com/svn/trunk@14178 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkBitmapProcState_matrix.h | 138 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_matrixProcs.cpp | 117 | ||||
-rw-r--r-- | src/core/SkBitmapProcState_matrix_template.h | 124 |
3 files changed, 211 insertions, 168 deletions
diff --git a/src/core/SkBitmapProcState_matrix.h b/src/core/SkBitmapProcState_matrix.h index d796d0b04c..b71c3c3b75 100644 --- a/src/core/SkBitmapProcState_matrix.h +++ b/src/core/SkBitmapProcState_matrix.h @@ -9,11 +9,8 @@ #include "SkMath.h" #include "SkMathPriv.h" -#define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale) #define SCALE_FILTER_NAME MAKENAME(_filter_scale) -#define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine) #define AFFINE_FILTER_NAME MAKENAME(_filter_affine) -#define PERSP_NOFILTER_NAME MAKENAME(_nofilter_persp) #define PERSP_FILTER_NAME MAKENAME(_filter_persp) #define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) @@ -28,13 +25,6 @@ #endif // declare functions externally to suppress warnings. -void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y); -void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y); -void PERSP_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t* SK_RESTRICT xy, - int count, int x, int y); void SCALE_FILTER_NAME(const SkBitmapProcState& s, uint32_t xy[], int count, int x, int y); void AFFINE_FILTER_NAME(const SkBitmapProcState& s, @@ -43,122 +33,6 @@ void PERSP_FILTER_NAME(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy, int count, int x, int y); -void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask)) == 0); - - PREAMBLE(s); - // we store y, x, x, x, x, x - - const unsigned maxX = s.fBitmap->width() - 1; - SkFractionalInt fx; - { - SkPoint pt; - s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &pt); - fx = SkScalarToFractionalInt(pt.fY); - const unsigned maxY = s.fBitmap->height() - 1; - *xy++ = TILEY_PROCF(SkFractionalIntToFixed(fx), maxY); - fx = SkScalarToFractionalInt(pt.fX); - } - - if (0 == maxX) { - // all of the following X values must be 0 - memset(xy, 0, count * sizeof(uint16_t)); - return; - } - - const SkFractionalInt dx = s.fInvSxFractionalInt; - -#ifdef CHECK_FOR_DECAL - if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { - decal_nofilter_scale(xy, SkFractionalIntToFixed(fx), - SkFractionalIntToFixed(dx), count); - } else -#endif - { - int i; - for (i = (count >> 2); i > 0; --i) { - unsigned a, b; - a = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; - b = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; -#ifdef SK_CPU_BENDIAN - *xy++ = (a << 16) | b; -#else - *xy++ = (b << 16) | a; -#endif - a = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; - b = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; -#ifdef SK_CPU_BENDIAN - *xy++ = (a << 16) | b; -#else - *xy++ = (b << 16) | a; -#endif - } - uint16_t* xx = (uint16_t*)xy; - for (i = (count & 3); i > 0; --i) { - *xx++ = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; - } - } -} - -// note: we could special-case on a matrix which is skewed in X but not Y. -// this would require a more general setup thatn SCALE does, but could use -// SCALE's inner loop that only looks at dx - -void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask | - SkMatrix::kAffine_Mask)) == 0); - - PREAMBLE(s); - SkPoint srcPt; - s.fInvProc(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - - SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX); - SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY); - SkFractionalInt dx = s.fInvSxFractionalInt; - SkFractionalInt dy = s.fInvKyFractionalInt; - int maxX = s.fBitmap->width() - 1; - int maxY = s.fBitmap->height() - 1; - - for (int i = count; i > 0; --i) { - *xy++ = (TILEY_PROCF(SkFractionalIntToFixed(fy), maxY) << 16) | - TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); - fx += dx; fy += dy; - } -} - -void PERSP_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t* SK_RESTRICT xy, - int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); - - PREAMBLE(s); - int maxX = s.fBitmap->width() - 1; - int maxY = s.fBitmap->height() - 1; - - SkPerspIter iter(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, count); - - while ((count = iter.next()) != 0) { - const SkFixed* SK_RESTRICT srcXY = iter.getXY(); - while (--count >= 0) { - *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) | - TILEX_PROCF(srcXY[0], maxX); - srcXY += 2; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, SkFixed one PREAMBLE_PARAM_Y) { unsigned i = TILEY_PROCF(f, max); @@ -270,15 +144,6 @@ void PERSP_FILTER_NAME(const SkBitmapProcState& s, } } -static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = { - SCALE_NOFILTER_NAME, - SCALE_FILTER_NAME, - AFFINE_NOFILTER_NAME, - AFFINE_FILTER_NAME, - PERSP_NOFILTER_NAME, - PERSP_FILTER_NAME -}; - #undef MAKENAME #undef TILEX_PROCF #undef TILEY_PROCF @@ -286,11 +151,8 @@ static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = { #undef CHECK_FOR_DECAL #endif -#undef SCALE_NOFILTER_NAME #undef SCALE_FILTER_NAME -#undef AFFINE_NOFILTER_NAME #undef AFFINE_FILTER_NAME -#undef PERSP_NOFILTER_NAME #undef PERSP_FILTER_NAME #undef PREAMBLE diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp index 57376d5699..904e9488e7 100644 --- a/src/core/SkBitmapProcState_matrixProcs.cpp +++ b/src/core/SkBitmapProcState_matrixProcs.cpp @@ -33,6 +33,10 @@ static inline int sk_int_mod(int x, int n) { void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); +#include "SkBitmapProcState_matrix_template.h" + +/////////////////////////////////////////////////////////////////////////////// + // Compile neon code paths if needed #if !SK_ARM_NEON_IS_NONE @@ -52,6 +56,35 @@ extern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; #define CHECK_FOR_DECAL #include "SkBitmapProcState_matrix.h" +struct ClampTileProcs { + static unsigned X(const SkBitmapProcState&, SkFixed fx, int max) { + return SkClampMax(fx >> 16, max); + } + static unsigned Y(const SkBitmapProcState&, SkFixed fy, int max) { + return SkClampMax(fy >> 16, max); + } +}; + +// Referenced in opts_check_SSE2.cpp +void ClampX_ClampY_nofilter_scale(const SkBitmapProcState& s, uint32_t xy[], + int count, int x, int y) { + return NoFilterProc_Scale<ClampTileProcs, true>(s, xy, count, x, y); +} +void ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s, uint32_t xy[], + int count, int x, int y) { + return NoFilterProc_Affine<ClampTileProcs>(s, xy, count, x, y); +} + +static SkBitmapProcState::MatrixProc ClampX_ClampY_Procs[] = { + // only clamp lives in the right coord space to check for decal + ClampX_ClampY_nofilter_scale, + ClampX_ClampY_filter_scale, + ClampX_ClampY_nofilter_affine, + ClampX_ClampY_filter_affine, + NoFilterProc_Persp<ClampTileProcs>, + ClampX_ClampY_filter_persp +}; + #define MAKENAME(suffix) RepeatX_RepeatY ## suffix #define TILEX_PROCF(fx, max) SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1)) #define TILEY_PROCF(fy, max) SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1)) @@ -60,6 +93,24 @@ extern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; #include "SkBitmapProcState_matrix.h" #endif +struct RepeatTileProcs { + static unsigned X(const SkBitmapProcState&, SkFixed fx, int max) { + return SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1)); + } + static unsigned Y(const SkBitmapProcState&, SkFixed fy, int max) { + return SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1)); + } +}; + +static SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs[] = { + NoFilterProc_Scale<RepeatTileProcs, false>, + RepeatX_RepeatY_filter_scale, + NoFilterProc_Affine<RepeatTileProcs>, + RepeatX_RepeatY_filter_affine, + NoFilterProc_Persp<RepeatTileProcs>, + RepeatX_RepeatY_filter_persp +}; + #define MAKENAME(suffix) GeneralXY ## suffix #define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; (void) tileProcX; \ SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY; (void) tileProcY; \ @@ -75,8 +126,27 @@ extern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; #define TILEY_LOW_BITS(fy, max) tileLowBitsProcY(fy, (max) + 1) #include "SkBitmapProcState_matrix.h" -static inline U16CPU fixed_clamp(SkFixed x) -{ +struct GeneralTileProcs { + static unsigned X(const SkBitmapProcState& s, SkFixed fx, int max) { + return SK_USHIFT16(s.fTileProcX(fx) * ((max) + 1)); + } + static unsigned Y(const SkBitmapProcState& s, SkFixed fy, int max) { + return SK_USHIFT16(s.fTileProcY(fy) * ((max) + 1)); + } +}; + +static SkBitmapProcState::MatrixProc GeneralXY_Procs[] = { + NoFilterProc_Scale<GeneralTileProcs, false>, + GeneralXY_filter_scale, + NoFilterProc_Affine<GeneralTileProcs>, + GeneralXY_filter_affine, + NoFilterProc_Persp<GeneralTileProcs>, + GeneralXY_filter_persp +}; + +/////////////////////////////////////////////////////////////////////////////// + +static inline U16CPU fixed_clamp(SkFixed x) { if (x < 0) { x = 0; } @@ -86,8 +156,7 @@ static inline U16CPU fixed_clamp(SkFixed x) return x; } -static inline U16CPU fixed_repeat(SkFixed x) -{ +static inline U16CPU fixed_repeat(SkFixed x) { return x & 0xFFFF; } @@ -97,8 +166,7 @@ static inline U16CPU fixed_repeat(SkFixed x) #pragma optimize("", off) #endif -static inline U16CPU fixed_mirror(SkFixed x) -{ +static inline U16CPU fixed_mirror(SkFixed x) { SkFixed s = x << 15 >> 31; // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval return (x ^ s) & 0xFFFF; @@ -108,12 +176,13 @@ static inline U16CPU fixed_mirror(SkFixed x) #pragma optimize("", on) #endif -static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) -{ - if (SkShader::kClamp_TileMode == m) +static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) { + if (SkShader::kClamp_TileMode == m) { return fixed_clamp; - if (SkShader::kRepeat_TileMode == m) + } + if (SkShader::kRepeat_TileMode == m) { return fixed_repeat; + } SkASSERT(SkShader::kMirror_TileMode == m); return fixed_mirror; } @@ -178,12 +247,10 @@ static SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned tm) { ////////////////////////////////////////////////////////////////////////////// -void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) -{ +void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) { int i; - for (i = (count >> 2); i > 0; --i) - { + for (i = (count >> 2); i > 0; --i) { *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); fx += dx+dx; *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); @@ -197,18 +264,13 @@ void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) } } -void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) -{ - - - if (count & 1) - { +void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) { + if (count & 1) { SkASSERT((fx >> (16 + 14)) == 0); *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); fx += dx; } - while ((count -= 2) >= 0) - { + while ((count -= 2) >= 0) { SkASSERT((fx >> (16 + 14)) == 0); *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); fx += dx; @@ -412,8 +474,7 @@ static void mirrorx_nofilter_trans(const SkBitmapProcState& s, /////////////////////////////////////////////////////////////////////////////// -SkBitmapProcState::MatrixProc -SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { +SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { // test_int_tileprocs(); // check for our special case when there is no scale/affine/perspective if (trivial_matrix) { @@ -439,9 +500,7 @@ SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { index += 2; } - if (SkShader::kClamp_TileMode == fTileModeX && - SkShader::kClamp_TileMode == fTileModeY) - { + if (SkShader::kClamp_TileMode == fTileModeX && SkShader::kClamp_TileMode == fTileModeY) { // clamp gets special version of filterOne fFilterOneX = SK_Fixed1; fFilterOneY = SK_Fixed1; @@ -452,9 +511,7 @@ SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { fFilterOneX = SK_Fixed1 / fBitmap->width(); fFilterOneY = SK_Fixed1 / fBitmap->height(); - if (SkShader::kRepeat_TileMode == fTileModeX && - SkShader::kRepeat_TileMode == fTileModeY) - { + if (SkShader::kRepeat_TileMode == fTileModeX && SkShader::kRepeat_TileMode == fTileModeY) { return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index]; } diff --git a/src/core/SkBitmapProcState_matrix_template.h b/src/core/SkBitmapProcState_matrix_template.h new file mode 100644 index 0000000000..4b0044b46a --- /dev/null +++ b/src/core/SkBitmapProcState_matrix_template.h @@ -0,0 +1,124 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBitmapProcState_MatrixTemplates_DEFINED +#define SkBitmapProcState_MatrixTemplates_DEFINED + +#include "SkMath.h" +#include "SkMathPriv.h" + +template <typename TileProc, bool tryDecal> +void NoFilterProc_Scale(const SkBitmapProcState& s, uint32_t xy[], + int count, int x, int y) { + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | + SkMatrix::kScale_Mask)) == 0); + + // we store y, x, x, x, x, x + + const unsigned maxX = s.fBitmap->width() - 1; + SkFractionalInt fx; + { + SkPoint pt; + s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &pt); + fx = SkScalarToFractionalInt(pt.fY); + const unsigned maxY = s.fBitmap->height() - 1; + *xy++ = TileProc::Y(s, SkFractionalIntToFixed(fx), maxY); + fx = SkScalarToFractionalInt(pt.fX); + } + + if (0 == maxX) { + // all of the following X values must be 0 + memset(xy, 0, count * sizeof(uint16_t)); + return; + } + + const SkFractionalInt dx = s.fInvSxFractionalInt; + + if (tryDecal && can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { + decal_nofilter_scale(xy, SkFractionalIntToFixed(fx), + SkFractionalIntToFixed(dx), count); + } else { + int i; + for (i = (count >> 2); i > 0; --i) { + unsigned a, b; + a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; + b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; +#ifdef SK_CPU_BENDIAN + *xy++ = (a << 16) | b; +#else + *xy++ = (b << 16) | a; +#endif + a = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; + b = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; +#ifdef SK_CPU_BENDIAN + *xy++ = (a << 16) | b; +#else + *xy++ = (b << 16) | a; +#endif + } + uint16_t* xx = (uint16_t*)xy; + for (i = (count & 3); i > 0; --i) { + *xx++ = TileProc::X(s, SkFractionalIntToFixed(fx), maxX); fx += dx; + } + } +} + +// note: we could special-case on a matrix which is skewed in X but not Y. +// this would require a more general setup thatn SCALE does, but could use +// SCALE's inner loop that only looks at dx + +template <typename TileProc> +void NoFilterProc_Affine(const SkBitmapProcState& s, uint32_t xy[], + int count, int x, int y) { + SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); + SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | + SkMatrix::kScale_Mask | + SkMatrix::kAffine_Mask)) == 0); + + SkPoint srcPt; + s.fInvProc(s.fInvMatrix, + SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + + SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX); + SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY); + SkFractionalInt dx = s.fInvSxFractionalInt; + SkFractionalInt dy = s.fInvKyFractionalInt; + int maxX = s.fBitmap->width() - 1; + int maxY = s.fBitmap->height() - 1; + + for (int i = count; i > 0; --i) { + *xy++ = (TileProc::Y(s, SkFractionalIntToFixed(fy), maxY) << 16) | + TileProc::X(s, SkFractionalIntToFixed(fx), maxX); + fx += dx; fy += dy; + } +} + +template <typename TileProc> +void NoFilterProc_Persp(const SkBitmapProcState& s, uint32_t* SK_RESTRICT xy, + int count, int x, int y) { + SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); + + int maxX = s.fBitmap->width() - 1; + int maxY = s.fBitmap->height() - 1; + + SkPerspIter iter(s.fInvMatrix, + SkIntToScalar(x) + SK_ScalarHalf, + SkIntToScalar(y) + SK_ScalarHalf, count); + + while ((count = iter.next()) != 0) { + const SkFixed* SK_RESTRICT srcXY = iter.getXY(); + while (--count >= 0) { + *xy++ = (TileProc::Y(s, srcXY[1], maxY) << 16) | + TileProc::X(s, srcXY[0], maxX); + srcXY += 2; + } + } +} + +#endif |