1fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com/* NEON optimized code (C) COPYRIGHT 2009 Motorola 26c5bf8d9fe6fe263f583a4c22d04e3be879ecfebcaryclark@google.com * 36c5bf8d9fe6fe263f583a4c22d04e3be879ecfebcaryclark@google.com * Use of this source code is governed by a BSD-style license that can be 46c5bf8d9fe6fe263f583a4c22d04e3be879ecfebcaryclark@google.com * found in the LICENSE file. 56c5bf8d9fe6fe263f583a4c22d04e3be879ecfebcaryclark@google.com */ 6ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmapProcState.h" 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPerspIter.h" 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkShader.h" 1007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com#include "SkUtils.h" 11fce02aca62525c3041226501574f740f7ea3714bdigit@google.com#include "SkUtilsArm.h" 12a8c09668f9e602f77422a344dfa4d13155c91fd3commit-bot@chromium.org#include "SkBitmapProcState_utils.h" 1399c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com 1407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com/* returns 0...(n-1) given any x (positive or negative). 15fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com As an example, if n (which is always positive) is 5... 17fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 1907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com returns: 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 2007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com */ 2107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic inline int sk_int_mod(int x, int n) { 2207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkASSERT(n > 0); 2307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if ((unsigned)x >= (unsigned)n) { 2407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (x < 0) { 2507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x = n + ~(~x % n); 2607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } else { 2707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x = x % n; 2807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 2907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 3007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return x; 3107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 36d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com#include "SkBitmapProcState_matrix_template.h" 37d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 38d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com/////////////////////////////////////////////////////////////////////////////// 39d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 40fce02aca62525c3041226501574f740f7ea3714bdigit@google.com// Compile neon code paths if needed 41fce02aca62525c3041226501574f740f7ea3714bdigit@google.com#if !SK_ARM_NEON_IS_NONE 42fce02aca62525c3041226501574f740f7ea3714bdigit@google.com 43fce02aca62525c3041226501574f740f7ea3714bdigit@google.com// These are defined in src/opts/SkBitmapProcState_matrixProcs_neon.cpp 44fce02aca62525c3041226501574f740f7ea3714bdigit@google.comextern const SkBitmapProcState::MatrixProc ClampX_ClampY_Procs_neon[]; 45fce02aca62525c3041226501574f740f7ea3714bdigit@google.comextern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; 46fce02aca62525c3041226501574f740f7ea3714bdigit@google.com 47fce02aca62525c3041226501574f740f7ea3714bdigit@google.com#endif // !SK_ARM_NEON_IS_NONE 48fce02aca62525c3041226501574f740f7ea3714bdigit@google.com 49fce02aca62525c3041226501574f740f7ea3714bdigit@google.com// Compile non-neon code path if needed 50fce02aca62525c3041226501574f740f7ea3714bdigit@google.com#if !SK_ARM_NEON_IS_ALWAYS 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MAKENAME(suffix) ClampX_ClampY ## suffix 52c1992933f1d97edd3f2f4c7dcbd81ffea6f6c1d8reed@google.com#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) 53c1992933f1d97edd3f2f4c7dcbd81ffea6f6c1d8reed@google.com#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define CHECK_FOR_DECAL 57fce02aca62525c3041226501574f740f7ea3714bdigit@google.com#include "SkBitmapProcState_matrix.h" 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 59d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstruct ClampTileProcs { 60d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com static unsigned X(const SkBitmapProcState&, SkFixed fx, int max) { 61d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return SkClampMax(fx >> 16, max); 62d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 63d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com static unsigned Y(const SkBitmapProcState&, SkFixed fy, int max) { 64d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return SkClampMax(fy >> 16, max); 65d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 66d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com}; 67d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 688c4953c6f176469ad287c3270ab146e292b23badcommit-bot@chromium.org// Referenced in opts_check_x86.cpp 69d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid ClampX_ClampY_nofilter_scale(const SkBitmapProcState& s, uint32_t xy[], 70d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com int count, int x, int y) { 71d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return NoFilterProc_Scale<ClampTileProcs, true>(s, xy, count, x, y); 72d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com} 73d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid ClampX_ClampY_nofilter_affine(const SkBitmapProcState& s, uint32_t xy[], 74d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com int count, int x, int y) { 75d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return NoFilterProc_Affine<ClampTileProcs>(s, xy, count, x, y); 76d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com} 77d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 78d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic SkBitmapProcState::MatrixProc ClampX_ClampY_Procs[] = { 79d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com // only clamp lives in the right coord space to check for decal 80d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com ClampX_ClampY_nofilter_scale, 81d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com ClampX_ClampY_filter_scale, 82d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com ClampX_ClampY_nofilter_affine, 83d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com ClampX_ClampY_filter_affine, 84d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Persp<ClampTileProcs>, 85d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com ClampX_ClampY_filter_persp 86d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com}; 87d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MAKENAME(suffix) RepeatX_RepeatY ## suffix 8999c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com#define TILEX_PROCF(fx, max) SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1)) 9099c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com#define TILEY_PROCF(fy, max) SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1)) 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 93fce02aca62525c3041226501574f740f7ea3714bdigit@google.com#include "SkBitmapProcState_matrix.h" 94d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 95d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstruct RepeatTileProcs { 96d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com static unsigned X(const SkBitmapProcState&, SkFixed fx, int max) { 97d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1)); 98d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 99d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com static unsigned Y(const SkBitmapProcState&, SkFixed fy, int max) { 100d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1)); 101d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 102d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com}; 103d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 104d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs[] = { 105d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Scale<RepeatTileProcs, false>, 106d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com RepeatX_RepeatY_filter_scale, 107d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Affine<RepeatTileProcs>, 108d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com RepeatX_RepeatY_filter_affine, 109d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Persp<RepeatTileProcs>, 110d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com RepeatX_RepeatY_filter_persp 111d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com}; 112ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com#endif 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define MAKENAME(suffix) GeneralXY ## suffix 11505af1afd429808913683da75644e48bece12e820humper@google.com#define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; (void) tileProcX; \ 11605af1afd429808913683da75644e48bece12e820humper@google.com SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY; (void) tileProcY; \ 11705af1afd429808913683da75644e48bece12e820humper@google.com SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX = (state).fTileLowBitsProcX; (void) tileLowBitsProcX; \ 11805af1afd429808913683da75644e48bece12e820humper@google.com SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY = (state).fTileLowBitsProcY; (void) tileLowBitsProcY 119f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com#define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX 120f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY 121f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com#define PREAMBLE_ARG_X , tileProcX, tileLowBitsProcX 122f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com#define PREAMBLE_ARG_Y , tileProcY, tileLowBitsProcY 12399c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com#define TILEX_PROCF(fx, max) SK_USHIFT16(tileProcX(fx) * ((max) + 1)) 12499c114e0ac732ba01705e24d12f5e4dd7e144abdreed@google.com#define TILEY_PROCF(fy, max) SK_USHIFT16(tileProcY(fy) * ((max) + 1)) 125f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com#define TILEX_LOW_BITS(fx, max) tileLowBitsProcX(fx, (max) + 1) 126f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com#define TILEY_LOW_BITS(fy, max) tileLowBitsProcY(fy, (max) + 1) 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBitmapProcState_matrix.h" 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 129d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstruct GeneralTileProcs { 130d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com static unsigned X(const SkBitmapProcState& s, SkFixed fx, int max) { 131d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return SK_USHIFT16(s.fTileProcX(fx) * ((max) + 1)); 132d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 133d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com static unsigned Y(const SkBitmapProcState& s, SkFixed fy, int max) { 134d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com return SK_USHIFT16(s.fTileProcY(fy) * ((max) + 1)); 135d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 136d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com}; 137d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 138d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic SkBitmapProcState::MatrixProc GeneralXY_Procs[] = { 139d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Scale<GeneralTileProcs, false>, 140d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com GeneralXY_filter_scale, 141d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Affine<GeneralTileProcs>, 142d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com GeneralXY_filter_affine, 143d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com NoFilterProc_Persp<GeneralTileProcs>, 144d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com GeneralXY_filter_persp 145d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com}; 146d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 147d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com/////////////////////////////////////////////////////////////////////////////// 148d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com 149d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic inline U16CPU fixed_clamp(SkFixed x) { 15038bad32cf5297ec6908620fd174cd08c937d331acommit-bot@chromium.org if (x < 0) { 1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com x = 0; 15238bad32cf5297ec6908620fd174cd08c937d331acommit-bot@chromium.org } 15338bad32cf5297ec6908620fd174cd08c937d331acommit-bot@chromium.org if (x >> 16) { 154cc0c8e6084e140c962ae9a6885992bafea8ec048reed@google.com x = 0xFFFF; 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return x; 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 159d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic inline U16CPU fixed_repeat(SkFixed x) { 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return x & 0xFFFF; 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 163a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly. 164a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com// See http://code.google.com/p/skia/issues/detail?id=472 165a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com#if defined(_MSC_VER) && (_MSC_VER >= 1600) 166a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com#pragma optimize("", off) 167a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com#endif 168a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com 169d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic inline U16CPU fixed_mirror(SkFixed x) { 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkFixed s = x << 15 >> 31; 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (x ^ s) & 0xFFFF; 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 175a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com#if defined(_MSC_VER) && (_MSC_VER >= 1600) 176a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com#pragma optimize("", on) 177a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com#endif 178a4b0d139e34e9d06bff0828adfb66fdfed9141c4reed@google.com 179d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comstatic SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) { 180d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (SkShader::kClamp_TileMode == m) { 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fixed_clamp; 182d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 183d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (SkShader::kRepeat_TileMode == m) { 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fixed_repeat; 185d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com } 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkShader::kMirror_TileMode == m); 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fixed_mirror; 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 190f444e8ccda8905a8ce16bac368e09f205786db31reed@google.comstatic inline U16CPU fixed_clamp_lowbits(SkFixed x, int) { 191f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com return (x >> 12) & 0xF; 192f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com} 193f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com 194f444e8ccda8905a8ce16bac368e09f205786db31reed@google.comstatic inline U16CPU fixed_repeat_or_mirrow_lowbits(SkFixed x, int scale) { 195f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com return ((x * scale) >> 12) & 0xF; 196f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com} 197f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com 198f444e8ccda8905a8ce16bac368e09f205786db31reed@google.comstatic SkBitmapProcState::FixedTileLowBitsProc choose_tile_lowbits_proc(unsigned m) { 199f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com if (SkShader::kClamp_TileMode == m) { 200f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com return fixed_clamp_lowbits; 201f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com } else { 202f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com SkASSERT(SkShader::kMirror_TileMode == m || 203f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com SkShader::kRepeat_TileMode == m); 204f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com // mirror and repeat have the same behavior for the low bits. 205f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com return fixed_repeat_or_mirrow_lowbits; 206f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com } 207f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com} 208f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com 20907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic inline U16CPU int_clamp(int x, int n) { 21038bad32cf5297ec6908620fd174cd08c937d331acommit-bot@chromium.org if (x >= n) { 21107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x = n - 1; 21238bad32cf5297ec6908620fd174cd08c937d331acommit-bot@chromium.org } 21338bad32cf5297ec6908620fd174cd08c937d331acommit-bot@chromium.org if (x < 0) { 21407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x = 0; 21507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 21607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return x; 21707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 21907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic inline U16CPU int_repeat(int x, int n) { 22007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return sk_int_mod(x, n); 22107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 22207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 22307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic inline U16CPU int_mirror(int x, int n) { 22407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x = sk_int_mod(x, 2 * n); 22507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (x >= n) { 22607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com x = n + ~(x - n); 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 22807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return x; 22907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com#if 0 23207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic void test_int_tileprocs() { 23307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com for (int i = -8; i <= 8; i++) { 23407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkDebugf(" int_mirror(%2d, 3) = %d\n", i, int_mirror(i, 3)); 2358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 23607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 23707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com#endif 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned tm) { 24007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (SkShader::kClamp_TileMode == tm) 24107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return int_clamp; 24207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (SkShader::kRepeat_TileMode == tm) 24307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return int_repeat; 24407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkASSERT(SkShader::kMirror_TileMode == tm); 24507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return int_mirror; 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////// 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 250d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) { 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int i; 2528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 253d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com for (i = (count >> 2); i > 0; --i) { 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fx += dx+dx; 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fx += dx+dx; 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 259ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com count &= 3; 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 261ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com uint16_t* xx = (uint16_t*)dst; 262ed881c2704bc81fe46a68c0cf9e292287313baa6reed@android.com for (i = count; i > 0; --i) { 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *xx++ = SkToU16(fx >> 16); fx += dx; 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 267d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comvoid decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) { 268d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (count & 1) { 2698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((fx >> (16 + 14)) == 0); 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fx += dx; 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 273d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com while ((count -= 2) >= 0) { 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((fx >> (16 + 14)) == 0); 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fx += dx; 2778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fx += dx; 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com/////////////////////////////////////////////////////////////////////////////// 28407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com// stores the same as SCALE, but is cheaper to compute. Also since there is no 28507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com// scale, we don't need/have a FILTER version 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 28707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic void fill_sequential(uint16_t xptr[], int start, int count) { 28807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com#if 1 28907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (reinterpret_cast<intptr_t>(xptr) & 0x2) { 29007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com *xptr++ = start++; 29107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count -= 1; 29207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 29307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (count > 3) { 29407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint32_t* xxptr = reinterpret_cast<uint32_t*>(xptr); 29507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint32_t pattern0 = PACK_TWO_SHORTS(start + 0, start + 1); 29607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint32_t pattern1 = PACK_TWO_SHORTS(start + 2, start + 3); 29707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com start += count & ~3; 29807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int qcount = count >> 2; 29907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com do { 30007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com *xxptr++ = pattern0; 30107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com pattern0 += 0x40004; 30207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com *xxptr++ = pattern1; 30307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com pattern1 += 0x40004; 3044c128c4917acf25c2cc5d1bd22282a4e1bb53d96reed@android.com } while (--qcount != 0); 30507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr = reinterpret_cast<uint16_t*>(xxptr); 30607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count &= 3; 30707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 30807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com while (--count >= 0) { 30907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com *xptr++ = start++; 31007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 31107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com#else 31207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com for (int i = 0; i < count; i++) { 31307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com *xptr++ = start++; 31407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 31507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com#endif 31607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic int nofilter_trans_preamble(const SkBitmapProcState& s, uint32_t** xy, 31907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int x, int y) { 32007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkPoint pt; 3219c96d4b5ffdbf8c82f55b2058a2fea7225fe11d6humper@google.com s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 32207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkIntToScalar(y) + SK_ScalarHalf, &pt); 32307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com **xy = s.fIntTileProcY(SkScalarToFixed(pt.fY) >> 16, 32407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com s.fBitmap->height()); 32507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com *xy += 1; // bump the ptr 32607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // return our starting X position 32707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return SkScalarToFixed(pt.fX) >> 16; 32807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 33007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic void clampx_nofilter_trans(const SkBitmapProcState& s, 33107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint32_t xy[], int count, int x, int y) { 33207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 33307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 33407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int xpos = nofilter_trans_preamble(s, &xy, x, y); 335fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const int width = s.fBitmap->width(); 33607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (1 == width) { 33707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // all of the following X values must be 0 33807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com memset(xy, 0, count * sizeof(uint16_t)); 33907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return; 34007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 341fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 34207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 34307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int n; 34407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 34507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // fill before 0 as needed 34607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (xpos < 0) { 34707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = -xpos; 34807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (n > count) { 34907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = count; 35007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 35107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com memset(xptr, 0, n * sizeof(uint16_t)); 35207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count -= n; 35307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (0 == count) { 35407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return; 35507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 35607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr += n; 35707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xpos = 0; 35807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 35907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 36007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // fill in 0..width-1 if needed 36107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (xpos < width) { 36207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = width - xpos; 36307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (n > count) { 36407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = count; 36507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 36607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, xpos, n); 36707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count -= n; 36807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (0 == count) { 36907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return; 37007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 37107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr += n; 37207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 37307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 37407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // fill the remaining with the max value 375258cb228c636282a3e4f4ce87b1017498e207f33reed@android.com sk_memset16(xptr, width - 1, count); 37607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 37707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 37807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic void repeatx_nofilter_trans(const SkBitmapProcState& s, 37907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint32_t xy[], int count, int x, int y) { 38007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 38107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 38207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int xpos = nofilter_trans_preamble(s, &xy, x, y); 383fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const int width = s.fBitmap->width(); 38407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (1 == width) { 38507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // all of the following X values must be 0 38607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com memset(xy, 0, count * sizeof(uint16_t)); 38707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return; 38807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 38907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 39007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 39107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int start = sk_int_mod(xpos, width); 39207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int n = width - start; 39307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (n > count) { 39407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = count; 39507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 39607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, start, n); 39707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr += n; 39807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count -= n; 39907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 40007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com while (count >= width) { 40107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, 0, width); 40207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr += width; 40307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count -= width; 40407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 40507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 40607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (count > 0) { 40707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, 0, count); 40807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 40907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 41007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 41107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic void fill_backwards(uint16_t xptr[], int pos, int count) { 41207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com for (int i = 0; i < count; i++) { 41307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkASSERT(pos >= 0); 41407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr[i] = pos--; 41507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 41607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 41707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 41807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.comstatic void mirrorx_nofilter_trans(const SkBitmapProcState& s, 41907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint32_t xy[], int count, int x, int y) { 42007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 42107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 42207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int xpos = nofilter_trans_preamble(s, &xy, x, y); 423fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com const int width = s.fBitmap->width(); 42407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (1 == width) { 42507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // all of the following X values must be 0 42607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com memset(xy, 0, count * sizeof(uint16_t)); 42707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return; 42807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 42907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 43007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 43107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // need to know our start, and our initial phase (forward or backward) 43207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com bool forward; 43307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int n; 43407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int start = sk_int_mod(xpos, 2 * width); 43507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (start >= width) { 43607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com start = width + ~(start - width); 43707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com forward = false; 43807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = start + 1; // [start .. 0] 43907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } else { 44007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com forward = true; 44107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = width - start; // [start .. width) 44207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 44307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (n > count) { 44407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com n = count; 44507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 44607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (forward) { 44707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, start, n); 44807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } else { 44907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_backwards(xptr, start, n); 45007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 45107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com forward = !forward; 45207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr += n; 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com count -= n; 454fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 45507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com while (count >= width) { 45607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (forward) { 45707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, 0, width); 45807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } else { 45907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_backwards(xptr, width - 1, width); 46007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 46107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com forward = !forward; 46207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com xptr += width; 46307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com count -= width; 46407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 465fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 46607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (count > 0) { 46707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (forward) { 46807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_sequential(xptr, 0, count); 46907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } else { 47007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fill_backwards(xptr, width - 1, count); 47107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 47207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 47307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com} 47407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 47507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com/////////////////////////////////////////////////////////////////////////////// 47607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com 477d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.comSkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { 47807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com// test_int_tileprocs(); 47907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // check for our special case when there is no scale/affine/perspective 4808d9153fca25897bf40ca0ebac8b03616612cc7b4humper if (trivial_matrix && SkPaint::kNone_FilterLevel == fFilterLevel) { 48107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fIntTileProcY = choose_int_tile_proc(fTileModeY); 48207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com switch (fTileModeX) { 48307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com case SkShader::kClamp_TileMode: 48407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return clampx_nofilter_trans; 48507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com case SkShader::kRepeat_TileMode: 48607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return repeatx_nofilter_trans; 48707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com case SkShader::kMirror_TileMode: 48807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return mirrorx_nofilter_trans; 48907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 49007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 491fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 49207d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com int index = 0; 4939cfc83cc8ac2ee50a7ce889e65a707941f48bdeareed@google.com if (fFilterLevel != SkPaint::kNone_FilterLevel) { 49407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com index = 1; 49507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 49607d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com if (fInvType & SkMatrix::kPerspective_Mask) { 49707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com index += 4; 49807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } else if (fInvType & SkMatrix::kAffine_Mask) { 499a2b2c4ba5351b8cee0f03b5a9eeeb430862bbc7dreed@android.com index += 2; 50007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 501fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 502d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (SkShader::kClamp_TileMode == fTileModeX && SkShader::kClamp_TileMode == fTileModeY) { 50307d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // clamp gets special version of filterOne 50407d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fFilterOneX = SK_Fixed1; 50507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fFilterOneY = SK_Fixed1; 506157d94465a47a57e30e5cf49cd57dccd903e27e2digit@google.com return SK_ARM_NEON_WRAP(ClampX_ClampY_Procs)[index]; 50707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 508fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 50907d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com // all remaining procs use this form for filterOne 51007d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fFilterOneX = SK_Fixed1 / fBitmap->width(); 51107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fFilterOneY = SK_Fixed1 / fBitmap->height(); 512fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 513d9ae2314f58ccac54068a2e50a4a159cf3929c1areed@google.com if (SkShader::kRepeat_TileMode == fTileModeX && SkShader::kRepeat_TileMode == fTileModeY) { 514157d94465a47a57e30e5cf49cd57dccd903e27e2digit@google.com return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index]; 51507d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com } 516fce02aca62525c3041226501574f740f7ea3714bdigit@google.com 51707d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fTileProcX = choose_tile_proc(fTileModeX); 51807d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com fTileProcY = choose_tile_proc(fTileModeY); 519f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com fTileLowBitsProcX = choose_tile_lowbits_proc(fTileModeX); 520f444e8ccda8905a8ce16bac368e09f205786db31reed@google.com fTileLowBitsProcY = choose_tile_lowbits_proc(fTileModeY); 52107d1f008b365e94ef7c7347be19a03d00bd36805reed@android.com return GeneralXY_Procs[index]; 5228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 523