Remove dead gradient perspective code

The cool bit here is that Sk4fLinearGradient is now always fast, and never calls the slow
base-class impl.  This means we can rip out Sk4fGradientBase::{mapTs, shadeSpan4f, etc}.

Change-Id: Id3788bc810873b2a209f66efa4187c84b3397e2f
Reviewed-on: https://skia-review.googlesource.com/22366
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/src/shaders/SkShader.cpp b/src/shaders/SkShader.cpp
index 5a58410..3c9d989 100644
--- a/src/shaders/SkShader.cpp
+++ b/src/shaders/SkShader.cpp
@@ -123,7 +123,6 @@
     // Because the context parameters must be valid at this point, we know that the matrix is
     // invertible.
     SkAssertResult(fShader.computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, &fTotalInverse));
-    fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
 
     fPaintAlpha = rec.fPaint->getAlpha();
 }
@@ -214,19 +213,6 @@
 #endif
 }
 
-SkShaderBase::Context::MatrixClass SkShaderBase::Context::ComputeMatrixClass(const SkMatrix& mat) {
-    MatrixClass mc = kLinear_MatrixClass;
-
-    if (mat.hasPerspective()) {
-        if (mat.isFixedStepInX()) {
-            mc = kFixedStepInX_MatrixClass;
-        } else {
-            mc = kPerspective_MatrixClass;
-        }
-    }
-    return mc;
-}
-
 //////////////////////////////////////////////////////////////////////////////
 
 const SkMatrix& SkShader::getLocalMatrix() const {
diff --git a/src/shaders/SkShaderBase.h b/src/shaders/SkShaderBase.h
index d469442..f43790a 100644
--- a/src/shaders/SkShaderBase.h
+++ b/src/shaders/SkShaderBase.h
@@ -119,24 +119,14 @@
         // Reference to shader, so we don't have to dupe information.
         const SkShaderBase& fShader;
 
-        enum MatrixClass {
-            kLinear_MatrixClass,            // no perspective
-            kFixedStepInX_MatrixClass,      // fast perspective, need to call fixedStepInX() each
-                                            // scanline
-            kPerspective_MatrixClass        // slow perspective, need to mappoints each pixel
-        };
-        static MatrixClass ComputeMatrixClass(const SkMatrix&);
-
         uint8_t         getPaintAlpha() const { return fPaintAlpha; }
         const SkMatrix& getTotalInverse() const { return fTotalInverse; }
-        MatrixClass     getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
         const SkMatrix& getCTM() const { return fCTM; }
 
     private:
         SkMatrix    fCTM;
         SkMatrix    fTotalInverse;
         uint8_t     fPaintAlpha;
-        uint8_t     fTotalInverseClass;
 
         typedef SkNoncopyable INHERITED;
     };
diff --git a/src/shaders/gradients/Sk4fGradientBase.cpp b/src/shaders/gradients/Sk4fGradientBase.cpp
index f5d5e71..0d9e6d0 100644
--- a/src/shaders/gradients/Sk4fGradientBase.cpp
+++ b/src/shaders/gradients/Sk4fGradientBase.cpp
@@ -293,8 +293,8 @@
 
     const SkMatrix& inverse = this->getTotalInverse();
     fDstToPos.setConcat(shader.fPtsToUnit, inverse);
+    SkASSERT(!fDstToPos.hasPerspective());
     fDstToPosProc = fDstToPos.getMapXYProc();
-    fDstToPosClass = static_cast<uint8_t>(INHERITED::ComputeMatrixClass(fDstToPos));
 
     if (shader.fColorsAreOpaque && this->getPaintAlpha() == SK_AlphaOPAQUE) {
         fFlags |= kOpaqueAlpha_Flag;
@@ -315,126 +315,3 @@
     // This impl only shades to 4f.
     SkASSERT(false);
 }
