14f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger/* NEON optimized code (C) COPYRIGHT 2009 Motorola 24f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * 34f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be 44f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger * found in the LICENSE file. 54f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger */ 63600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBitmapProcState.h" 80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPerspIter.h" 90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkShader.h" 109a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#include "SkUtils.h" 119a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 129a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed/* returns 0...(n-1) given any x (positive or negative). 139a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 149a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed As an example, if n (which is always positive) is 5... 159a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 169a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 179a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed returns: 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 189a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed */ 199a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic inline int sk_int_mod(int x, int n) { 209a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT(n > 0); 219a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if ((unsigned)x >= (unsigned)n) { 229a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (x < 0) { 239a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = n + ~(~x % n); 249a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else { 259a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = x % n; 269a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 279a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 289a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return x; 299a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); 330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MAKENAME(suffix) ClampX_ClampY ## suffix 350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) 360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) 370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) 380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) 390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define CHECK_FOR_DECAL 403600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#if defined(__ARM_HAVE_NEON) 413600ab34671774af980bb97ecff2842c4cfc5955Mike Reed #include "SkBitmapProcState_matrix_clamp.h" 423600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#else 433600ab34671774af980bb97ecff2842c4cfc5955Mike Reed #include "SkBitmapProcState_matrix.h" 443600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#endif 450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MAKENAME(suffix) RepeatX_RepeatY ## suffix 470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) 480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEY_PROCF(fy, max) (((fy) & 0xFFFF) * ((max) + 1) >> 16) 490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) 513600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#if defined(__ARM_HAVE_NEON) 523600ab34671774af980bb97ecff2842c4cfc5955Mike Reed #include "SkBitmapProcState_matrix_repeat.h" 533600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#else 543600ab34671774af980bb97ecff2842c4cfc5955Mike Reed #include "SkBitmapProcState_matrix.h" 553600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#endif 560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define MAKENAME(suffix) GeneralXY ## suffix 580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define PREAMBLE(state) SkBitmapProcState::FixedTileProc tileProcX = (state).fTileProcX; \ 590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkBitmapProcState::FixedTileProc tileProcY = (state).fTileProcY 600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define PREAMBLE_PARAM_X , SkBitmapProcState::FixedTileProc tileProcX 610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY 620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define PREAMBLE_ARG_X , tileProcX 630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define PREAMBLE_ARG_Y , tileProcY 640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEX_PROCF(fx, max) (tileProcX(fx) * ((max) + 1) >> 16) 650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEY_PROCF(fy, max) (tileProcY(fy) * ((max) + 1) >> 16) 660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx) * ((max) + 1) >> 12) & 0xF) 670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy) * ((max) + 1) >> 12) & 0xF) 680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBitmapProcState_matrix.h" 690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U16CPU fixed_clamp(SkFixed x) 710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x >> 16) 740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0xFFFF; 750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x < 0) 760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0; 770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else 780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x >> 16) 790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (x < 0) 810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0; 820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project else 830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project x = 0xFFFF; 840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif 860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return x; 870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U16CPU fixed_repeat(SkFixed x) 900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return x & 0xFFFF; 920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline U16CPU fixed_mirror(SkFixed x) 950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkFixed s = x << 15 >> 31; 970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval 980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return (x ^ s) & 0xFFFF; 990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) 1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (SkShader::kClamp_TileMode == m) 1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fixed_clamp; 1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (SkShader::kRepeat_TileMode == m) 1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fixed_repeat; 1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT(SkShader::kMirror_TileMode == m); 1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project return fixed_mirror; 1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1119a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic inline U16CPU int_clamp(int x, int n) { 1129a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#ifdef SK_CPU_HAS_CONDITIONAL_INSTR 1139a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (x >= n) 1149a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = n - 1; 1159a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (x < 0) 1169a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = 0; 1179a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#else 1189a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if ((unsigned)x >= (unsigned)n) { 1199a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (x < 0) { 1209a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = 0; 1219a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else { 1229a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = n - 1; 1239a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 1249a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 1259a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#endif 1269a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return x; 1279a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1299a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic inline U16CPU int_repeat(int x, int n) { 1309a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return sk_int_mod(x, n); 1319a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 1329a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 1339a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic inline U16CPU int_mirror(int x, int n) { 1349a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = sk_int_mod(x, 2 * n); 1359a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (x >= n) { 1369a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed x = n + ~(x - n); 1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1389a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return x; 1399a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1419a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#if 0 1429a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic void test_int_tileprocs() { 1439a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed for (int i = -8; i <= 8; i++) { 1449a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkDebugf(" int_mirror(%2d, 3) = %d\n", i, int_mirror(i, 3)); 1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 1469a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 1479a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#endif 1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1499a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned tm) { 1509a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (SkShader::kClamp_TileMode == tm) 1519a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return int_clamp; 1529a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (SkShader::kRepeat_TileMode == tm) 1539a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return int_repeat; 1549a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT(SkShader::kMirror_TileMode == tm); 1559a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return int_mirror; 1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project////////////////////////////////////////////////////////////////////////////// 1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) 1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project int i; 1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 1643600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#if defined(__ARM_HAVE_NEON) 1653600ab34671774af980bb97ecff2842c4cfc5955Mike Reed if (count >= 8) { 1663600ab34671774af980bb97ecff2842c4cfc5955Mike Reed /* SkFixed is 16.16 fixed point */ 1673600ab34671774af980bb97ecff2842c4cfc5955Mike Reed SkFixed dx2 = dx+dx; 1683600ab34671774af980bb97ecff2842c4cfc5955Mike Reed SkFixed dx4 = dx2+dx2; 1693600ab34671774af980bb97ecff2842c4cfc5955Mike Reed SkFixed dx8 = dx4+dx4; 1703600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 1713600ab34671774af980bb97ecff2842c4cfc5955Mike Reed /* now build fx/fx+dx/fx+2dx/fx+3dx */ 1723600ab34671774af980bb97ecff2842c4cfc5955Mike Reed SkFixed fx1, fx2, fx3; 1733600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x2_t lower, upper; 1743600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t lbase, hbase; 1753600ab34671774af980bb97ecff2842c4cfc5955Mike Reed uint16_t *dst16 = (uint16_t *)dst; 1763600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 1773600ab34671774af980bb97ecff2842c4cfc5955Mike Reed fx1 = fx+dx; 1783600ab34671774af980bb97ecff2842c4cfc5955Mike Reed fx2 = fx1+dx; 1793600ab34671774af980bb97ecff2842c4cfc5955Mike Reed fx3 = fx2+dx; 1803600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 1813600ab34671774af980bb97ecff2842c4cfc5955Mike Reed /* avoid an 'lbase unitialized' warning */ 1823600ab34671774af980bb97ecff2842c4cfc5955Mike Reed lbase = vdupq_n_s32(fx); 1833600ab34671774af980bb97ecff2842c4cfc5955Mike Reed lbase = vsetq_lane_s32(fx1, lbase, 1); 1843600ab34671774af980bb97ecff2842c4cfc5955Mike Reed lbase = vsetq_lane_s32(fx2, lbase, 2); 1853600ab34671774af980bb97ecff2842c4cfc5955Mike Reed lbase = vsetq_lane_s32(fx3, lbase, 3); 1863600ab34671774af980bb97ecff2842c4cfc5955Mike Reed hbase = vaddq_s32(lbase, vdupq_n_s32(dx4)); 1873600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 1883600ab34671774af980bb97ecff2842c4cfc5955Mike Reed /* take upper 16 of each, store, and bump everything */ 1893600ab34671774af980bb97ecff2842c4cfc5955Mike Reed do { 1903600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t lout, hout; 1913600ab34671774af980bb97ecff2842c4cfc5955Mike Reed uint16x8_t hi16; 1923600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 1933600ab34671774af980bb97ecff2842c4cfc5955Mike Reed lout = lbase; 1943600ab34671774af980bb97ecff2842c4cfc5955Mike Reed hout = hbase; 1953600ab34671774af980bb97ecff2842c4cfc5955Mike Reed /* gets hi's of all louts then hi's of all houts */ 1963600ab34671774af980bb97ecff2842c4cfc5955Mike Reed asm ("vuzpq.16 %q0, %q1" : "+w" (lout), "+w" (hout)); 1973600ab34671774af980bb97ecff2842c4cfc5955Mike Reed hi16 = vreinterpretq_u16_s32(hout); 1983600ab34671774af980bb97ecff2842c4cfc5955Mike Reed vst1q_u16(dst16, hi16); 1993600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2003600ab34671774af980bb97ecff2842c4cfc5955Mike Reed /* on to the next */ 2013600ab34671774af980bb97ecff2842c4cfc5955Mike Reed lbase = vaddq_s32 (lbase, vdupq_n_s32(dx8)); 2023600ab34671774af980bb97ecff2842c4cfc5955Mike Reed hbase = vaddq_s32 (hbase, vdupq_n_s32(dx8)); 2033600ab34671774af980bb97ecff2842c4cfc5955Mike Reed dst16 += 8; 2043600ab34671774af980bb97ecff2842c4cfc5955Mike Reed count -= 8; 2053600ab34671774af980bb97ecff2842c4cfc5955Mike Reed fx += dx8; 2063600ab34671774af980bb97ecff2842c4cfc5955Mike Reed } while (count >= 8); 2073600ab34671774af980bb97ecff2842c4cfc5955Mike Reed dst = (uint32_t *) dst16; 2083600ab34671774af980bb97ecff2842c4cfc5955Mike Reed } 2093600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#else 2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project for (i = (count >> 2); i > 0; --i) 2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fx += dx+dx; 2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = pack_two_shorts(fx >> 16, (fx + dx) >> 16); 2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fx += dx+dx; 2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2173600ab34671774af980bb97ecff2842c4cfc5955Mike Reed count &= 3; 2183600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#endif 2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2203600ab34671774af980bb97ecff2842c4cfc5955Mike Reed uint16_t* xx = (uint16_t*)dst; 2213600ab34671774af980bb97ecff2842c4cfc5955Mike Reed for (i = count; i > 0; --i) { 2220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *xx++ = SkToU16(fx >> 16); fx += dx; 2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count) 2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ 2283600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2293600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#if defined(__ARM_HAVE_NEON) 2303600ab34671774af980bb97ecff2842c4cfc5955Mike Reed if (count >= 8) { 2313600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t wide_fx; 2323600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t wide_fx2; 2333600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t wide_dx8 = vdupq_n_s32(dx*8); 2343600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2353600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx = vdupq_n_s32(fx); 2363600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx = vsetq_lane_s32(fx+dx, wide_fx, 1); 2373600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx = vsetq_lane_s32(fx+dx+dx, wide_fx, 2); 2383600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx = vsetq_lane_s32(fx+dx+dx+dx, wide_fx, 3); 2393600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2403600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx2 = vaddq_s32(wide_fx, vdupq_n_s32(dx+dx+dx+dx)); 2413600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2423600ab34671774af980bb97ecff2842c4cfc5955Mike Reed while (count >= 8) { 2433600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t wide_out; 2443600ab34671774af980bb97ecff2842c4cfc5955Mike Reed int32x4_t wide_out2; 2453600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2463600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_out = vshlq_n_s32(vshrq_n_s32(wide_fx, 12), 14); 2473600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_out = vorrq_s32(wide_out, 2483600ab34671774af980bb97ecff2842c4cfc5955Mike Reed vaddq_s32(vshrq_n_s32(wide_fx,16), vdupq_n_s32(1))); 2493600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2503600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_out2 = vshlq_n_s32(vshrq_n_s32(wide_fx2, 12), 14); 2513600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_out2 = vorrq_s32(wide_out2, 2523600ab34671774af980bb97ecff2842c4cfc5955Mike Reed vaddq_s32(vshrq_n_s32(wide_fx2,16), vdupq_n_s32(1))); 2533600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2543600ab34671774af980bb97ecff2842c4cfc5955Mike Reed vst1q_u32(dst, vreinterpretq_u32_s32(wide_out)); 2553600ab34671774af980bb97ecff2842c4cfc5955Mike Reed vst1q_u32(dst+4, vreinterpretq_u32_s32(wide_out2)); 2563600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2573600ab34671774af980bb97ecff2842c4cfc5955Mike Reed dst += 8; 2583600ab34671774af980bb97ecff2842c4cfc5955Mike Reed fx += dx*8; 2593600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx = vaddq_s32(wide_fx, wide_dx8); 2603600ab34671774af980bb97ecff2842c4cfc5955Mike Reed wide_fx2 = vaddq_s32(wide_fx2, wide_dx8); 2613600ab34671774af980bb97ecff2842c4cfc5955Mike Reed count -= 8; 2623600ab34671774af980bb97ecff2842c4cfc5955Mike Reed } 2633600ab34671774af980bb97ecff2842c4cfc5955Mike Reed } 2643600ab34671774af980bb97ecff2842c4cfc5955Mike Reed#endif 2653600ab34671774af980bb97ecff2842c4cfc5955Mike Reed 2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project if (count & 1) 2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((fx >> (16 + 14)) == 0); 2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fx += dx; 2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project while ((count -= 2) >= 0) 2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project { 2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project SkASSERT((fx >> (16 + 14)) == 0); 2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fx += dx; 2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project *dst++ = (fx >> 12 << 14) | ((fx >> 16) + 1); 2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project fx += dx; 2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project } 2810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2839a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed/////////////////////////////////////////////////////////////////////////////// 2849a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed// stores the same as SCALE, but is cheaper to compute. Also since there is no 2859a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed// scale, we don't need/have a FILTER version 2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 2879a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic void fill_sequential(uint16_t xptr[], int start, int count) { 2889a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#if 1 2899a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (reinterpret_cast<intptr_t>(xptr) & 0x2) { 2909a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed *xptr++ = start++; 2919a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count -= 1; 2929a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 2939a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (count > 3) { 2949a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint32_t* xxptr = reinterpret_cast<uint32_t*>(xptr); 2959a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint32_t pattern0 = PACK_TWO_SHORTS(start + 0, start + 1); 2969a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint32_t pattern1 = PACK_TWO_SHORTS(start + 2, start + 3); 2979a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed start += count & ~3; 2989a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int qcount = count >> 2; 2999a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed do { 3009a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed *xxptr++ = pattern0; 3019a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed pattern0 += 0x40004; 3029a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed *xxptr++ = pattern1; 3039a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed pattern1 += 0x40004; 304c1c43a17e7f2a87951739691056728a80e9aef6bMike Reed } while (--qcount != 0); 3059a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr = reinterpret_cast<uint16_t*>(xxptr); 3069a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count &= 3; 3079a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3089a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed while (--count >= 0) { 3099a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed *xptr++ = start++; 3109a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3119a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#else 3129a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed for (int i = 0; i < count; i++) { 3139a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed *xptr++ = start++; 3149a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3159a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed#endif 3169a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3189a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic int nofilter_trans_preamble(const SkBitmapProcState& s, uint32_t** xy, 3199a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int x, int y) { 3209a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkPoint pt; 3219a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 3229a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkIntToScalar(y) + SK_ScalarHalf, &pt); 3239a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed **xy = s.fIntTileProcY(SkScalarToFixed(pt.fY) >> 16, 3249a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed s.fBitmap->height()); 3259a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed *xy += 1; // bump the ptr 3269a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // return our starting X position 3279a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return SkScalarToFixed(pt.fX) >> 16; 3289a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3309a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic void clampx_nofilter_trans(const SkBitmapProcState& s, 3319a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint32_t xy[], int count, int x, int y) { 3329a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 3339a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3349a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int xpos = nofilter_trans_preamble(s, &xy, x, y); 3359a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed const int width = s.fBitmap->width(); 3369a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (1 == width) { 3379a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // all of the following X values must be 0 3389a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed memset(xy, 0, count * sizeof(uint16_t)); 3399a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return; 3409a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 3429a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 3439a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int n; 3449a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3459a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // fill before 0 as needed 3469a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (xpos < 0) { 3479a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = -xpos; 3489a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (n > count) { 3499a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = count; 3509a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3519a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed memset(xptr, 0, n * sizeof(uint16_t)); 3529a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count -= n; 3539a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (0 == count) { 3549a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return; 3559a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3569a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr += n; 3579a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xpos = 0; 3589a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3599a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3609a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // fill in 0..width-1 if needed 3619a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (xpos < width) { 3629a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = width - xpos; 3639a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (n > count) { 3649a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = count; 3659a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3669a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, xpos, n); 3679a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count -= n; 3689a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (0 == count) { 3699a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return; 3709a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3719a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr += n; 3729a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3739a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3749a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // fill the remaining with the max value 3754c1037238c8ebcef8c75b5d43730ed308a11102cMike Reed sk_memset16(xptr, width - 1, count); 3769a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 3779a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3789a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic void repeatx_nofilter_trans(const SkBitmapProcState& s, 3799a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint32_t xy[], int count, int x, int y) { 3809a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 3819a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3829a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int xpos = nofilter_trans_preamble(s, &xy, x, y); 3839a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed const int width = s.fBitmap->width(); 3849a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (1 == width) { 3859a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // all of the following X values must be 0 3869a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed memset(xy, 0, count * sizeof(uint16_t)); 3879a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return; 3889a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3899a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 3909a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 3919a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int start = sk_int_mod(xpos, width); 3929a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int n = width - start; 3939a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (n > count) { 3949a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = count; 3959a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 3969a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, start, n); 3979a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr += n; 3989a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count -= n; 3999a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4009a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed while (count >= width) { 4019a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, 0, width); 4029a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr += width; 4039a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count -= width; 4049a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4059a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4069a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (count > 0) { 4079a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, 0, count); 4089a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4099a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 4109a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4119a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic void fill_backwards(uint16_t xptr[], int pos, int count) { 4129a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed for (int i = 0; i < count; i++) { 4139a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT(pos >= 0); 4149a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr[i] = pos--; 4159a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4169a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 4179a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4189a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reedstatic void mirrorx_nofilter_trans(const SkBitmapProcState& s, 4199a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint32_t xy[], int count, int x, int y) { 4209a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); 4219a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4229a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int xpos = nofilter_trans_preamble(s, &xy, x, y); 4239a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed const int width = s.fBitmap->width(); 4249a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (1 == width) { 4259a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // all of the following X values must be 0 4269a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed memset(xy, 0, count * sizeof(uint16_t)); 4279a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return; 4289a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4299a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4309a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed uint16_t* xptr = reinterpret_cast<uint16_t*>(xy); 4319a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // need to know our start, and our initial phase (forward or backward) 4329a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed bool forward; 4339a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int n; 4349a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int start = sk_int_mod(xpos, 2 * width); 4359a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (start >= width) { 4369a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed start = width + ~(start - width); 4379a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed forward = false; 4389a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = start + 1; // [start .. 0] 4399a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else { 4409a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed forward = true; 4419a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = width - start; // [start .. width) 4429a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4439a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (n > count) { 4449a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed n = count; 4459a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4469a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (forward) { 4479a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, start, n); 4489a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else { 4499a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_backwards(xptr, start, n); 4509a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4519a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed forward = !forward; 4529a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr += n; 4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project count -= n; 4549a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4559a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed while (count >= width) { 4569a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (forward) { 4579a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, 0, width); 4589a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else { 4599a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_backwards(xptr, width - 1, width); 4609a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4619a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed forward = !forward; 4629a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed xptr += width; 4639a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed count -= width; 4649a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4659a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4669a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (count > 0) { 4679a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (forward) { 4689a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_sequential(xptr, 0, count); 4699a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else { 4709a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fill_backwards(xptr, width - 1, count); 4719a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4729a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4739a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed} 4749a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4759a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed/////////////////////////////////////////////////////////////////////////////// 4769a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4779a5843c9b6ef01f25513bef72a91936f75cc4458Mike ReedSkBitmapProcState::MatrixProc 4789a5843c9b6ef01f25513bef72a91936f75cc4458Mike ReedSkBitmapProcState::chooseMatrixProc(bool trivial_matrix) { 4799a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed// test_int_tileprocs(); 4809a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // check for our special case when there is no scale/affine/perspective 4819a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (trivial_matrix) { 4829a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkASSERT(!fDoFilter); 4839a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fIntTileProcY = choose_int_tile_proc(fTileModeY); 4849a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed switch (fTileModeX) { 4859a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed case SkShader::kClamp_TileMode: 4869a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return clampx_nofilter_trans; 4879a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed case SkShader::kRepeat_TileMode: 4889a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return repeatx_nofilter_trans; 4899a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed case SkShader::kMirror_TileMode: 4909a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return mirrorx_nofilter_trans; 4919a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4929a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4939a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 4949a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed int index = 0; 4959a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (fDoFilter) { 4969a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed index = 1; 4979a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 4989a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (fInvType & SkMatrix::kPerspective_Mask) { 4999a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed index += 4; 5009a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } else if (fInvType & SkMatrix::kAffine_Mask) { 50117d1e95f527382203087356175890dab480ed3baMike Reed index += 2; 5029a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 5039a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 5049a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (SkShader::kClamp_TileMode == fTileModeX && 5059a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkShader::kClamp_TileMode == fTileModeY) 5069a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed { 5079a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // clamp gets special version of filterOne 5089a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fFilterOneX = SK_Fixed1; 5099a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fFilterOneY = SK_Fixed1; 5109a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return ClampX_ClampY_Procs[index]; 5119a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 5129a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 5139a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed // all remaining procs use this form for filterOne 5149a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fFilterOneX = SK_Fixed1 / fBitmap->width(); 5159a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fFilterOneY = SK_Fixed1 / fBitmap->height(); 5169a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 5179a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed if (SkShader::kRepeat_TileMode == fTileModeX && 5189a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed SkShader::kRepeat_TileMode == fTileModeY) 5199a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed { 5209a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return RepeatX_RepeatY_Procs[index]; 5219a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed } 5229a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed 5239a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fTileProcX = choose_tile_proc(fTileModeX); 5249a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed fTileProcY = choose_tile_proc(fTileModeY); 5259a5843c9b6ef01f25513bef72a91936f75cc4458Mike Reed return GeneralXY_Procs[index]; 5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project} 5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project 528