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.
28 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
29 uint32_t xy[], int count, int x, int y);
30 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
31 uint32_t xy[], int count, int x, int y);
32 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
33 uint32_t* SK_RESTRICT xy, int count,
34 int x, int y);
35
PACK_FILTER_Y_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_Y)36 static 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
PACK_FILTER_X_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_X)43 static 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
SCALE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)50 void 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.fPixmap.width() - 1;
59 const SkFixed one = s.fFilterOneX;
60 const SkFractionalInt dx = s.fInvSxFractionalInt;
61 SkFractionalInt fx;
62
63 {
64 const SkBitmapProcStateAutoMapper mapper(s, x, y);
65 const SkFixed fy = mapper.fixedY();
66 const unsigned maxY = s.fPixmap.height() - 1;
67 // compute our two Y values up front
68 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
69 // now initialize fx
70 fx = mapper.fractionalIntX();
71 }
72
73 #ifdef CHECK_FOR_DECAL
74 if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) {
75 decal_filter_scale(xy, SkFractionalIntToFixed(fx),
76 SkFractionalIntToFixed(dx), count);
77 } else
78 #endif
79 {
80 do {
81 SkFixed fixedFx = SkFractionalIntToFixed(fx);
82 *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X);
83 fx += dx;
84 } while (--count != 0);
85 }
86 }
87
AFFINE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)88 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
89 uint32_t xy[], int count, int x, int y) {
90 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
91 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
92 SkMatrix::kScale_Mask |
93 SkMatrix::kAffine_Mask)) == 0);
94
95 PREAMBLE(s);
96 const SkBitmapProcStateAutoMapper mapper(s, x, y);
97
98 SkFixed oneX = s.fFilterOneX;
99 SkFixed oneY = s.fFilterOneY;
100 SkFixed fx = mapper.fixedX();
101 SkFixed fy = mapper.fixedY();
102 SkFixed dx = s.fInvSx;
103 SkFixed dy = s.fInvKy;
104 unsigned maxX = s.fPixmap.width() - 1;
105 unsigned maxY = s.fPixmap.height() - 1;
106
107 do {
108 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
109 fy += dy;
110 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
111 fx += dx;
112 } while (--count != 0);
113 }
114
PERSP_FILTER_NAME(const SkBitmapProcState & s,uint32_t * SK_RESTRICT xy,int count,int x,int y)115 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
116 uint32_t* SK_RESTRICT xy, int count,
117 int x, int y) {
118 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
119
120 PREAMBLE(s);
121 unsigned maxX = s.fPixmap.width() - 1;
122 unsigned maxY = s.fPixmap.height() - 1;
123 SkFixed oneX = s.fFilterOneX;
124 SkFixed oneY = s.fFilterOneY;
125
126 SkPerspIter iter(s.fInvMatrix,
127 SkIntToScalar(x) + SK_ScalarHalf,
128 SkIntToScalar(y) + SK_ScalarHalf, count);
129
130 while ((count = iter.next()) != 0) {
131 const SkFixed* SK_RESTRICT srcXY = iter.getXY();
132 do {
133 *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY,
134 oneY PREAMBLE_ARG_Y);
135 *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX,
136 oneX PREAMBLE_ARG_X);
137 srcXY += 2;
138 } while (--count != 0);
139 }
140 }
141
142 #undef MAKENAME
143 #undef TILEX_PROCF
144 #undef TILEY_PROCF
145 #ifdef CHECK_FOR_DECAL
146 #undef CHECK_FOR_DECAL
147 #endif
148
149 #undef SCALE_FILTER_NAME
150 #undef AFFINE_FILTER_NAME
151 #undef PERSP_FILTER_NAME
152
153 #undef PREAMBLE
154 #undef PREAMBLE_PARAM_X
155 #undef PREAMBLE_PARAM_Y
156 #undef PREAMBLE_ARG_X
157 #undef PREAMBLE_ARG_Y
158
159 #undef TILEX_LOW_BITS
160 #undef TILEY_LOW_BITS
161