reed@google.com | 69d0555 | 2011-05-24 12:14:28 +0000 | [diff] [blame] | 1 | /* |
epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 2 | * Copyright 2011 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
reed@google.com | 69d0555 | 2011-05-24 12:14:28 +0000 | [diff] [blame] | 6 | */ |
| 7 | |
tomhudson@google.com | 889bd8b | 2011-09-27 17:38:17 +0000 | [diff] [blame] | 8 | #include "SkMath.h" |
reed@google.com | 4b163ed | 2012-08-07 21:35:13 +0000 | [diff] [blame] | 9 | #include "SkMathPriv.h" |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 10 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 11 | #define SCALE_FILTER_NAME MAKENAME(_filter_scale) |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 12 | |
| 13 | #define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) |
| 14 | #define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y) |
| 15 | |
| 16 | #ifndef PREAMBLE |
| 17 | #define PREAMBLE(state) |
| 18 | #define PREAMBLE_PARAM_X |
| 19 | #define PREAMBLE_PARAM_Y |
| 20 | #define PREAMBLE_ARG_X |
| 21 | #define PREAMBLE_ARG_Y |
| 22 | #endif |
| 23 | |
caryclark@google.com | 803eceb | 2012-06-06 12:09:34 +0000 | [diff] [blame] | 24 | // declare functions externally to suppress warnings. |
caryclark@google.com | 803eceb | 2012-06-06 12:09:34 +0000 | [diff] [blame] | 25 | void SCALE_FILTER_NAME(const SkBitmapProcState& s, |
| 26 | uint32_t xy[], int count, int x, int y); |
caryclark@google.com | 803eceb | 2012-06-06 12:09:34 +0000 | [diff] [blame] | 27 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 28 | static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, |
| 29 | SkFixed one PREAMBLE_PARAM_Y) { |
| 30 | unsigned i = TILEY_PROCF(f, max); |
Florin Malita | d1c550e | 2016-12-19 10:55:41 -0500 | [diff] [blame] | 31 | i = (i << 4) | EXTRACT_LOW_BITS(f, max); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 32 | return (i << 14) | (TILEY_PROCF((f + one), max)); |
| 33 | } |
| 34 | |
| 35 | static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max, |
| 36 | SkFixed one PREAMBLE_PARAM_X) { |
| 37 | unsigned i = TILEX_PROCF(f, max); |
Florin Malita | d1c550e | 2016-12-19 10:55:41 -0500 | [diff] [blame] | 38 | i = (i << 4) | EXTRACT_LOW_BITS(f, max); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 39 | return (i << 14) | (TILEX_PROCF((f + one), max)); |
| 40 | } |
| 41 | |
senorblanco@chromium.org | dc7de74 | 2009-11-30 20:00:29 +0000 | [diff] [blame] | 42 | void SCALE_FILTER_NAME(const SkBitmapProcState& s, |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 43 | uint32_t xy[], int count, int x, int y) { |
| 44 | SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | |
| 45 | SkMatrix::kScale_Mask)) == 0); |
| 46 | SkASSERT(s.fInvKy == 0); |
| 47 | |
| 48 | PREAMBLE(s); |
rmistry@google.com | fbfcd56 | 2012-08-23 18:09:54 +0000 | [diff] [blame] | 49 | |
reed | ad7ae6c | 2015-06-04 14:12:25 -0700 | [diff] [blame] | 50 | const unsigned maxX = s.fPixmap.width() - 1; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 51 | const SkFixed one = s.fFilterOneX; |
reed@google.com | 411215a | 2012-03-08 20:13:46 +0000 | [diff] [blame] | 52 | const SkFractionalInt dx = s.fInvSxFractionalInt; |
| 53 | SkFractionalInt fx; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 54 | |
| 55 | { |
fmalita | 2404f03 | 2016-02-03 05:44:21 -0800 | [diff] [blame] | 56 | const SkBitmapProcStateAutoMapper mapper(s, x, y); |
fmalita | be5cfa9 | 2016-02-03 10:21:33 -0800 | [diff] [blame] | 57 | const SkFixed fy = mapper.fixedY(); |
reed | ad7ae6c | 2015-06-04 14:12:25 -0700 | [diff] [blame] | 58 | const unsigned maxY = s.fPixmap.height() - 1; |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 59 | // compute our two Y values up front |
| 60 | *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); |
| 61 | // now initialize fx |
fmalita | be5cfa9 | 2016-02-03 10:21:33 -0800 | [diff] [blame] | 62 | fx = mapper.fractionalIntX(); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 63 | } |
| 64 | |
| 65 | #ifdef CHECK_FOR_DECAL |
Florin Malita | 9953737 | 2017-01-04 13:01:55 -0500 | [diff] [blame] | 66 | const SkFixed fixedFx = SkFractionalIntToFixed(fx); |
| 67 | const SkFixed fixedDx = SkFractionalIntToFixed(dx); |
| 68 | if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) { |
| 69 | decal_filter_scale(xy, fixedFx, fixedDx, count); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 70 | } else |
| 71 | #endif |
| 72 | { |
| 73 | do { |
reed@google.com | 411215a | 2012-03-08 20:13:46 +0000 | [diff] [blame] | 74 | SkFixed fixedFx = SkFractionalIntToFixed(fx); |
| 75 | *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X); |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 76 | fx += dx; |
| 77 | } while (--count != 0); |
| 78 | } |
| 79 | } |
| 80 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 81 | #undef MAKENAME |
| 82 | #undef TILEX_PROCF |
| 83 | #undef TILEY_PROCF |
| 84 | #ifdef CHECK_FOR_DECAL |
| 85 | #undef CHECK_FOR_DECAL |
| 86 | #endif |
| 87 | |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 88 | #undef SCALE_FILTER_NAME |
reed@android.com | 8a1c16f | 2008-12-17 15:59:43 +0000 | [diff] [blame] | 89 | |
| 90 | #undef PREAMBLE |
| 91 | #undef PREAMBLE_PARAM_X |
| 92 | #undef PREAMBLE_PARAM_Y |
| 93 | #undef PREAMBLE_ARG_X |
| 94 | #undef PREAMBLE_ARG_Y |
| 95 | |
Florin Malita | d1c550e | 2016-12-19 10:55:41 -0500 | [diff] [blame] | 96 | #undef EXTRACT_LOW_BITS |