1 Index: sgl/SkBitmapProcState.h
2 ===================================================================
3 --- sgl/SkBitmapProcState.h (revision 42716)
4 +++ sgl/SkBitmapProcState.h (working copy)
9 - typedef U16CPU (*FixedTileProc)(SkFixed); // returns 0..0xFFFF
11 + typedef SkFixed (*FixedTileProc)(SkFixed, int);
12 + typedef int (*IntTileProc)(int, int);
14 MatrixProc fMatrixProc; // chooseProcs
15 SampleProc32 fSampleProc32; // chooseProcs
16 SampleProc16 fSampleProc16; // chooseProcs
18 SkMatrix fUnitInvMatrix; // chooseProcs
19 FixedTileProc fTileProcX; // chooseProcs
20 FixedTileProc fTileProcY; // chooseProcs
21 + IntTileProc iTileProcX; // chooseProcs
22 + IntTileProc iTileProcY; // chooseProcs
26 Index: sgl/SkBitmapProcState.cpp
27 ===================================================================
28 --- sgl/SkBitmapProcState.cpp (revision 42716)
29 +++ sgl/SkBitmapProcState.cpp (working copy)
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)) {
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;
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)
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)
70 #define PREAMBLE_ARG_Y
73 +#ifndef PREAMBLE_TRANS
74 + #define PREAMBLE_TRANS(state)
77 +static void TRANSLATE_NOFILTER_NAME(const SkBitmapProcState& s,
78 + uint32_t xy[], int count, int x, int y)
80 + SkASSERT((s.fInvType & ~SkMatrix::kTranslate_Mask) == 0);
84 + x += SkScalarFloor(s.fInvMatrix->getTranslateX());
85 + y += SkScalarFloor(s.fInvMatrix->getTranslateY());
87 + *xy++ = (uint32_t)TILEY_TRANS(y, (s.fBitmap->height() - 1));
89 + int maxX = s.fBitmap->width() - 1;
91 + uint16_t* xx = (uint16_t*)xy;
92 + for (i = (count >> 2); i > 0; --i)
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++;
99 + for (i = (count & 3); i > 0; --i)
101 + *xx++ = (uint16_t)TILEX_TRANS(x, maxX); x++;
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 |
109 unsigned maxY = s.fBitmap->height() - 1;
112 - *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneX PREAMBLE_ARG_Y);
113 + *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y);
115 - *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneY PREAMBLE_ARG_X);
116 + *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X);
118 } while (--count != 0);
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.
129 AFFINE_NOFILTER_NAME,
131 #ifdef CHECK_FOR_DECAL
132 #undef CHECK_FOR_DECAL
138 +#undef TRANSLATE_NOFILTER_NAME
139 #undef SCALE_NOFILTER_NAME
140 #undef SCALE_FILTER_NAME
141 #undef AFFINE_NOFILTER_NAME
143 #undef PREAMBLE_PARAM_Y
144 #undef PREAMBLE_ARG_X
145 #undef PREAMBLE_ARG_Y
146 +#undef PREAMBLE_TRANS
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)
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"
162 #define MAKENAME(suffix) RepeatX_RepeatY ## suffix
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"
172 #define MAKENAME(suffix) GeneralXY ## suffix
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 = (state).iTileProcX; \
186 + SkBitmapProcState::IntTileProc tileProcY = (state).iTileProcY
187 +#define TILEX_TRANS(x, max) tileProcX(x, max)
188 +#define TILEY_TRANS(y, max) tileProcY(y, max)
189 #include "SkBitmapProcState_matrix.h"
191 -static inline U16CPU fixed_clamp(SkFixed x)
192 +static inline SkFixed fixed_clamp(SkFixed x, int max)
194 #ifdef SK_CPU_HAS_CONDITIONAL_INSTR
201 + return x * (max + 1);
204 -static inline U16CPU fixed_repeat(SkFixed x)
205 +static inline SkFixed fixed_repeat(SkFixed x, int max)
208 + return (x & 0xFFFF) * (max + 1);
211 -static inline U16CPU fixed_mirror(SkFixed x)
212 +static inline SkFixed fixed_mirror(SkFixed x, int max)
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;
221 static SkBitmapProcState::FixedTileProc choose_tile_proc(unsigned m)
223 SkASSERT(SkShader::kMirror_TileMode == m);
227 +static inline int int_clamp(int x, int max)
229 + SkASSERT(max >= 0);
231 + return SkClampMax(x, max);
234 +static inline int int_repeat(int x, int max)
236 + SkASSERT(max >= 0);
238 + return x % (max + 1);
241 +static inline int int_mirror(int x, int max)
243 + SkASSERT(max >= 0);
245 + int dx = x % (max + 1);
249 + return (x / (max + 1) % 2) ? max - dx : dx;
252 +static SkBitmapProcState::IntTileProc choose_int_tile_proc(unsigned m)
254 + if (SkShader::kClamp_TileMode == m)
256 + if (SkShader::kRepeat_TileMode == m)
258 + SkASSERT(SkShader::kMirror_TileMode == m);
262 SkBitmapProcState::MatrixProc SkBitmapProcState::chooseMatrixProc()
267 if (fInvType & SkMatrix::kPerspective_Mask)
269 + else if (fInvType & SkMatrix::kAffine_Mask)
271 - else if (fInvType & SkMatrix::kAffine_Mask)
272 + else if (fInvType & SkMatrix::kScale_Mask)
275 if (SkShader::kClamp_TileMode == fTileModeX &&
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];