1
2 #define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale)
3 #define SCALE_FILTER_NAME MAKENAME(_filter_scale)
4 #define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine)
5 #define AFFINE_FILTER_NAME MAKENAME(_filter_affine)
6 #define PERSP_NOFILTER_NAME MAKENAME(_nofilter_persp)
7 #define PERSP_FILTER_NAME MAKENAME(_filter_persp)
8
9 #define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x)
10 #define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y)
11
12 #ifndef PREAMBLE
13 #define PREAMBLE(state)
14 #define PREAMBLE_PARAM_X
15 #define PREAMBLE_PARAM_Y
16 #define PREAMBLE_ARG_X
17 #define PREAMBLE_ARG_Y
18 #endif
19
SCALE_NOFILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)20 static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s,
21 uint32_t xy[], int count, int x, int y) {
22 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
23 SkMatrix::kScale_Mask)) == 0);
24
25 PREAMBLE(s);
26 // we store y, x, x, x, x, x
27
28 const unsigned maxX = s.fBitmap->width() - 1;
29 SkFixed fx;
30 {
31 SkPoint pt;
32 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
33 SkIntToScalar(y) + SK_ScalarHalf, &pt);
34 fx = SkScalarToFixed(pt.fY);
35 const unsigned maxY = s.fBitmap->height() - 1;
36 *xy++ = TILEY_PROCF(fx, maxY);
37 fx = SkScalarToFixed(pt.fX);
38 }
39
40 if (0 == maxX) {
41 // all of the following X values must be 0
42 memset(xy, 0, count * sizeof(uint16_t));
43 return;
44 }
45
46 const SkFixed dx = s.fInvSx;
47
48 #ifdef CHECK_FOR_DECAL
49 // test if we don't need to apply the tile proc
50 if ((unsigned)(fx >> 16) <= maxX &&
51 (unsigned)((fx + dx * (count - 1)) >> 16) <= maxX) {
52 decal_nofilter_scale(xy, fx, dx, count);
53 } else
54 #endif
55 {
56 int i;
57 for (i = (count >> 2); i > 0; --i) {
58 unsigned a, b;
59 a = TILEX_PROCF(fx, maxX); fx += dx;
60 b = TILEX_PROCF(fx, maxX); fx += dx;
61 #ifdef SK_CPU_BENDIAN
62 *xy++ = (a << 16) | b;
63 #else
64 *xy++ = (b << 16) | a;
65 #endif
66 a = TILEX_PROCF(fx, maxX); fx += dx;
67 b = TILEX_PROCF(fx, maxX); fx += dx;
68 #ifdef SK_CPU_BENDIAN
69 *xy++ = (a << 16) | b;
70 #else
71 *xy++ = (b << 16) | a;
72 #endif
73 }
74 uint16_t* xx = (uint16_t*)xy;
75 for (i = (count & 3); i > 0; --i) {
76 *xx++ = TILEX_PROCF(fx, maxX); fx += dx;
77 }
78 }
79 }
80
81 // note: we could special-case on a matrix which is skewed in X but not Y.
82 // this would require a more general setup thatn SCALE does, but could use
83 // SCALE's inner loop that only looks at dx
84
AFFINE_NOFILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)85 static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s,
86 uint32_t xy[], int count, int x, int y) {
87 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
88 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
89 SkMatrix::kScale_Mask |
90 SkMatrix::kAffine_Mask)) == 0);
91
92 PREAMBLE(s);
93 SkPoint srcPt;
94 s.fInvProc(*s.fInvMatrix,
95 SkIntToScalar(x) + SK_ScalarHalf,
96 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
97
98 SkFixed fx = SkScalarToFixed(srcPt.fX);
99 SkFixed fy = SkScalarToFixed(srcPt.fY);
100 SkFixed dx = s.fInvSx;
101 SkFixed dy = s.fInvKy;
102 int maxX = s.fBitmap->width() - 1;
103 int maxY = s.fBitmap->height() - 1;
104
105 for (int i = count; i > 0; --i) {
106 *xy++ = (TILEY_PROCF(fy, maxY) << 16) | TILEX_PROCF(fx, maxX);
107 fx += dx; fy += dy;
108 }
109 }
110
PERSP_NOFILTER_NAME(const SkBitmapProcState & s,uint32_t * SK_RESTRICT xy,int count,int x,int y)111 static void PERSP_NOFILTER_NAME(const SkBitmapProcState& s,
112 uint32_t* SK_RESTRICT xy,
113 int count, int x, int y) {
114 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
115
116 PREAMBLE(s);
117 int maxX = s.fBitmap->width() - 1;
118 int maxY = s.fBitmap->height() - 1;
119
120 SkPerspIter iter(*s.fInvMatrix,
121 SkIntToScalar(x) + SK_ScalarHalf,
122 SkIntToScalar(y) + SK_ScalarHalf, count);
123
124 while ((count = iter.next()) != 0) {
125 const SkFixed* SK_RESTRICT srcXY = iter.getXY();
126 while (--count >= 0) {
127 *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) |
128 TILEX_PROCF(srcXY[0], maxX);
129 srcXY += 2;
130 }
131 }
132 }
133
134 //////////////////////////////////////////////////////////////////////////////
135
PACK_FILTER_Y_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_Y)136 static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
137 SkFixed one PREAMBLE_PARAM_Y) {
138 unsigned i = TILEY_PROCF(f, max);
139 i = (i << 4) | TILEY_LOW_BITS(f, max);
140 return (i << 14) | (TILEY_PROCF((f + one), max));
141 }
142
PACK_FILTER_X_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_X)143 static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
144 SkFixed one PREAMBLE_PARAM_X) {
145 unsigned i = TILEX_PROCF(f, max);
146 i = (i << 4) | TILEX_LOW_BITS(f, max);
147 return (i << 14) | (TILEX_PROCF((f + one), max));
148 }
149
SCALE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)150 static void SCALE_FILTER_NAME(const SkBitmapProcState& s,
151 uint32_t xy[], int count, int x, int y) {
152 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
153 SkMatrix::kScale_Mask)) == 0);
154 SkASSERT(s.fInvKy == 0);
155
156 PREAMBLE(s);
157
158 const unsigned maxX = s.fBitmap->width() - 1;
159 const SkFixed one = s.fFilterOneX;
160 const SkFixed dx = s.fInvSx;
161 SkFixed fx;
162
163 {
164 SkPoint pt;
165 s.fInvProc(*s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf,
166 SkIntToScalar(y) + SK_ScalarHalf, &pt);
167 const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1);
168 const unsigned maxY = s.fBitmap->height() - 1;
169 // compute our two Y values up front
170 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
171 // now initialize fx
172 fx = SkScalarToFixed(pt.fX) - (one >> 1);
173 }
174
175 #ifdef CHECK_FOR_DECAL
176 // test if we don't need to apply the tile proc
177 if (dx > 0 &&
178 (unsigned)(fx >> 16) <= maxX &&
179 (unsigned)((fx + dx * (count - 1)) >> 16) < maxX) {
180 decal_filter_scale(xy, fx, dx, count);
181 } else
182 #endif
183 {
184 do {
185 *xy++ = PACK_FILTER_X_NAME(fx, maxX, one PREAMBLE_ARG_X);
186 fx += dx;
187 } while (--count != 0);
188 }
189 }
190
AFFINE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)191 static void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
192 uint32_t xy[], int count, int x, int y) {
193 SkASSERT(s.fInvType & SkMatrix::kAffine_Mask);
194 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
195 SkMatrix::kScale_Mask |
196 SkMatrix::kAffine_Mask)) == 0);
197
198 PREAMBLE(s);
199 SkPoint srcPt;
200 s.fInvProc(*s.fInvMatrix,
201 SkIntToScalar(x) + SK_ScalarHalf,
202 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
203
204 SkFixed oneX = s.fFilterOneX;
205 SkFixed oneY = s.fFilterOneY;
206 SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1);
207 SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1);
208 SkFixed dx = s.fInvSx;
209 SkFixed dy = s.fInvKy;
210 unsigned maxX = s.fBitmap->width() - 1;
211 unsigned maxY = s.fBitmap->height() - 1;
212
213 do {
214 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
215 fy += dy;
216 *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
217 fx += dx;
218 } while (--count != 0);
219 }
220
PERSP_FILTER_NAME(const SkBitmapProcState & s,uint32_t * SK_RESTRICT xy,int count,int x,int y)221 static void PERSP_FILTER_NAME(const SkBitmapProcState& s,
222 uint32_t* SK_RESTRICT xy, int count,
223 int x, int y) {
224 SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask);
225
226 PREAMBLE(s);
227 unsigned maxX = s.fBitmap->width() - 1;
228 unsigned maxY = s.fBitmap->height() - 1;
229 SkFixed oneX = s.fFilterOneX;
230 SkFixed oneY = s.fFilterOneY;
231
232 SkPerspIter iter(*s.fInvMatrix,
233 SkIntToScalar(x) + SK_ScalarHalf,
234 SkIntToScalar(y) + SK_ScalarHalf, count);
235
236 while ((count = iter.next()) != 0) {
237 const SkFixed* SK_RESTRICT srcXY = iter.getXY();
238 do {
239 *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY,
240 oneY PREAMBLE_ARG_Y);
241 *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX,
242 oneX PREAMBLE_ARG_X);
243 srcXY += 2;
244 } while (--count != 0);
245 }
246 }
247
248 static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = {
249 SCALE_NOFILTER_NAME,
250 SCALE_FILTER_NAME,
251 AFFINE_NOFILTER_NAME,
252 AFFINE_FILTER_NAME,
253 PERSP_NOFILTER_NAME,
254 PERSP_FILTER_NAME
255 };
256
257 #undef MAKENAME
258 #undef TILEX_PROCF
259 #undef TILEY_PROCF
260 #ifdef CHECK_FOR_DECAL
261 #undef CHECK_FOR_DECAL
262 #endif
263
264 #undef SCALE_NOFILTER_NAME
265 #undef SCALE_FILTER_NAME
266 #undef AFFINE_NOFILTER_NAME
267 #undef AFFINE_FILTER_NAME
268 #undef PERSP_NOFILTER_NAME
269 #undef PERSP_FILTER_NAME
270
271 #undef PREAMBLE
272 #undef PREAMBLE_PARAM_X
273 #undef PREAMBLE_PARAM_Y
274 #undef PREAMBLE_ARG_X
275 #undef PREAMBLE_ARG_Y
276
277 #undef TILEX_LOW_BITS
278 #undef TILEY_LOW_BITS
279