OLD | NEW |
| (Empty) |
1 Index: sgl/SkBitmapProcState.h | |
2 =================================================================== | |
3 --- sgl/SkBitmapProcState.h (revision 42716) | |
4 +++ sgl/SkBitmapProcState.h (working copy) | |
5 @@ -39,8 +39,9 @@ | |
6 int count, | |
7 uint16_t colors[]); | |
8 | |
9 - typedef U16CPU (*FixedTileProc)(SkFixed); // returns 0..0xFFFF | |
10 - | |
11 + typedef SkFixed (*FixedTileProc)(SkFixed, int); | |
12 + typedef int (*IntTileProc)(int, int); | |
13 + | |
14 MatrixProc fMatrixProc; // chooseProcs | |
15 SampleProc32 fSampleProc32; // chooseProcs | |
16 SampleProc16 fSampleProc16; // chooseProcs | |
17 @@ -48,6 +49,8 @@ | |
18 SkMatrix fUnitInvMatrix; // chooseProcs | |
19 FixedTileProc fTileProcX; // chooseProcs | |
20 FixedTileProc fTileProcY; // chooseProcs | |
21 + IntTileProc iTileProcX; // chooseProcs | |
22 + IntTileProc iTileProcY; // chooseProcs | |
23 SkFixed fFilterOneX; | |
24 SkFixed fFilterOneY; | |
25 | |
26 Index: sgl/SkBitmapProcState.cpp | |
27 =================================================================== | |
28 --- sgl/SkBitmapProcState.cpp (revision 42716) | |
29 +++ sgl/SkBitmapProcState.cpp (working copy) | |
30 @@ -296,8 +296,9 @@ | |
31 } | |
32 const SkMatrix* m; | |
33 | |
34 - if (SkShader::kClamp_TileMode == fTileModeX && | |
35 - SkShader::kClamp_TileMode == fTileModeY) { | |
36 + if (inv.getType() <= SkMatrix::kTranslate_Mask || | |
37 + (SkShader::kClamp_TileMode == fTileModeX && | |
38 + SkShader::kClamp_TileMode == fTileModeY)) { | |
39 m = &inv; | |
40 } else { | |
41 fUnitInvMatrix = inv; | |
42 @@ -330,6 +331,16 @@ | |
43 fInvMatrix = m; | |
44 fInvProc = m->getMapXYProc(); | |
45 fInvType = m->getType(); | |
46 + if (fInvType <= SkMatrix::kTranslate_Mask && | |
47 + inv.getType() > SkMatrix::kTranslate_Mask) { | |
48 + SkASSERT(inv.getType() <= | |
49 + (SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask)); | |
50 + // It is possible that by the calculation of fUnitInvMatrix, we have | |
51 + // eliminated the scale transformation of the matrix (e.g., if inv^(-1) | |
52 + // scales fOrigBitmap into an 1X1 rect). We add the scale flag back so | |
53 + // that we don't make wrong choice in chooseMatrixProc(). | |
54 + fInvType |= SkMatrix::kScale_Mask; | |
55 + } | |
56 fInvSx = SkScalarToFixed(m->getScaleX()); | |
57 fInvSy = SkScalarToFixed(m->getScaleY()); | |
58 fInvKy = SkScalarToFixed(m->getSkewY()); | |
59 Index: sgl/SkBitmapProcState_matrix.h | |
60 =================================================================== | |
61 --- sgl/SkBitmapProcState_matrix.h (revision 42716) | |
62 +++ sgl/SkBitmapProcState_matrix.h (working copy) | |
63 @@ -1,4 +1,5 @@ | |
64 | |
65 +#define TRANSLATE_NOFILTER_NAME MAKENAME(_nofilter_translate) | |
66 #define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale) | |
67 #define SCALE_FILTER_NAME MAKENAME(_filter_scale) | |
68 #define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine) | |
69 @@ -17,6 +18,38 @@ | |
70 #define PREAMBLE_ARG_Y | |
71 #endif | |
72 | |
73 +#ifndef PREAMBLE_TRANS | |
74 + #define PREAMBLE_TRANS(state) | |
75 +#endif | |
76 + | |
77 +static void TRANSLATE_NOFILTER_NAME(const SkBitmapProcState& s, | |
78 + uint32_t xy[], int count, int x, int y) | |
79 +{ | |
80 + SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0); | |
81 + | |
82 + PREAMBLE_TRANS(s); | |
83 + | |
84 + x += SkScalarFloor(s.fInvMatrix->getTranslateX()); | |
85 + y += SkScalarFloor(s.fInvMatrix->getTranslateY()); | |
86 + | |
87 + *xy++ = (uint32_t)TILEY_TRANS(y, (s.fBitmap->height() - 1)); | |
88 + | |
89 + int maxX = s.fBitmap->width() - 1; | |
90 + int i; | |
91 + uint16_t* xx = (uint16_t*)xy; | |
92 + for (i = (count >> 2); i > 0; --i) | |
93 + { | |
94 + *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++; | |
95 + *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++; | |
96 + *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++; | |
97 + *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++; | |
98 + } | |
99 + for (i = (count & 3); i > 0; --i) | |
100 + { | |
101 + *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++; | |
102 + } | |
103 +} | |
104 + | |
105 static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, | |
106 uint32_t xy[], int count, int x, int y) { | |
107 SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | | |
108 @@ -206,9 +239,9 @@ | |
109 unsigned maxY = s.fBitmap->height() - 1; | |
110 | |
111 do { | |
112 - *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneX PREAMBLE_ARG_Y); | |
113 + *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); | |
114 fy += dy; | |
115 - *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneY PREAMBLE_ARG_X); | |
116 + *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); | |
117 fx += dx; | |
118 } while (--count != 0); | |
119 } | |
120 @@ -241,6 +274,9 @@ | |
121 } | |
122 | |
123 static SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = { | |
124 + TRANSLATE_NOFILTER_NAME, | |
125 + TRANSLATE_NOFILTER_NAME, // No need to do filtering if the matrix is no | |
126 + // more complex than identity/translate. | |
127 SCALE_NOFILTER_NAME, | |
128 SCALE_FILTER_NAME, | |
129 AFFINE_NOFILTER_NAME, | |
130 @@ -255,7 +291,10 @@ | |
131 #ifdef CHECK_FOR_DECAL | |
132 #undef CHECK_FOR_DECAL | |
133 #endif | |
134 - | |
135 +#undef TILEX_TRANS | |
136 +#undef TILEY_TRANS | |
137 + | |
138 +#undef TRANSLATE_NOFILTER_NAME | |
139 #undef SCALE_NOFILTER_NAME | |
140 #undef SCALE_FILTER_NAME | |
141 #undef AFFINE_NOFILTER_NAME | |
142 @@ -268,6 +307,7 @@ | |
143 #undef PREAMBLE_PARAM_Y | |
144 #undef PREAMBLE_ARG_X | |
145 #undef PREAMBLE_ARG_Y | |
146 +#undef PREAMBLE_TRANS | |
147 | |
148 #undef TILEX_LOW_BITS | |
149 #undef TILEY_LOW_BITS | |
150 Index: sgl/SkBitmapProcState_matrixProcs.cpp | |
151 =================================================================== | |
152 --- sgl/SkBitmapProcState_matrixProcs.cpp (revision 42716) | |
153 +++ sgl/SkBitmapProcState_matrixProcs.cpp (working copy) | |
154 @@ -28,6 +28,8 @@ | |
155 #define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) | |
156 #define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) | |
157 #define CHECK_FOR_DECAL | |
158 +#define TILEX_TRANS(x, max) SkClampMax(x, max) | |
159 +#define TILEY_TRANS(y, max) SkClampMax(y, max) | |
160 #include "SkBitmapProcState_matrix.h" | |
161 | |
162 #define MAKENAME(suffix) RepeatX_RepeatY ## suffix | |
163 @@ -35,6 +37,9 @@ | |
164 #define TILEY_PROCF(fy, max) (((fy) & 0xFFFF) * ((max) + 1) >> 16) | |
165 #define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) | |
166 #define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) | |
167 +#define REAL_MOD(val, modulus) (((val)%(modulus)) + (modulus)*( (val)<0 )) | |
168 +#define TILEX_TRANS(x, max) (REAL_MOD((x), ((max) + 1))) | |
169 +#define TILEY_TRANS(y, max) (REAL_MOD((y), ((max) + 1))) | |
170 #include "SkBitmapProcState_matrix.h" | |
171 | |
172 #define MAKENAME(suffix) GeneralXY ## suffix | |
173 @@ -44,13 +49,17 @@ | |
174 #define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY | |
175 #define PREAMBLE_ARG_X , tileProcX | |
176 #define PREAMBLE_ARG_Y , tileProcY | |
177 -#define TILEX_PROCF(fx, max) (tileProcX(fx) * ((max) + 1) >> 16) | |
178 -#define TILEY_PROCF(fy, max) (tileProcY(fy) * ((max) + 1) >> 16) | |
179 -#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx) * ((max) + 1) >> 12) & 0xF) | |
180 -#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy) * ((max) + 1) >> 12) & 0xF) | |
181 +#define TILEX_PROCF(fx, max) (tileProcX(fx, max) >> 16) | |
182 +#define TILEY_PROCF(fy, max) (tileProcY(fy, max) >> 16) | |
183 +#define TILEX_LOW_BITS(fx, max) ((tileProcX(fx, max) >> 14) & 0x3) | |
184 +#define TILEY_LOW_BITS(fy, max) ((tileProcY(fy, max) >> 14) & 0x3) | |
185 +#define PREAMBLE_TRANS(state) SkBitmapProcState::IntTileProc tileProcX = (sta
te).iTileProcX; \ | |
186 + SkBitmapProcState::IntTileProc tileProcY = (sta
te).iTileProcY | |
187 +#define TILEX_TRANS(x, max) tileProcX(x, max) | |
188 +#define TILEY_TRANS(y, max) tileProcY(y, max) | |
189 #include "SkBitmapProcState_matrix.h" | |
190 | |
191 -static inline U16CPU fixed_clamp(SkFixed x) | |
192 +static inline SkFixed fixed_clamp(SkFixed x, int max) | |
193 { | |
194 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR | |
195 if (x >> 16) | |
196 @@ -66,19 +75,20 @@ | |
197 x = 0xFFFF; | |
198 } | |
199 #endif | |
200 - return x; | |
201 + return x * (max + 1); | |
202 } | |
203 | |
204 -static inline U16CPU fixed_repeat(SkFixed x) | |
205 +static inline SkFixed fixed_repeat(SkFixed x, int max) | |
206 { | |
207 - return x & 0xFFFF; | |
208 + return (x & 0xFFFF) * (max + 1); | |
209 } | |
210 | |
211 -static inline U16CPU fixed_mirror(SkFixed x) | |
212 +static inline SkFixed fixed_mirror(SkFixed x, int max) | |
213 { | |
214 SkFixed s = x << 15 >> 31; | |
215 // s is FFFFFFFF if we're on an odd interval, or 0 if an even interval | |
216 - return (x ^ s) & 0xFFFF; | |
217 + x = ((x ^ s) & 0xFFFF) * (max + 1); | |
218 + return s ? (x ^ 0xFFFF) : x; | |
219 } | |
220 | |
221 static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m) | |
222 @@ -90,15 +100,52 @@ | |
223 SkASSERT(SkShader::kMirror_TileMode == m); | |
224 return fixed_mirror; | |
225 } | |
226 + | |
227 +static inline int int_clamp(int x, int max) | |
228 +{ | |
229 + SkASSERT(max >= 0); | |
230 + | |
231 + return SkClampMax(x, max); | |
232 +} | |
233 | |
234 +static inline int int_repeat(int x, int max) | |
235 +{ | |
236 + SkASSERT(max >= 0); | |
237 + | |
238 + return x % (max + 1); | |
239 +} | |
240 + | |
241 +static inline int int_mirror(int x, int max) | |
242 +{ | |
243 + SkASSERT(max >= 0); | |
244 + | |
245 + int dx = x % (max + 1); | |
246 + if (dx < 0) | |
247 + dx = -dx - 1; | |
248 + | |
249 + return (x / (max + 1) % 2) ? max - dx : dx; | |
250 +} | |
251 + | |
252 +static SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned m) | |
253 +{ | |
254 + if (SkShader::kClamp_TileMode == m) | |
255 + return int_clamp; | |
256 + if (SkShader::kRepeat_TileMode == m) | |
257 + return int_repeat; | |
258 + SkASSERT(SkShader::kMirror_TileMode == m); | |
259 + return int_mirror; | |
260 +} | |
261 + | |
262 SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc() | |
263 { | |
264 int index = 0; | |
265 if (fDoFilter) | |
266 index = 1; | |
267 if (fInvType & SkMatrix::kPerspective_Mask) | |
268 + index |= 6; | |
269 + else if (fInvType & SkMatrix::kAffine_Mask) | |
270 index |= 4; | |
271 - else if (fInvType & SkMatrix::kAffine_Mask) | |
272 + else if (fInvType & SkMatrix::kScale_Mask) | |
273 index |= 2; | |
274 | |
275 if (SkShader::kClamp_TileMode == fTileModeX && | |
276 @@ -123,6 +170,8 @@ | |
277 // only general needs these procs | |
278 fTileProcX = choose_tile_proc(fTileModeX); | |
279 fTileProcY = choose_tile_proc(fTileModeY); | |
280 + iTileProcX = choose_int_tile_proc(fTileModeX); | |
281 + iTileProcY = choose_int_tile_proc(fTileModeY); | |
282 return GeneralXY_Procs[index]; | |
283 } | |
284 | |
OLD | NEW |