From 34150b451da7d3c70a2d34e67b0285cb36932d45 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 16 Oct 2013 18:59:44 +0000 Subject: [PATCH] Clear out SK_SCALAR_IS_FLOAT from SkRadialGradient, and merge the logic for radial_mirror and radial_repeat. New radial/repeated bench is 10-20x faster now using float instead of fixed; the rest are unaffected. BUG= R=reed@google.com Author: mtklein@google.com Review URL: https://codereview.chromium.org/26410003 git-svn-id: http://skia.googlecode.com/svn/trunk@11824 2bbb7eff-a529-9590-31e7-b0007b416f81 --- bench/GradientBench.cpp | 1 + src/effects/gradients/SkRadialGradient.cpp | 118 +++++++++++------------------ 2 files changed, 47 insertions(+), 72 deletions(-) diff --git a/bench/GradientBench.cpp b/bench/GradientBench.cpp index e04a812..63fa8ae 100644 --- a/bench/GradientBench.cpp +++ b/bench/GradientBench.cpp @@ -245,6 +245,7 @@ DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kC DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kClamp_TileMode, kOval_GeomType); ) DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kMirror_TileMode); ) +DEF_BENCH( return new GradientBench(kRadial_GradType, gGradData[0], SkShader::kRepeat_TileMode); ) DEF_BENCH( return new GradientBench(kSweep_GradType); ) DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); ) DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); ) diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp index 8bac12a..9d60cf7 100644 --- a/src/effects/gradients/SkRadialGradient.cpp +++ b/src/effects/gradients/SkRadialGradient.cpp @@ -46,6 +46,15 @@ void SkRadialGradient_BuildTable() { namespace { +// GCC doesn't like using static functions as template arguments. So force these to be non-static. +inline SkFixed mirror_tileproc_nonstatic(SkFixed x) { + return mirror_tileproc(x); +} + +inline SkFixed repeat_tileproc_nonstatic(SkFixed x) { + return repeat_tileproc(x); +} + void rad_to_unit_matrix(const SkPoint& center, SkScalar radius, SkMatrix* matrix) { SkScalar inv = SkScalarInvert(radius); @@ -105,51 +114,35 @@ void shadeSpan16_radial_clamp(SkScalar sfx, SkScalar sdx, } } -void shadeSpan16_radial_mirror(SkScalar sfx, SkScalar sdx, - SkScalar sfy, SkScalar sdy, - uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, - int toggle, int count) { +template +void shadeSpan16_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, + uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, + int toggle, int count) { do { -#ifdef SK_SCALAR_IS_FLOAT - float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy); - SkFixed dist = SkFloatToFixed(fdist); -#else - SkFixed magnitudeSquared = SkFixedSquare(sfx) + - SkFixedSquare(sfy); - if (magnitudeSquared < 0) // Overflow. - magnitudeSquared = SK_FixedMax; - SkFixed dist = SkFixedSqrt(magnitudeSquared); -#endif - unsigned fi = mirror_tileproc(dist); + const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy)); + const unsigned fi = TileProc(dist); SkASSERT(fi <= 0xFFFF); *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)]; toggle = next_dither_toggle16(toggle); - sfx += sdx; - sfy += sdy; - } while (--count != 0); -} - -void shadeSpan16_radial_repeat(SkScalar sfx, SkScalar sdx, - SkScalar sfy, SkScalar sdy, - uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, - int toggle, int count) { - SkFixed fx = SkScalarToFixed(sfx); - SkFixed dx = SkScalarToFixed(sdx); - SkFixed fy = SkScalarToFixed(sfy); - SkFixed dy = SkScalarToFixed(sdy); - do { - SkFixed dist = SkFixedSqrt(SkFixedSquare(fx) + SkFixedSquare(fy)); - unsigned fi = repeat_tileproc(dist); - SkASSERT(fi <= 0xFFFF); fx += dx; fy += dy; - *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)]; - toggle = next_dither_toggle16(toggle); } while (--count != 0); } +void shadeSpan16_radial_mirror(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, + uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, + int toggle, int count) { + shadeSpan16_radial(fx, dx, fy, dy, dstC, cache, toggle, count); +} + +void shadeSpan16_radial_repeat(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, + uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache, + int toggle, int count) { + shadeSpan16_radial(fx, dx, fy, dy, dstC, cache, toggle, count); } +} // namespace + ///////////////////////////////////////////////////////////////////// SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, @@ -367,45 +360,13 @@ void shadeSpan_radial_clamp(SkScalar sfx, SkScalar sdx, // Unrolling this loop doesn't seem to help (when float); we're stalling to // get the results of the sqrt (?), and don't have enough extra registers to // have many in flight. -void shadeSpan_radial_mirror(SkScalar sfx, SkScalar sdx, - SkScalar sfy, SkScalar sdy, - SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, - int count, int toggle) { - do { -#ifdef SK_SCALAR_IS_FLOAT - float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy); - SkFixed dist = SkFloatToFixed(fdist); -#else - SkFixed magnitudeSquared = SkFixedSquare(sfx) + - SkFixedSquare(sfy); - if (magnitudeSquared < 0) // Overflow. - magnitudeSquared = SK_FixedMax; - SkFixed dist = SkFixedSqrt(magnitudeSquared); -#endif - unsigned fi = mirror_tileproc(dist); - SkASSERT(fi <= 0xFFFF); - *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)]; - toggle = next_dither_toggle(toggle); - sfx += sdx; - sfy += sdy; - } while (--count != 0); -} - -void shadeSpan_radial_repeat(SkScalar sfx, SkScalar sdx, - SkScalar sfy, SkScalar sdy, - SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, - int count, int toggle) { - SkFixed fx = SkScalarToFixed(sfx); - SkFixed dx = SkScalarToFixed(sdx); - SkFixed fy = SkScalarToFixed(sfy); - SkFixed dy = SkScalarToFixed(sdy); +template +void shadeSpan_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count, int toggle) { do { - SkFixed magnitudeSquared = SkFixedSquare(fx) + - SkFixedSquare(fy); - if (magnitudeSquared < 0) // Overflow. - magnitudeSquared = SK_FixedMax; - SkFixed dist = SkFixedSqrt(magnitudeSquared); - unsigned fi = repeat_tileproc(dist); + const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy)); + const unsigned fi = TileProc(dist); SkASSERT(fi <= 0xFFFF); *dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)]; toggle = next_dither_toggle(toggle); @@ -413,8 +374,21 @@ void shadeSpan_radial_repeat(SkScalar sfx, SkScalar sdx, fy += dy; } while (--count != 0); } + +void shadeSpan_radial_mirror(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count, int toggle) { + shadeSpan_radial(fx, dx, fy, dy, dstC, cache, count, toggle); } +void shadeSpan_radial_repeat(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy, + SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, + int count, int toggle) { + shadeSpan_radial(fx, dx, fy, dy, dstC, cache, count, toggle); +} + +} // namespace + void SkRadialGradient::shadeSpan(int x, int y, SkPMColor* SK_RESTRICT dstC, int count) { SkASSERT(count > 0); -- 2.7.4