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