-
-void SkGradientShaderBase::
-GradientShaderBase4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
-    if (fColorsArePremul) {
-        this->shadePremulSpan<ApplyPremul::False>(x, y, dst, count);
-    } else {
-        this->shadePremulSpan<ApplyPremul::True>(x, y, dst, count);
-    }
-}
-
-template<ApplyPremul premul>
-void SkGradientShaderBase::
-GradientShaderBase4fContext::shadePremulSpan(int x, int y, SkPM4f dst[], int count) const {
-    const SkGradientShaderBase& shader =
-        static_cast<const SkGradientShaderBase&>(fShader);
-
-    switch (shader.fTileMode) {
-    case kClamp_TileMode:
-        this->shadeSpanInternal<premul, kClamp_TileMode>(x, y, dst, count);
-        break;
-    case kRepeat_TileMode:
-        this->shadeSpanInternal<premul, kRepeat_TileMode>(x, y, dst, count);
-        break;
-    case kMirror_TileMode:
-        this->shadeSpanInternal<premul, kMirror_TileMode>(x, y, dst, count);
-        break;
-    }
-}
-
-template<ApplyPremul premul, SkShader::TileMode tileMode>
-void SkGradientShaderBase::
-GradientShaderBase4fContext::shadeSpanInternal(int x, int y, SkPM4f dst[], int count) const {
-    static const int kBufSize = 128;
-    SkScalar ts[kBufSize];
-    TSampler<premul, tileMode> sampler(*this);
-
-    SkASSERT(count > 0);
-    do {
-        const int n = SkTMin(kBufSize, count);
-        this->mapTs(x, y, ts, n);
-        for (int i = 0; i < n; ++i) {
-            const Sk4f c = sampler.sample(ts[i]);
-            DstTraits<premul>::store(c, dst++);
-        }
-        x += n;
-        count -= n;
-    } while (count > 0);
-}
-
-template<ApplyPremul premul, SkShader::TileMode tileMode>
-class SkGradientShaderBase::GradientShaderBase4fContext::TSampler {
-public:
-    TSampler(const GradientShaderBase4fContext& ctx)
-        : fCtx(ctx)
-        , fInterval(nullptr) {
-        switch (tileMode) {
-        case kClamp_TileMode:
-            fLargestIntervalValue = SK_ScalarInfinity;
-            break;
-        case kRepeat_TileMode:
-            fLargestIntervalValue = nextafterf(1, 0);
-            break;
-        case kMirror_TileMode:
-            fLargestIntervalValue = nextafterf(2.0f, 0);
-            break;
-        }
-    }
-
-    Sk4f sample(SkScalar t) {
-        const auto tiled_t = tileProc(t);
-
-        if (!fInterval) {
-            // Very first sample => locate the initial interval.
-            // TODO: maybe do this in ctor to remove a branch?
-            fInterval = fCtx.fIntervals.find(tiled_t);
-            this->loadIntervalData(fInterval);
-        } else if (!fInterval->contains(tiled_t)) {
-            fInterval = fCtx.fIntervals.findNext(tiled_t, fInterval, t >= fPrevT);
-            this->loadIntervalData(fInterval);
-        }
-
-        fPrevT = t;
-        return lerp(tiled_t);
-    }
-
-private:
-    SkScalar tileProc(SkScalar t) const {
-        switch (tileMode) {
-        case kClamp_TileMode:
-            // synthetic clamp-mode edge intervals allow for a free-floating t:
-            //   [-inf..0)[0..1)[1..+inf)
-            return t;
-        case kRepeat_TileMode:
-            // t % 1  (intervals range: [0..1))
-            // Due to the extra arithmetic, we must clamp to ensure the value remains less than 1.
-            return SkTMin(t - SkScalarFloorToScalar(t), fLargestIntervalValue);
-        case kMirror_TileMode:
-            // t % 2  (synthetic mirror intervals expand the range to [0..2)
-            // Due to the extra arithmetic, we must clamp to ensure the value remains less than 2.
-            return SkTMin(t - SkScalarFloorToScalar(t / 2) * 2, fLargestIntervalValue);
-        }
-
-        SK_ABORT("Unhandled tile mode.");
-        return 0;
-    }
-
-    Sk4f lerp(SkScalar t) {
-        SkASSERT(fInterval->contains(t));
-        return fCb + fCg * t;
-    }
-
-    void loadIntervalData(const Sk4fGradientInterval* i) {
-        fCb = DstTraits<premul>::load(i->fCb);
-        fCg = DstTraits<premul>::load(i->fCg);
-    }
-
-    const GradientShaderBase4fContext& fCtx;
-    const Sk4fGradientInterval*        fInterval;
-    SkScalar                           fPrevT;
-    SkScalar                           fLargestIntervalValue;
-    Sk4f                               fCb;
-    Sk4f                               fCg;
-};
diff --git a/src/shaders/gradients/Sk4fGradientBase.h b/src/shaders/gradients/Sk4fGradientBase.h
index acba642..629b065 100644
--- a/src/shaders/gradients/Sk4fGradientBase.h
+++ b/src/shaders/gradients/Sk4fGradientBase.h
@@ -60,18 +60,14 @@
 
     uint32_t getFlags() const override { return fFlags; }
 
