| OLD | NEW |
| 1 /* NEON optimized code (C) COPYRIGHT 2009 Motorola | 1 /* NEON optimized code (C) COPYRIGHT 2009 Motorola |
| 2 * | 2 * |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 #include "SkBitmapProcState.h" | 7 #include "SkBitmapProcState.h" |
| 8 #include "SkPerspIter.h" | 8 #include "SkPerspIter.h" |
| 9 #include "SkShader.h" | 9 #include "SkShader.h" |
| 10 #include "SkUtils.h" | 10 #include "SkUtils.h" |
| 11 #include "SkUtilsArm.h" | 11 #include "SkUtilsArm.h" |
| 12 | 12 #include "SkBitmapProcState_utils.h" |
| 13 // Helper to ensure that when we shift down, we do it w/o sign-extension | |
| 14 // so the caller doesn't have to manually mask off the top 16 bits | |
| 15 // | |
| 16 static unsigned SK_USHIFT16(unsigned x) { | |
| 17 return x >> 16; | |
| 18 } | |
| 19 | 13 |
| 20 /* returns 0...(n-1) given any x (positive or negative). | 14 /* returns 0...(n-1) given any x (positive or negative). |
| 21 | 15 |
| 22 As an example, if n (which is always positive) is 5... | 16 As an example, if n (which is always positive) is 5... |
| 23 | 17 |
| 24 x: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 | 18 x: -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 |
| 25 returns: 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 | 19 returns: 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 |
| 26 */ | 20 */ |
| 27 static inline int sk_int_mod(int x, int n) { | 21 static inline int sk_int_mod(int x, int n) { |
| 28 SkASSERT(n > 0); | 22 SkASSERT(n > 0); |
| 29 if ((unsigned)x >= (unsigned)n) { | 23 if ((unsigned)x >= (unsigned)n) { |
| 30 if (x < 0) { | 24 if (x < 0) { |
| 31 x = n + ~(~x % n); | 25 x = n + ~(~x % n); |
| 32 } else { | 26 } else { |
| 33 x = x % n; | 27 x = x % n; |
| 34 } | 28 } |
| 35 } | 29 } |
| 36 return x; | 30 return x; |
| 37 } | 31 } |
| 38 | 32 |
| 39 /* | |
| 40 * The decal_ functions require that | |
| 41 * 1. dx > 0 | |
| 42 * 2. [fx, fx+dx, fx+2dx, fx+3dx, ... fx+(count-1)dx] are all <= maxX | |
| 43 * | |
| 44 * In addition, we use SkFractionalInt to keep more fractional precision than | |
| 45 * just SkFixed, so we will abort the decal_ call if dx is very small, since | |
| 46 * the decal_ function just operates on SkFixed. If that were changed, we could | |
| 47 * skip the very_small test here. | |
| 48 */ | |
| 49 static inline bool can_truncate_to_fixed_for_decal(SkFractionalInt frX, | |
| 50 SkFractionalInt frDx, | |
| 51 int count, unsigned max) { | |
| 52 SkFixed dx = SkFractionalIntToFixed(frDx); | |
| 53 | |
| 54 // if decal_ kept SkFractionalInt precision, this would just be dx <= 0 | |
| 55 // I just made up the 1/256. Just don't want to perceive accumulated error | |
| 56 // if we truncate frDx and lose its low bits. | |
| 57 if (dx <= SK_Fixed1 / 256) { | |
| 58 return false; | |
| 59 } | |
| 60 | |
| 61 // We cast to unsigned so we don't have to check for negative values, which | |
| 62 // will now appear as very large positive values, and thus fail our test! | |
| 63 SkFixed fx = SkFractionalIntToFixed(frX); | |
| 64 return (unsigned)SkFixedFloorToInt(fx) <= max && | |
| 65 (unsigned)SkFixedFloorToInt(fx + dx * (count - 1)) < max; | |
| 66 } | |
| 67 | |
| 68 void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); | 33 void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); |
| 69 void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); | 34 void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count); |
| 70 | 35 |
| 71 // Compile neon code paths if needed | 36 // Compile neon code paths if needed |
| 72 #if !SK_ARM_NEON_IS_NONE | 37 #if !SK_ARM_NEON_IS_NONE |
| 73 | 38 |
| 74 // These are defined in src/opts/SkBitmapProcState_matrixProcs_neon.cpp | 39 // These are defined in src/opts/SkBitmapProcState_matrixProcs_neon.cpp |
| 75 extern const SkBitmapProcState::MatrixProc ClampX_ClampY_Procs_neon[]; | 40 extern const SkBitmapProcState::MatrixProc ClampX_ClampY_Procs_neon[]; |
| 76 extern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; | 41 extern const SkBitmapProcState::MatrixProc RepeatX_RepeatY_Procs_neon[]; |
| 77 | 42 |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 { | 477 { |
| 513 return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index]; | 478 return SK_ARM_NEON_WRAP(RepeatX_RepeatY_Procs)[index]; |
| 514 } | 479 } |
| 515 | 480 |
| 516 fTileProcX = choose_tile_proc(fTileModeX); | 481 fTileProcX = choose_tile_proc(fTileModeX); |
| 517 fTileProcY = choose_tile_proc(fTileModeY); | 482 fTileProcY = choose_tile_proc(fTileModeY); |
| 518 fTileLowBitsProcX = choose_tile_lowbits_proc(fTileModeX); | 483 fTileLowBitsProcX = choose_tile_lowbits_proc(fTileModeX); |
| 519 fTileLowBitsProcY = choose_tile_lowbits_proc(fTileModeY); | 484 fTileLowBitsProcY = choose_tile_lowbits_proc(fTileModeY); |
| 520 return GeneralXY_Procs[index]; | 485 return GeneralXY_Procs[index]; |
| 521 } | 486 } |
| OLD | NEW |