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