diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-09-21 13:38:36 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-09-21 13:38:36 +0000 |
commit | 51baf5abe796b75a7295389b05821f47ea1340ab (patch) | |
tree | 664626d19a40bd621b038f360465c6b3e2f4f2fd /src/effects/SkGradientShader.cpp | |
parent | b3b0a5b128885cc82d07be98c8c57614b9eea3dd (diff) |
speed up radial-mirror 16x, sweep by ~2x
git-svn-id: http://skia.googlecode.com/svn/trunk@2294 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/effects/SkGradientShader.cpp')
-rw-r--r-- | src/effects/SkGradientShader.cpp | 80 |
1 files changed, 61 insertions, 19 deletions
diff --git a/src/effects/SkGradientShader.cpp b/src/effects/SkGradientShader.cpp index 36177b1b32..d629c57a1e 100644 --- a/src/effects/SkGradientShader.cpp +++ b/src/effects/SkGradientShader.cpp @@ -15,6 +15,10 @@ #include "SkTemplates.h" #include "SkBitmapCache.h" +#if defined(SK_SCALAR_IS_FLOAT) && !defined(SK_DONT_USE_FLOAT_SQRT) + #define SK_USE_FLOAT_SQRT +#endif + #ifndef SK_DISABLE_DITHER_32BIT_GRADIENT #define USE_DITHER_32BIT_GRADIENT #endif @@ -1160,16 +1164,27 @@ public: SkIntToScalar(y) + SK_ScalarHalf, &srcPt); SkFixed dx, fx = SkScalarToFixed(srcPt.fX); SkFixed dy, fy = SkScalarToFixed(srcPt.fY); +#ifdef SK_USE_FLOAT_SQRT + float fdx, fdy; +#endif if (fDstToIndexClass == kFixedStepInX_MatrixClass) { SkFixed storage[2]; (void)fDstToIndex.fixedStepInX(SkIntToScalar(y), &storage[0], &storage[1]); dx = storage[0]; dy = storage[1]; +#ifdef SK_USE_FLOAT_SQRT + fdx = SkFixedToFloat(storage[0]); + fdy = SkFixedToFloat(storage[1]); +#endif } else { SkASSERT(fDstToIndexClass == kLinear_MatrixClass); dx = SkScalarToFixed(fDstToIndex.getScaleX()); dy = SkScalarToFixed(fDstToIndex.getSkewY()); +#ifdef SK_USE_FLOAT_SQRT + fdx = fDstToIndex.getScaleX(); + fdy = fDstToIndex.getSkewY(); +#endif } if (proc == clamp_tileproc) { @@ -1188,6 +1203,18 @@ public: fy += dy; } while (--count != 0); } else if (proc == mirror_tileproc) { +#ifdef SK_USE_FLOAT_SQRT + float ffx = srcPt.fX; + float ffy = srcPt.fY; + do { + float fdist = sk_float_sqrt(ffx*ffx + ffy*ffy); + unsigned fi = mirror_tileproc(SkFloatToFixed(fdist)); + SkASSERT(fi <= 0xFFFF); + *dstC++ = cache[fi >> (16 - kCache32Bits)]; + ffx += fdx; + ffy += fdy; + } while (--count != 0); +#else do { SkFixed magnitudeSquared = SkFixedSquare(fx) + SkFixedSquare(fy); if (magnitudeSquared < 0) // Overflow. @@ -1199,6 +1226,7 @@ public: fx += dx; fy += dy; } while (--count != 0); +#endif } else { SkASSERT(proc == repeat_tileproc); do { @@ -1907,6 +1935,23 @@ static unsigned atan_0_90(SkFixed y, SkFixed x) { } // returns angle in a circle [0..2PI) -> [0..255] +#ifdef SK_SCALAR_IS_FLOAT +static unsigned SkATan2_255(float y, float x) { + // static const float g255Over2PI = 255 / (2 * SK_ScalarPI); + static const float g255Over2PI = 40.584510488433314f; + + float result = sk_float_atan2(y, x); + if (result < 0) { + result += 2 * SK_ScalarPI; + } + SkASSERT(result >= 0); + // since our value is always >= 0, we can cast to int, which is faster than + // calling floorf() + int ir = (int)(result * g255Over2PI); + SkASSERT(ir >= 0 && ir <= 255); + return ir; +} +#else static unsigned SkATan2_255(SkFixed y, SkFixed x) { if (x == 0) { if (y == 0) { @@ -1961,6 +2006,7 @@ static unsigned SkATan2_255(SkFixed y, SkFixed x) { SkASSERT(result < 256); return result; } +#endif void Sweep_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) { SkMatrix::MapXYProc proc = fDstToIndexProc; @@ -1971,19 +2017,19 @@ void Sweep_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int co if (fDstToIndexClass != kPerspective_MatrixClass) { proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - SkFixed dx, fx = SkScalarToFixed(srcPt.fX); - SkFixed dy, fy = SkScalarToFixed(srcPt.fY); + SkScalar dx, fx = srcPt.fX; + SkScalar dy, fy = srcPt.fY; if (fDstToIndexClass == kFixedStepInX_MatrixClass) { SkFixed storage[2]; (void)matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf, &storage[0], &storage[1]); - dx = storage[0]; - dy = storage[1]; + dx = SkFixedToScalar(storage[0]); + dy = SkFixedToScalar(storage[1]); } else { SkASSERT(fDstToIndexClass == kLinear_MatrixClass); - dx = SkScalarToFixed(matrix.getScaleX()); - dy = SkScalarToFixed(matrix.getSkewY()); + dx = matrix.getScaleX(); + dy = matrix.getSkewY(); } for (; count > 0; --count) { @@ -1994,11 +2040,8 @@ void Sweep_Gradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int co } else { // perspective case for (int stop = x + count; x < stop; x++) { proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - - int index = SkATan2_255(SkScalarToFixed(srcPt.fY), - SkScalarToFixed(srcPt.fX)); - *dstC++ = cache[index]; + SkIntToScalar(y) + SK_ScalarHalf, &srcPt); + *dstC++ = cache[SkATan2_255(srcPt.fY, srcPt.fX)]; } } } @@ -2013,19 +2056,19 @@ void Sweep_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int c if (fDstToIndexClass != kPerspective_MatrixClass) { proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - SkFixed dx, fx = SkScalarToFixed(srcPt.fX); - SkFixed dy, fy = SkScalarToFixed(srcPt.fY); + SkScalar dx, fx = srcPt.fX; + SkScalar dy, fy = srcPt.fY; if (fDstToIndexClass == kFixedStepInX_MatrixClass) { SkFixed storage[2]; (void)matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf, &storage[0], &storage[1]); - dx = storage[0]; - dy = storage[1]; + dx = SkFixedToScalar(storage[0]); + dy = SkFixedToScalar(storage[1]); } else { SkASSERT(fDstToIndexClass == kLinear_MatrixClass); - dx = SkScalarToFixed(matrix.getScaleX()); - dy = SkScalarToFixed(matrix.getSkewY()); + dx = matrix.getScaleX(); + dy = matrix.getSkewY(); } for (; count > 0; --count) { @@ -2040,8 +2083,7 @@ void Sweep_Gradient::shadeSpan16(int x, int y, uint16_t* SK_RESTRICT dstC, int c proc(matrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - int index = SkATan2_255(SkScalarToFixed(srcPt.fY), - SkScalarToFixed(srcPt.fX)); + int index = SkATan2_255(srcPt.fY, srcPt.fX); index >>= (8 - kCache16Bits); *dstC++ = cache[toggle + index]; toggle ^= (1 << kCache16Bits); |