• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1Index: 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
26Index: 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());
59Index: 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
150Index: 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
285