-    void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
-    void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
+    void shadeSpan(int x, int y, SkPMColor dst[], int count) final;
 
     bool isValid() const;
 
 protected:
-    virtual void mapTs(int x, int y, SkScalar ts[], int count) const = 0;
-
     Sk4fGradientIntervalBuffer fIntervals;
     SkMatrix                   fDstToPos;
     SkMatrix::MapXYProc        fDstToPosProc;
-    uint8_t                    fDstToPosClass;
     uint8_t                    fFlags;
     bool                       fColorsArePremul;
 
@@ -80,15 +76,6 @@
 
     void addMirrorIntervals(const SkGradientShaderBase&,
                             const Sk4f& componentScale, bool reverse);
-
-    template<ApplyPremul, SkShader::TileMode tileMode>
-    class TSampler;
-
-    template <ApplyPremul premul>
-    void shadePremulSpan(int x, int y, SkPM4f[], int count) const;
-
-    template <ApplyPremul premul, SkShader::TileMode tileMode>
-    void shadeSpanInternal(int x, int y, SkPM4f[], int count) const;
 };
 
 #endif // Sk4fGradientBase_DEFINED
diff --git a/src/shaders/gradients/Sk4fLinearGradient.cpp b/src/shaders/gradients/Sk4fLinearGradient.cpp
index aab1779..700b7fb 100644
--- a/src/shaders/gradients/Sk4fLinearGradient.cpp
+++ b/src/shaders/gradients/Sk4fLinearGradient.cpp
@@ -91,7 +91,7 @@
     : INHERITED(shader, rec) {
 
     // Our fast path expects interval points to be monotonically increasing in x.
-    const bool reverseIntervals = this->isFast() && std::signbit(fDstToPos.getScaleX());
+    const bool reverseIntervals = std::signbit(fDstToPos.getScaleX());
     fIntervals.init(shader, rec.fDstColorSpace, shader.fTileMode,
                     fColorsArePremul, rec.fPaint->getAlpha() * (1.0f / 255), reverseIntervals);
 
@@ -142,18 +142,7 @@
 }
 
 void SkLinearGradient::
-LinearGradient4fContext::shadeSpan(int x, int y, SkPMColor dst[], int count) {
-    // This impl only shades to 4f.
-    SkASSERT(false);
-}
-
-void SkLinearGradient::
 LinearGradient4fContext::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
-    if (!this->isFast()) {
-        this->INHERITED::shadeSpan4f(x, y, dst, count);
-        return;
-    }
-
     SkASSERT(count > 0);
     if (fColorsArePremul) {
         this->shadePremulSpan<ApplyPremul::False>(x, y, dst, count);
@@ -353,50 +342,3 @@
     const SkScalar              fDx;        // 'dx' for consistency with other impls; actually dt/dx
     const bool                  fIsVertical;
 };
-
-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);
-            // Perspective may yield NaN values.
-            // Short of a better idea, drop to 0.
-            ts[i] = SkScalarIsNaN(pt.x()) ? 0 : pt.x();
-            sx += SK_Scalar1;
-        }
-    }
-}
diff --git a/src/shaders/gradients/Sk4fLinearGradient.h b/src/shaders/gradients/Sk4fLinearGradient.h
index 96af4df..11606e1 100644
--- a/src/shaders/gradients/Sk4fLinearGradient.h
+++ b/src/shaders/gradients/Sk4fLinearGradient.h
@@ -16,12 +16,8 @@
 public:
     LinearGradient4fContext(const SkLinearGradient&, const ContextRec&);
 
-    void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
     void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
 
-protected:
-    void mapTs(int x, int y, SkScalar ts[], int count) const override;
-
 private:
     using INHERITED = GradientShaderBase4fContext;
 
@@ -36,8 +32,6 @@
 
     const Sk4fGradientInterval* findInterval(SkScalar fx) const;
 
-    bool isFast() const { return fDstToPosClass == kLinear_MatrixClass; }
-
     mutable const Sk4fGradientInterval* fCachedInterval;
 };
 
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index 0619ef0..6377018 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -534,12 +534,9 @@
     const SkMatrix& inverse = this->getTotalInverse();
 
     fDstToIndex.setConcat(shader.fPtsToUnit, inverse);
+    SkASSERT(!fDstToIndex.hasPerspective());
 
     fDstToIndexProc = fDstToIndex.getMapXYProc();
