1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9#include "SkMath.h" 10#include "SkMathPriv.h" 11 12#define SCALE_FILTER_NAME MAKENAME(_filter_scale) 13#define AFFINE_FILTER_NAME MAKENAME(_filter_affine) 14#define PERSP_FILTER_NAME MAKENAME(_filter_persp) 15 16#define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) 17#define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y) 18 19#ifndef PREAMBLE 20 #define PREAMBLE(state) 21 #define PREAMBLE_PARAM_X 22 #define PREAMBLE_PARAM_Y 23 #define PREAMBLE_ARG_X 24 #define PREAMBLE_ARG_Y 25#endif 26 27// declare functions externally to suppress warnings. 28void SCALE_FILTER_NAME(const SkBitmapProcState& s, 29 uint32_t xy[], int count, int x, int y); 30void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 31 uint32_t xy[], int count, int x, int y); 32void PERSP_FILTER_NAME(const SkBitmapProcState& s, 33 uint32_t* SK_RESTRICT xy, int count, 34 int x, int y); 35 36static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, 37 SkFixed one PREAMBLE_PARAM_Y) { 38 unsigned i = TILEY_PROCF(f, max); 39 i = (i << 4) | TILEY_LOW_BITS(f, max); 40 return (i << 14) | (TILEY_PROCF((f + one), max)); 41} 42 43static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max, 44 SkFixed one PREAMBLE_PARAM_X) { 45 unsigned i = TILEX_PROCF(f, max); 46 i = (i << 4) | TILEX_LOW_BITS(f, max); 47 return (i << 14) | (TILEX_PROCF((f + one), max)); 48} 49 50void SCALE_FILTER_NAME(const SkBitmapProcState& s, 51 uint32_t xy[], int count, int x, int y) { 52 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 53 SkMatrix::kScale_Mask)) == 0); 54 SkASSERT(s.fInvKy == 0); 55 56 PREAMBLE(s); 57 58 const unsigned maxX = s.fBitmap->width() - 1; 59 const SkFixed one = s.fFilterOneX; 60 const SkFractionalInt dx = s.fInvSxFractionalInt; 61 SkFractionalInt fx; 62 63 { 64 SkPoint pt; 65 s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, 66 SkIntToScalar(y) + SK_ScalarHalf, &pt); 67 const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1); 68 const unsigned maxY = s.fBitmap->height() - 1; 69 // compute our two Y values up front 70 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); 71 // now initialize fx 72 fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1); 73 } 74 75#ifdef CHECK_FOR_DECAL 76 if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { 77 decal_filter_scale(xy, SkFractionalIntToFixed(fx), 78 SkFractionalIntToFixed(dx), count); 79 } else 80#endif 81 { 82 do { 83 SkFixed fixedFx = SkFractionalIntToFixed(fx); 84 *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X); 85 fx += dx; 86 } while (--count != 0); 87 } 88} 89 90void AFFINE_FILTER_NAME(const SkBitmapProcState& s, 91 uint32_t xy[], int count, int x, int y) { 92 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); 93 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | 94 SkMatrix::kScale_Mask | 95 SkMatrix::kAffine_Mask)) == 0); 96 97 PREAMBLE(s); 98 SkPoint srcPt; 99 s.fInvProc(s.fInvMatrix, 100 SkIntToScalar(x) + SK_ScalarHalf, 101 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); 102 103 SkFixed oneX = s.fFilterOneX; 104 SkFixed oneY = s.fFilterOneY; 105 SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1); 106 SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1); 107 SkFixed dx = s.fInvSx; 108 SkFixed dy = s.fInvKy; 109 unsigned maxX = s.fBitmap->width() - 1; 110 unsigned maxY = s.fBitmap->height() - 1; 111 112 do { 113 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); 114 fy += dy; 115 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); 116 fx += dx; 117 } while (--count != 0); 118} 119 120void PERSP_FILTER_NAME(const SkBitmapProcState& s, 121 uint32_t* SK_RESTRICT xy, int count, 122 int x, int y) { 123 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); 124 125 PREAMBLE(s); 126 unsigned maxX = s.fBitmap->width() - 1; 127 unsigned maxY = s.fBitmap->height() - 1; 128 SkFixed oneX = s.fFilterOneX; 129 SkFixed oneY = s.fFilterOneY; 130 131 SkPerspIter iter(s.fInvMatrix, 132 SkIntToScalar(x) + SK_ScalarHalf, 133 SkIntToScalar(y) + SK_ScalarHalf, count); 134 135 while ((count = iter.next()) != 0) { 136 const SkFixed* SK_RESTRICT srcXY = iter.getXY(); 137 do { 138 *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY, 139 oneY PREAMBLE_ARG_Y); 140 *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX, 141 oneX PREAMBLE_ARG_X); 142 srcXY += 2; 143 } while (--count != 0); 144 } 145} 146 147#undef MAKENAME 148#undef TILEX_PROCF 149#undef TILEY_PROCF 150#ifdef CHECK_FOR_DECAL 151 #undef CHECK_FOR_DECAL 152#endif 153 154#undef SCALE_FILTER_NAME 155#undef AFFINE_FILTER_NAME 156#undef PERSP_FILTER_NAME 157 158#undef PREAMBLE 159#undef PREAMBLE_PARAM_X 160#undef PREAMBLE_PARAM_Y 161#undef PREAMBLE_ARG_X 162#undef PREAMBLE_ARG_Y 163 164#undef TILEX_LOW_BITS 165#undef TILEY_LOW_BITS 166