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
This commit is contained in:
parent
cbbf1ca304
commit
34150b451d
@ -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::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::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); )
|
||||||
DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); )
|
DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[1]); )
|
||||||
DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); )
|
DEF_BENCH( return new GradientBench(kSweep_GradType, gGradData[2]); )
|
||||||
|
@ -46,6 +46,15 @@ void SkRadialGradient_BuildTable() {
|
|||||||
|
|
||||||
namespace {
|
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,
|
void rad_to_unit_matrix(const SkPoint& center, SkScalar radius,
|
||||||
SkMatrix* matrix) {
|
SkMatrix* matrix) {
|
||||||
SkScalar inv = SkScalarInvert(radius);
|
SkScalar inv = SkScalarInvert(radius);
|
||||||
@ -105,51 +114,35 @@ void shadeSpan16_radial_clamp(SkScalar sfx, SkScalar sdx,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shadeSpan16_radial_mirror(SkScalar sfx, SkScalar sdx,
|
template <SkFixed (*TileProc)(SkFixed)>
|
||||||
SkScalar sfy, SkScalar sdy,
|
void shadeSpan16_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy,
|
||||||
uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache,
|
uint16_t* SK_RESTRICT dstC, const uint16_t* SK_RESTRICT cache,
|
||||||
int toggle, int count) {
|
int toggle, int count) {
|
||||||
do {
|
do {
|
||||||
#ifdef SK_SCALAR_IS_FLOAT
|
const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy));
|
||||||
float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy);
|
const unsigned fi = TileProc(dist);
|
||||||
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);
|
SkASSERT(fi <= 0xFFFF);
|
||||||
*dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)];
|
*dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)];
|
||||||
toggle = next_dither_toggle16(toggle);
|
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;
|
fx += dx;
|
||||||
fy += dy;
|
fy += dy;
|
||||||
*dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache16Shift)];
|
|
||||||
toggle = next_dither_toggle16(toggle);
|
|
||||||
} while (--count != 0);
|
} 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,
|
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
|
// 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
|
// get the results of the sqrt (?), and don't have enough extra registers to
|
||||||
// have many in flight.
|
// have many in flight.
|
||||||
void shadeSpan_radial_mirror(SkScalar sfx, SkScalar sdx,
|
template <SkFixed (*TileProc)(SkFixed)>
|
||||||
SkScalar sfy, SkScalar sdy,
|
void shadeSpan_radial(SkScalar fx, SkScalar dx, SkScalar fy, SkScalar dy,
|
||||||
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
|
SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache,
|
||||||
int count, int toggle) {
|
int count, int toggle) {
|
||||||
do {
|
do {
|
||||||
#ifdef SK_SCALAR_IS_FLOAT
|
const SkFixed dist = SkFloatToFixed(sk_float_sqrt(fx*fx + fy*fy));
|
||||||
float fdist = sk_float_sqrt(sfx*sfx + sfy*sfy);
|
const unsigned fi = TileProc(dist);
|
||||||
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);
|
|
||||||
do {
|
|
||||||
SkFixed magnitudeSquared = SkFixedSquare(fx) +
|
|
||||||
SkFixedSquare(fy);
|
|
||||||
if (magnitudeSquared < 0) // Overflow.
|
|
||||||
magnitudeSquared = SK_FixedMax;
|
|
||||||
SkFixed dist = SkFixedSqrt(magnitudeSquared);
|
|
||||||
unsigned fi = repeat_tileproc(dist);
|
|
||||||
SkASSERT(fi <= 0xFFFF);
|
SkASSERT(fi <= 0xFFFF);
|
||||||
*dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)];
|
*dstC++ = cache[toggle + (fi >> SkGradientShaderBase::kCache32Shift)];
|
||||||
toggle = next_dither_toggle(toggle);
|
toggle = next_dither_toggle(toggle);
|
||||||
@ -413,8 +374,21 @@ void shadeSpan_radial_repeat(SkScalar sfx, SkScalar sdx,
|
|||||||
fy += dy;
|
fy += dy;
|
||||||
} while (--count != 0);
|
} 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,
|
void SkRadialGradient::shadeSpan(int x, int y,
|
||||||
SkPMColor* SK_RESTRICT dstC, int count) {
|
SkPMColor* SK_RESTRICT dstC, int count) {
|
||||||
SkASSERT(count > 0);
|
SkASSERT(count > 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user