-    fDstToIndexClass = (uint8_t)SkShaderBase::Context::ComputeMatrixClass(fDstToIndex);
-
-    // TODO: remove all perspective-related gradient code
-    SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
 
     // now convert our colors in to PMColors
     unsigned paintAlpha = this->getPaintAlpha();
diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp
index 08ce2db..fc49d34 100644
--- a/src/shaders/gradients/SkLinearGradient.cpp
+++ b/src/shaders/gradients/SkLinearGradient.cpp
@@ -285,9 +285,7 @@
     SkASSERT(count > 0);
     const SkLinearGradient& linearGradient = static_cast<const SkLinearGradient&>(fShader);
 
-    if (SkShader::kClamp_TileMode == linearGradient.fTileMode &&
-        kLinear_MatrixClass == fDstToIndexClass)
-    {
+    if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
         this->shade4_clamp(x, y, dstC, count);
         return;
     }
@@ -298,43 +296,22 @@
     const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
     int                 toggle = init_dither_toggle(x, y);
 
-    if (fDstToIndexClass != kPerspective_MatrixClass) {
-        dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
-                             SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
-        SkGradFixed dx, fx = SkScalarPinToGradFixed(srcPt.fX);
+    dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+                         SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+    SkGradFixed fx = SkScalarPinToGradFixed(srcPt.fX),
+                dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX());
 
-        if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
-            const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
-            // todo: do we need a real/high-precision value for dx here?
-            dx = SkScalarPinToGradFixed(step.fX);
-        } else {
-            SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
-            dx = SkScalarPinToGradFixed(fDstToIndex.getScaleX());
-        }
-
-        LinearShadeProc shadeProc = shadeSpan_linear_repeat;
-        if (0 == dx) {
-            shadeProc = shadeSpan_linear_vertical_lerp;
-        } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
-            shadeProc = shadeSpan_linear_clamp;
-        } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) {
-            shadeProc = shadeSpan_linear_mirror;
-        } else {
-            SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode);
-        }
-        (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count);
+    LinearShadeProc shadeProc = shadeSpan_linear_repeat;
+    if (0 == dx) {
+        shadeProc = shadeSpan_linear_vertical_lerp;
+    } else if (SkShader::kClamp_TileMode == linearGradient.fTileMode) {
+        shadeProc = shadeSpan_linear_clamp;
+    } else if (SkShader::kMirror_TileMode == linearGradient.fTileMode) {
+        shadeProc = shadeSpan_linear_mirror;
     } else {
-        SkScalar    dstX = SkIntToScalar(x);
-        SkScalar    dstY = SkIntToScalar(y);
-        do {
-            dstProc(fDstToIndex, dstX, dstY, &srcPt);
-            unsigned fi = proc(SkScalarToFixed(srcPt.fX));
-            SkASSERT(fi <= 0xFFFF);
-            *dstC++ = cache[toggle + (fi >> kCache32Shift)];
-            toggle = next_dither_toggle(toggle);
-            dstX += SK_Scalar1;
-        } while (--count != 0);
+        SkASSERT(SkShader::kRepeat_TileMode == linearGradient.fTileMode);
     }
