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::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]); )
|
||||
|
@ -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) {
|
||||
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 {
|
||||
#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);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user