static inline void test_fast_interp(skiatest::Reporter* reporter) { SkRandom r; U8CPU a0 = 0; U8CPU a255 = 255; for (int i = 0; i < 200; i++) { SkColor colorSrc = r.nextU(); SkColor colorDst = r.nextU(); SkPMColor src = SkPreMultiplyColor(colorSrc); SkPMColor dst = SkPreMultiplyColor(colorDst); REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a0) == dst); REPORTER_ASSERT(reporter, SkFastFourByteInterp(src, dst, a255) == src); } }
// Linear interpolation (lerp) is unnecessary if there are no sharp // discontinuities in the gradient - which must be true if there are // only 2 colors - but it's cheap. void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, int toggle, int count) { // We're a vertical gradient, so no change in a span. // If colors change sharply across the gradient, dithering is // insufficient (it subsamples the color space) and we need to lerp. unsigned fullIndex = proc(fx); unsigned fi = fullIndex >> (16 - SkGradientShaderBase::kCache32Bits); unsigned remainder = fullIndex & SkGradientShaderBase::kLerpRemainderMask32; SkPMColor lerp = SkFastFourByteInterp( cache[toggle + fi + 1], cache[toggle + fi], remainder); SkPMColor dlerp = SkFastFourByteInterp( cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + fi + 1], cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + fi], remainder); sk_memset32_dither(dstC, lerp, dlerp, count); } void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, SkPMColor* SK_RESTRICT dstC, const SkPMColor* SK_RESTRICT cache, int toggle, int count) { SkClampRange range; range.init(fx, dx, count, 0, SkGradientShaderBase::kGradient32Length);