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