1935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com/* NEON optimized code (C) COPYRIGHT 2009 Motorola 296164722b5b534463cbceb6e3a8b98821748dee6caryclark@google.com * 396164722b5b534463cbceb6e3a8b98821748dee6caryclark@google.com * Use of this source code is governed by a BSD-style license that can be 496164722b5b534463cbceb6e3a8b98821748dee6caryclark@google.com * found in the LICENSE file. 596164722b5b534463cbceb6e3a8b98821748dee6caryclark@google.com */ 6365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com 7bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkBitmapProcState.h" 8bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkPerspIter.h" 9bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkShader.h" 102cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com#include "SkUtils.h" 11d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com#include "SkUtilsArm.h" 122cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 1399cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com// Helper to ensure that when we shift down, we do it w/o sign-extension 1499cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com// so the caller doesn't have to manually mask off the top 16 bits 1599cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com// 1699cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.comstatic unsigned SK_USHIFT16(unsigned x) { 1799cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com return x >> 16; 1899cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com} 1999cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com 202cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com/* returns 0...(n-1) given any x (positive or negative). 21935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 222cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com As an example, if n (which is always positive) is 5... 23935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 242cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 252cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com returns: 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 262cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com */ 272cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic inline int sk_int_mod(int x, int n) { 282cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkASSERT(n > 0); 292cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if ((unsigned)x >= (unsigned)n) { 302cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (x < 0) { 312cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x = n + ~(~x % n); 322cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } else { 332cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x = x % n; 342cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 352cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 362cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return x; 372cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 38bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 39f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com/* 40f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * The decal_ functions require that 41f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * 1. dx > 0 42f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * 2. [fx, fx+dx, fx+2dx, fx+3dx, ... fx+(count-1)dx] are all <= maxX 43f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * 44f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * In addition, we use SkFractionalInt to keep more fractional precision than 45f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * just SkFixed, so we will abort the decal_ call if dx is very small, since 46f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * the decal_ function just operates on SkFixed. If that were changed, we could 47f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com * skip the very_small test here. 48f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com */ 49f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.comstatic inline bool can_truncate_to_fixed_for_decal(SkFractionalInt frX, 50f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com SkFractionalInt frDx, 51f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com int count, unsigned max) { 52f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com SkFixed dx = SkFractionalIntToFixed(frDx); 53935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 54f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com // if decal_ kept SkFractionalInt precision, this would just be dx <= 0 55f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com // I just made up the 1/256. Just don't want to perceive accumulated error 56f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com // if we truncate frDx and lose its low bits. 57f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com if (dx <= SK_Fixed1 / 256) { 58f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com return false; 59f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com } 60f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com 61f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com // We cast to unsigned so we don't have to check for negative values, which 62f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com // will now appear as very large positive values, and thus fail our test! 63f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com SkFixed fx = SkFractionalIntToFixed(frX); 64f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com return (unsigned)SkFixedFloorToInt(fx) <= max && 65f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com (unsigned)SkFixedFloorToInt(fx + dx * (count - 1)) < max; 66f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com} 67f58e53a4731829e374adb565acd58ea7b1b0c721reed@google.com 68bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 69bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 70bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 71d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com// Compile neon code paths if needed 72d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com#if !SK_ARM_NEON_IS_NONE 73d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com 74d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com// These are defined in src/opts/SkBitmapProcState_matrixProcs_neon.cpp 75d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.comextern const SkBitmapProcState::MatrixProc ClampX_ClampY_Procs_neon[]; 76d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.comextern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; 77d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com 78d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com#endif // !SK_ARM_NEON_IS_NONE 79d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com 80d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com// Compile non-neon code path if needed 81d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com#if !SK_ARM_NEON_IS_ALWAYS 82bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define MAKENAME(suffix) ClampX_ClampY ## suffix 83de8a82d9e8e55a0b6a72e62ad02324d7fa508e17reed@google.com#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) 84de8a82d9e8e55a0b6a72e62ad02324d7fa508e17reed@google.com#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) 85bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) 86bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) 87bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define CHECK_FOR_DECAL 88d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com#include "SkBitmapProcState_matrix.h" 89bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 90bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define MAKENAME(suffix) RepeatX_RepeatY ## suffix 9199cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com#define TILEX_PROCF(fx, max) SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1)) 9299cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com#define TILEY_PROCF(fy, max) SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1)) 93bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 94bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 95d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com#include "SkBitmapProcState_matrix.h" 96365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com#endif 97bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 98bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#define MAKENAME(suffix) GeneralXY ## suffix 99e3b9fcf6f0c014270d3ea1c00e638ca9799415fehumper@google.com#define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; (void) tileProcX; \ 100e3b9fcf6f0c014270d3ea1c00e638ca9799415fehumper@google.com SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY; (void) tileProcY; \ 101e3b9fcf6f0c014270d3ea1c00e638ca9799415fehumper@google.com SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX = (state).fTileLowBitsProcX; (void) tileLowBitsProcX; \ 102e3b9fcf6f0c014270d3ea1c00e638ca9799415fehumper@google.com SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY = (state).fTileLowBitsProcY; (void) tileLowBitsProcY 10306dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com#define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcX 10406dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY 10506dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com#define PREAMBLE_ARG_X , tileProcX, tileLowBitsProcX 10606dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com#define PREAMBLE_ARG_Y , tileProcY, tileLowBitsProcY 10799cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com#define TILEX_PROCF(fx, max) SK_USHIFT16(tileProcX(fx) * ((max) + 1)) 10899cc86fb17ba491fa316a6b1c5ac273d4af3e30breed@google.com#define TILEY_PROCF(fy, max) SK_USHIFT16(tileProcY(fy) * ((max) + 1)) 10906dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com#define TILEX_LOW_BITS(fx, max) tileLowBitsProcX(fx, (max) + 1) 11006dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com#define TILEY_LOW_BITS(fy, max) tileLowBitsProcY(fy, (max) + 1) 111bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com#include "SkBitmapProcState_matrix.h" 112bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 113bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic inline U16CPU fixed_clamp(SkFixed x) 114bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 115833a06de0bfa633045e2650165dfb169acd7547ecommit-bot@chromium.org if (x < 0) { 116bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com x = 0; 117833a06de0bfa633045e2650165dfb169acd7547ecommit-bot@chromium.org } 118833a06de0bfa633045e2650165dfb169acd7547ecommit-bot@chromium.org if (x >> 16) { 1190f2d191fd66c02bf03d6ecb9613c7feba177c00creed@google.com x = 0xFFFF; 120bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 121bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return x; 122bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 123bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 124bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic inline U16CPU fixed_repeat(SkFixed x) 125bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 126bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return x & 0xFFFF; 127bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 128bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1296398808ce504aed077deb601402117056723c852reed@google.com// Visual Studio 2010 (MSC_VER=1600) optimizes bit-shift code incorrectly. 1306398808ce504aed077deb601402117056723c852reed@google.com// See http://code.google.com/p/skia/issues/detail?id=472 1316398808ce504aed077deb601402117056723c852reed@google.com#if defined(_MSC_VER) && (_MSC_VER >= 1600) 1326398808ce504aed077deb601402117056723c852reed@google.com#pragma optimize("", off) 1336398808ce504aed077deb601402117056723c852reed@google.com#endif 1346398808ce504aed077deb601402117056723c852reed@google.com 135bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic inline U16CPU fixed_mirror(SkFixed x) 136bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 137bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkFixed s = x << 15 >> 31; 138bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 139bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return (x ^ s) & 0xFFFF; 140bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 141bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1426398808ce504aed077deb601402117056723c852reed@google.com#if defined(_MSC_VER) && (_MSC_VER >= 1600) 1436398808ce504aed077deb601402117056723c852reed@google.com#pragma optimize("", on) 1446398808ce504aed077deb601402117056723c852reed@google.com#endif 1456398808ce504aed077deb601402117056723c852reed@google.com 146bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comstatic SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) 147bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 148bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (SkShader::kClamp_TileMode == m) 149bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return fixed_clamp; 150bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (SkShader::kRepeat_TileMode == m) 151bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return fixed_repeat; 152bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT(SkShader::kMirror_TileMode == m); 153bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com return fixed_mirror; 154bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 155bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 15606dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.comstatic inline U16CPU fixed_clamp_lowbits(SkFixed x, int) { 15706dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com return (x >> 12) & 0xF; 15806dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com} 15906dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com 16006dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.comstatic inline U16CPU fixed_repeat_or_mirrow_lowbits(SkFixed x, int scale) { 16106dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com return ((x * scale) >> 12) & 0xF; 16206dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com} 16306dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com 16406dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.comstatic SkBitmapProcState::FixedTileLowBitsProc choose_tile_lowbits_proc(unsigned m) { 16506dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com if (SkShader::kClamp_TileMode == m) { 16606dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com return fixed_clamp_lowbits; 16706dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com } else { 16806dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com SkASSERT(SkShader::kMirror_TileMode == m || 16906dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com SkShader::kRepeat_TileMode == m); 17006dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com // mirror and repeat have the same behavior for the low bits. 17106dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com return fixed_repeat_or_mirrow_lowbits; 17206dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com } 17306dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com} 17406dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com 1752cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic inline U16CPU int_clamp(int x, int n) { 176833a06de0bfa633045e2650165dfb169acd7547ecommit-bot@chromium.org if (x >= n) { 1772cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x = n - 1; 178833a06de0bfa633045e2650165dfb169acd7547ecommit-bot@chromium.org } 179833a06de0bfa633045e2650165dfb169acd7547ecommit-bot@chromium.org if (x < 0) { 1802cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x = 0; 1812cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 1822cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return x; 1832cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 184bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1852cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic inline U16CPU int_repeat(int x, int n) { 1862cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return sk_int_mod(x, n); 1872cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 1882cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 1892cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic inline U16CPU int_mirror(int x, int n) { 1902cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x = sk_int_mod(x, 2 * n); 1912cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (x >= n) { 1922cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com x = n + ~(x - n); 193bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 1942cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return x; 1952cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 196bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 1972cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com#if 0 1982cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic void test_int_tileprocs() { 1992cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com for (int i = -8; i <= 8; i++) { 2002cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkDebugf(" int_mirror(%2d, 3) = %d\n", i, int_mirror(i, 3)); 201bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 2022cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 2032cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com#endif 204bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 2052cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned tm) { 2062cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (SkShader::kClamp_TileMode == tm) 2072cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return int_clamp; 2082cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (SkShader::kRepeat_TileMode == tm) 2092cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return int_repeat; 2102cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkASSERT(SkShader::kMirror_TileMode == tm); 2112cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return int_mirror; 212bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 213bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 214bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com////////////////////////////////////////////////////////////////////////////// 215bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 216bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) 217bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 218bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com int i; 219bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 220bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com for (i = (count >> 2); i > 0; --i) 221bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 222bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 223bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fx += dx+dx; 224bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 225bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fx += dx+dx; 226bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 227365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com count &= 3; 228bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 229365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com uint16_t* xx = (uint16_t*)dst; 230365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com for (i = count; i > 0; --i) { 231bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *xx++ = SkToU16(fx >> 16); fx += dx; 232bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 233bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 234bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 235bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.comvoid decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) 236bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com{ 237365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com 238365fb6723fd3507f35b4c80f1cbfc231cb7a4171reed@android.com 239bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com if (count & 1) 240bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 241bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((fx >> (16 + 14)) == 0); 242bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 243bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fx += dx; 244bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 245bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com while ((count -= 2) >= 0) 246bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com { 247bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com SkASSERT((fx >> (16 + 14)) == 0); 248bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 249bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fx += dx; 250bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 251bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 252bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com fx += dx; 253bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com } 254bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 255bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 2562cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com/////////////////////////////////////////////////////////////////////////////// 2572cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com// stores the same as SCALE, but is cheaper to compute. Also since there is no 2582cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com// scale, we don't need/have a FILTER version 259bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 2602cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic void fill_sequential(uint16_t xptr[], int start, int count) { 2612cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com#if 1 2622cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (reinterpret_cast<intptr_t>(xptr) & 0x2) { 2632cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com *xptr++ = start++; 2642cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count -= 1; 2652cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 2662cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (count > 3) { 2672cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint32_t* xxptr = reinterpret_cast<uint32_t*>(xptr); 2682cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint32_t pattern0 = PACK_TWO_SHORTS(start + 0, start + 1); 2692cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint32_t pattern1 = PACK_TWO_SHORTS(start + 2, start + 3); 2702cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com start += count & ~3; 2712cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int qcount = count >> 2; 2722cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com do { 2732cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com *xxptr++ = pattern0; 2742cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com pattern0 += 0x40004; 2752cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com *xxptr++ = pattern1; 2762cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com pattern1 += 0x40004; 277cf87e774356ef088b6d221da46a8702d16e19219reed@android.com } while (--qcount != 0); 2782cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr = reinterpret_cast<uint16_t*>(xxptr); 2792cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count &= 3; 2802cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 2812cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com while (--count >= 0) { 2822cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com *xptr++ = start++; 2832cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 2842cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com#else 2852cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com for (int i = 0; i < count; i++) { 2862cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com *xptr++ = start++; 2872cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 2882cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com#endif 2892cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 290bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 2912cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic int nofilter_trans_preamble(const SkBitmapProcState& s, uint32_t** xy, 2922cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int x, int y) { 2932cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkPoint pt; 2946212e31697a0aec85cda4f10e1a3c484563d0c3fhumper@google.com s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 2952cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkIntToScalar(y) + SK_ScalarHalf, &pt); 2962cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com **xy = s.fIntTileProcY(SkScalarToFixed(pt.fY) >> 16, 2972cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com s.fBitmap->height()); 2982cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com *xy += 1; // bump the ptr 2992cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // return our starting X position 3002cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return SkScalarToFixed(pt.fX) >> 16; 3012cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 302bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com 3032cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic void clampx_nofilter_trans(const SkBitmapProcState& s, 3042cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint32_t xy[], int count, int x, int y) { 3052cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 3062cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3072cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int xpos = nofilter_trans_preamble(s, &xy, x, y); 308935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com const int width = s.fBitmap->width(); 3092cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (1 == width) { 3102cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // all of the following X values must be 0 3112cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com memset(xy, 0, count * sizeof(uint16_t)); 3122cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return; 3132cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 314935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 3152cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 3162cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int n; 3172cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3182cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // fill before 0 as needed 3192cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (xpos < 0) { 3202cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = -xpos; 3212cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (n > count) { 3222cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = count; 3232cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3242cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com memset(xptr, 0, n * sizeof(uint16_t)); 3252cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count -= n; 3262cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (0 == count) { 3272cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return; 3282cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3292cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr += n; 3302cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xpos = 0; 3312cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3322cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3332cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // fill in 0..width-1 if needed 3342cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (xpos < width) { 3352cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = width - xpos; 3362cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (n > count) { 3372cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = count; 3382cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3392cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, xpos, n); 3402cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count -= n; 3412cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (0 == count) { 3422cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return; 3432cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3442cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr += n; 3452cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3462cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3472cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // fill the remaining with the max value 348d3450806b91dab28b36faf3a15bd54b05b133b24reed@android.com sk_memset16(xptr, width - 1, count); 3492cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 3502cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3512cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic void repeatx_nofilter_trans(const SkBitmapProcState& s, 3522cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint32_t xy[], int count, int x, int y) { 3532cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 3542cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3552cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int xpos = nofilter_trans_preamble(s, &xy, x, y); 356935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com const int width = s.fBitmap->width(); 3572cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (1 == width) { 3582cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // all of the following X values must be 0 3592cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com memset(xy, 0, count * sizeof(uint16_t)); 3602cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return; 3612cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3622cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3632cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 3642cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int start = sk_int_mod(xpos, width); 3652cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int n = width - start; 3662cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (n > count) { 3672cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = count; 3682cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3692cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, start, n); 3702cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr += n; 3712cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count -= n; 3722cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3732cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com while (count >= width) { 3742cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, 0, width); 3752cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr += width; 3762cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count -= width; 3772cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3782cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3792cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (count > 0) { 3802cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, 0, count); 3812cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3822cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 3832cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3842cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic void fill_backwards(uint16_t xptr[], int pos, int count) { 3852cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com for (int i = 0; i < count; i++) { 3862cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkASSERT(pos >= 0); 3872cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr[i] = pos--; 3882cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 3892cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 3902cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3912cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comstatic void mirrorx_nofilter_trans(const SkBitmapProcState& s, 3922cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint32_t xy[], int count, int x, int y) { 3932cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 3942cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 3952cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int xpos = nofilter_trans_preamble(s, &xy, x, y); 396935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com const int width = s.fBitmap->width(); 3972cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (1 == width) { 3982cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // all of the following X values must be 0 3992cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com memset(xy, 0, count * sizeof(uint16_t)); 4002cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return; 4012cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4022cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 4032cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 4042cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // need to know our start, and our initial phase (forward or backward) 4052cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com bool forward; 4062cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int n; 4072cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int start = sk_int_mod(xpos, 2 * width); 4082cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (start >= width) { 4092cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com start = width + ~(start - width); 4102cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com forward = false; 4112cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = start + 1; // [start .. 0] 4122cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } else { 4132cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com forward = true; 4142cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = width - start; // [start .. width) 4152cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4162cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (n > count) { 4172cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com n = count; 4182cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4192cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (forward) { 4202cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, start, n); 4212cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } else { 4222cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_backwards(xptr, start, n); 4232cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4242cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com forward = !forward; 4252cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr += n; 426bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com count -= n; 427935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4282cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com while (count >= width) { 4292cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (forward) { 4302cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, 0, width); 4312cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } else { 4322cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_backwards(xptr, width - 1, width); 4332cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4342cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com forward = !forward; 4352cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com xptr += width; 4362cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com count -= width; 4372cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 438935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4392cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (count > 0) { 4402cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (forward) { 4412cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_sequential(xptr, 0, count); 4422cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } else { 4432cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fill_backwards(xptr, width - 1, count); 4442cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4452cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4462cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com} 4472cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 4482cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com/////////////////////////////////////////////////////////////////////////////// 4492cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com 4502cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comSkBitmapProcState::MatrixProc 4512cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.comSkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { 4522cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com// test_int_tileprocs(); 4532cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // check for our special case when there is no scale/affine/perspective 4542cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (trivial_matrix) { 4554d112c5bcdd40d9786a685dc142653e31ffbcbabreed@google.com SkASSERT(SkPaint::kNone_FilterLevel == fFilterLevel); 4562cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fIntTileProcY = choose_int_tile_proc(fTileModeY); 4572cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com switch (fTileModeX) { 4582cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com case SkShader::kClamp_TileMode: 4592cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return clampx_nofilter_trans; 4602cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com case SkShader::kRepeat_TileMode: 4612cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return repeatx_nofilter_trans; 4622cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com case SkShader::kMirror_TileMode: 4632cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return mirrorx_nofilter_trans; 4642cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4652cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 466935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4672cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com int index = 0; 4684d112c5bcdd40d9786a685dc142653e31ffbcbabreed@google.com if (fFilterLevel != SkPaint::kNone_FilterLevel) { 4692cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com index = 1; 4702cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 4712cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (fInvType & SkMatrix::kPerspective_Mask) { 4722cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com index += 4; 4732cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } else if (fInvType & SkMatrix::kAffine_Mask) { 474b90adab1299ac35eab54240064e3eeb6240f849creed@android.com index += 2; 4752cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 476935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4772cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (SkShader::kClamp_TileMode == fTileModeX && 4782cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkShader::kClamp_TileMode == fTileModeY) 4792cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com { 4802cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // clamp gets special version of filterOne 4812cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fFilterOneX = SK_Fixed1; 4822cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fFilterOneY = SK_Fixed1; 48359c3235e42ec788faa4d7ef41884bdcc098be257digit@google.com return SK_ARM_NEON_WRAP(ClampX_ClampY_Procs)[index]; 4842cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 485935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4862cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com // all remaining procs use this form for filterOne 4872cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fFilterOneX = SK_Fixed1 / fBitmap->width(); 4882cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fFilterOneY = SK_Fixed1 / fBitmap->height(); 489935e9f4fafdfc64130e6be9ea2bb30e3bafd852armistry@google.com 4902cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com if (SkShader::kRepeat_TileMode == fTileModeX && 4912cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com SkShader::kRepeat_TileMode == fTileModeY) 4922cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com { 49359c3235e42ec788faa4d7ef41884bdcc098be257digit@google.com return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index]; 4942cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com } 495d7ded5043a6f308c4a5c80b841a3f4a0d00ef06fdigit@google.com 4962cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fTileProcX = choose_tile_proc(fTileModeX); 4972cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com fTileProcY = choose_tile_proc(fTileModeY); 49806dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com fTileLowBitsProcX = choose_tile_lowbits_proc(fTileModeX); 49906dcb2ea66610f55813ff5d6f967ae9cc599bb9creed@google.com fTileLowBitsProcY = choose_tile_lowbits_proc(fTileModeY); 5002cd2edb95aa867542962a21a503c2bfcf57d14b6reed@android.com return GeneralXY_Procs[index]; 501bcd4d5ab12df062500a4df90ec90d0f2d764931reed@android.com} 502