Esempio n. 1
0
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;
        }
    }
}
Esempio n. 2
0
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);
        }
    }
}