blob: 78118416b47fde433059c067ac1d3280d0365d7f [file] [log] [blame]
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];
}