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