1 /*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkMath.h"
9 #include "SkMathPriv.h"
10
11 #define SCALE_FILTER_NAME MAKENAME(_filter_scale)
12 #define AFFINE_FILTER_NAME MAKENAME(_filter_affine)
13 #define PERSP_FILTER_NAME MAKENAME(_filter_persp)
14
15 #define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x)
16 #define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y)
17
18 #ifndef PREAMBLE
19 #define PREAMBLE(state)
20 #define PREAMBLE_PARAM_X
21 #define PREAMBLE_PARAM_Y
22 #define PREAMBLE_ARG_X
23 #define PREAMBLE_ARG_Y
24 #endif
25
26 // declare functions externally to suppress warnings.
27 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
28 uint32_t xy[], int count, int x, int y);
29 void AFFINE_FILTER_NAME(const SkBitmapProcState& s,
30 uint32_t xy[], int count, int x, int y);
31 void PERSP_FILTER_NAME(const SkBitmapProcState& s,
32 uint32_t* SK_RESTRICT xy, int count,
33 int x, int y);
34
PACK_FILTER_Y_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_Y)35 static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max,
36 SkFixed one PREAMBLE_PARAM_Y) {
37 unsigned i = TILEY_PROCF(f, max);
38 i = (i << 4) | EXTRACT_LOW_BITS(f, max);
39 return (i << 14) | (TILEY_PROCF((f + one), max));
40 }
41
PACK_FILTER_X_NAME(SkFixed f,unsigned max,SkFixed one PREAMBLE_PARAM_X)42 static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max,
43 SkFixed one PREAMBLE_PARAM_X) {
44 unsigned i = TILEX_PROCF(f, max);
45 i = (i << 4) | EXTRACT_LOW_BITS(f, max);
46 return (i << 14) | (TILEX_PROCF((f + one), max));
47 }
48
SCALE_FILTER_NAME(const SkBitmapProcState & s,uint32_t xy[],int count,int x,int y)49 void SCALE_FILTER_NAME(const SkBitmapProcState& s,
50 uint32_t xy[], int count, int x, int y) {
51 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask |
52 SkMatrix::kScale_Mask)) == 0);
53 SkASSERT(s.fInvKy == 0);
54
55 PREAMBLE(s);
56
57 const unsigned maxX = s.fPixmap.width() - 1;
58 const SkFixed one = s.fFilterOneX;
59 const SkFractionalInt dx = s.fInvSxFractionalInt;
60 SkFractionalInt fx;
61
62 {
63 const SkBitmapProcStateAutoMapper mapper(s, x, y);
64 const SkFixed fy = mapper.fixedY();
65 const unsigned maxY = s.fPixmap.height() - 1;
66 // compute our two Y values up front
67 *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y);
68 // now initialize fx
69 fx = mapper.fractionalIntX();
70 }
71
72 #ifdef CHECK_FOR_DECAL
73 const SkFixed fixedFx = SkFractionalIntToFixed(fx);
74 const SkFixed fixedDx = SkFractionalIntToFixed(dx);
75 if (can_truncate_to_fixed_for_decal(fixedFx, fixedDx, count, maxX)) {
76 decal_filter_scale(xy, fixedFx, fixedDx, 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 EXTRACT_LOW_BITS
160