void SkLinearGradient:: LinearGradient4fContext::mapTs(int x, int y, SkScalar ts[], int count) const { SkASSERT(count > 0); SkASSERT(fDstToPosClass != kLinear_MatrixClass); SkScalar sx = x + SK_ScalarHalf; const SkScalar sy = y + SK_ScalarHalf; SkPoint pt; if (fDstToPosClass != kPerspective_MatrixClass) { // kLinear_MatrixClass, kFixedStepInX_MatrixClass => fixed dt per scanline const SkScalar dtdx = fDstToPos.fixedStepInX(sy).x(); fDstToPosProc(fDstToPos, sx, sy, &pt); const Sk4f dtdx4 = Sk4f(4 * dtdx); Sk4f t4 = Sk4f(pt.x() + 0 * dtdx, pt.x() + 1 * dtdx, pt.x() + 2 * dtdx, pt.x() + 3 * dtdx); while (count >= 4) { t4.store(ts); t4 = t4 + dtdx4; ts += 4; count -= 4; } if (count & 2) { *ts++ = t4[0]; *ts++ = t4[1]; t4 = SkNx_shuffle<2, 0, 1, 3>(t4); } if (count & 1) { *ts++ = t4[0]; } } else { for (int i = 0; i < count; ++i) { fDstToPosProc(fDstToPos, sx, sy, &pt); ts[i] = pt.x(); sx += SK_Scalar1; } } }
void SkLinearGradient:: LinearGradient4fContext::shadeSpanInternal(int x, int y, dstType dst[], int count, float bias0, float bias1) const { SkPoint pt; fDstToPosProc(fDstToPos, x + SK_ScalarHalf, y + SK_ScalarHalf, &pt); const SkScalar fx = pinFx<tileMode>(pt.x()); const SkScalar dx = fDstToPos.getScaleX(); LinearIntervalProcessor<dstType, premul, tileMode> proc(fIntervals->begin(), fIntervals->end() - 1, this->findInterval(fx), fx, dx, SkScalarNearlyZero(dx * count)); Sk4f bias4f0(bias0), bias4f1(bias1); while (count > 0) { // What we really want here is SkTPin(advance, 1, count) // but that's a significant perf hit for >> stops; investigate. const int n = SkScalarTruncToInt( SkTMin<SkScalar>(proc.currentAdvance() + 1, SkIntToScalar(count))); // The current interval advance can be +inf (e.g. when reaching // the clamp mode end intervals) - when that happens, we expect to // a) consume all remaining count in one swoop // b) return a zero color gradient SkASSERT(SkScalarIsFinite(proc.currentAdvance()) || (n == count && proc.currentRampIsZero())); if (proc.currentRampIsZero()) { DstTraits<dstType, premul>::store(proc.currentColor(), dst, n); } else { ramp<dstType, premul>(proc.currentColor(), proc.currentColorGrad(), dst, n, bias4f0, bias4f1); } proc.advance(SkIntToScalar(n)); count -= n; dst += n; if (n & 1) { SkTSwap(bias4f0, bias4f1); } } }