aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/GradientBench.cpp1
-rw-r--r--src/effects/gradients/SkRadialGradient.cpp118
2 files changed, 47 insertions, 72 deletions
diff --git a/bench/GradientBench.cpp b/bench/GradientBench.cpp
index e04a8122d1..63fa8ae4c3 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 8bac12a602..9d60cf7634 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 <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);