+    (*shadeProc)(proc, dx, fx, dstC, cache, toggle, count);
 }
 
 SkShader::GradientType SkLinearGradient::asAGradient(GradientInfo* info) const {
@@ -756,7 +733,6 @@
 void SkLinearGradient::LinearGradientContext::shade4_clamp(int x, int y, SkPMColor dstC[],
                                                            int count) {
     SkASSERT(count > 0);
-    SkASSERT(kLinear_MatrixClass == fDstToIndexClass);
 
     SkPoint srcPt;
     fDstToIndexProc(fDstToIndex, x + SK_ScalarHalf, y + SK_ScalarHalf, &srcPt);
diff --git a/src/shaders/gradients/SkRadialGradient.cpp b/src/shaders/gradients/SkRadialGradient.cpp
index 06135e8..0a6a940 100644
--- a/src/shaders/gradients/SkRadialGradient.cpp
+++ b/src/shaders/gradients/SkRadialGradient.cpp
@@ -194,44 +194,23 @@
 
     SkPoint             srcPt;
     SkMatrix::MapXYProc dstProc = fDstToIndexProc;
-    TileProc            proc = radialGradient.fTileProc;
     const SkPMColor* SK_RESTRICT cache = fCache->getCache32();
     int toggle = init_dither_toggle(x, y);
 
-    if (fDstToIndexClass != kPerspective_MatrixClass) {
-        dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
-                             SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
-        SkScalar sdx = fDstToIndex.getScaleX();
-        SkScalar sdy = fDstToIndex.getSkewY();
+    dstProc(fDstToIndex, SkIntToScalar(x) + SK_ScalarHalf,
+                         SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+    SkScalar sdx = fDstToIndex.getScaleX();
+    SkScalar sdy = fDstToIndex.getSkewY();
 
-        if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
-            const auto step = fDstToIndex.fixedStepInX(SkIntToScalar(y));
-            sdx = step.fX;
-            sdy = step.fY;
-        } else {
-            SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
-        }
-
-        RadialShadeProc shadeProc = shadeSpan_radial_repeat;
-        if (SkShader::kClamp_TileMode == radialGradient.fTileMode) {
-            shadeProc = shadeSpan_radial_clamp2;
-        } else if (SkShader::kMirror_TileMode == radialGradient.fTileMode) {
-            shadeProc = shadeSpan_radial_mirror;
-        } else {
-            SkASSERT(SkShader::kRepeat_TileMode == radialGradient.fTileMode);
-        }
-        (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle);
-    } else {    // perspective case
-        SkScalar dstX = SkIntToScalar(x);
-        SkScalar dstY = SkIntToScalar(y);
-        do {
-            dstProc(fDstToIndex, dstX, dstY, &srcPt);
-            unsigned fi = proc(SkScalarToFixed(srcPt.length()));
-            SkASSERT(fi <= 0xFFFF);
-            *dstC++ = cache[fi >> SkGradientShaderBase::kCache32Shift];
-            dstX += SK_Scalar1;
-        } while (--count != 0);
+    RadialShadeProc shadeProc = shadeSpan_radial_repeat;
+    if (SkShader::kClamp_TileMode == radialGradient.fTileMode) {
+        shadeProc = shadeSpan_radial_clamp2;
+    } else if (SkShader::kMirror_TileMode == radialGradient.fTileMode) {
+        shadeProc = shadeSpan_radial_mirror;
+    } else {
+        SkASSERT(SkShader::kRepeat_TileMode == radialGradient.fTileMode);
     }
+    (*shadeProc)(srcPt.fX, sdx, srcPt.fY, sdy, dstC, cache, count, toggle);
 }
 
 /////////////////////////////////////////////////////////////////////
diff --git a/src/shaders/gradients/SkSweepGradient.cpp b/src/shaders/gradients/SkSweepGradient.cpp
index 61ddf5c..e6bc42c 100644
--- a/src/shaders/gradients/SkSweepGradient.cpp
+++ b/src/shaders/gradients/SkSweepGradient.cpp
@@ -98,21 +98,13 @@
     int                 toggle = init_dither_toggle(x, y);
     SkPoint             srcPt;
 
-    if (fDstToIndexClass != kPerspective_MatrixClass) {
-        proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
-                     SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
-        SkScalar dx, fx = srcPt.fX;
-        SkScalar dy, fy = srcPt.fY;
+    proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
+                 SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
+    SkScalar fx = srcPt.fX,
+             fy = srcPt.fY;
 
-        if (fDstToIndexClass == kFixedStepInX_MatrixClass) {
-            const auto step = matrix.fixedStepInX(SkIntToScalar(y) + SK_ScalarHalf);
-            dx = step.fX;
-            dy = step.fY;
-        } else {
-            SkASSERT(fDstToIndexClass == kLinear_MatrixClass);
-            dx = matrix.getScaleX();
-            dy = matrix.getSkewY();
-        }
+    SkScalar dx = matrix.getScaleX(),
+             dy = matrix.getSkewY();
 
         for (; count > 0; --count) {
             *dstC++ = cache[toggle + SkATan2_255(fy, fx)];
@@ -120,14 +112,6 @@
             fy += dy;
             toggle = next_dither_toggle(toggle);
         }
-    } else {  // perspective case
-        for (int stop = x + count; x < stop; x++) {
-            proc(matrix, SkIntToScalar(x) + SK_ScalarHalf,
-                         SkIntToScalar(y) + SK_ScalarHalf, &srcPt);
-            *dstC++ = cache[toggle + SkATan2_255(srcPt.fY, srcPt.fX)];
-            toggle = next_dither_toggle(toggle);
-        }
-    }
 }
 
 /////////////////////////////////////////////////////////////////////