• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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