Index: src/effects/gradients/SkRadialGradient.cpp |
diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp |
index 8bac12a6021e3eb6418f02d88bb139fe578c7ef8..9d60cf7634e125fd2e013ea8f67f0387941b5524 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. |
reed1
2013/10/16 15:24:05
that is some kind of crazy
|
+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 <SkFixed (*TileProc)(SkFixed)> |
+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<mirror_tileproc_nonstatic>(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<repeat_tileproc_nonstatic>(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 <SkFixed (*TileProc)(SkFixed)> |
+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<mirror_tileproc_nonstatic>(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<repeat_tileproc_nonstatic>(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); |