initial.commit | ae2c20f | 2008-07-27 00:09:42 | [diff] [blame] | 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 = (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" |
| 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 | |