Factor out common code from sweep and linear.
authorHerb Derby <herb@google.com>
Thu, 4 May 2017 18:37:13 +0000 (14:37 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Thu, 4 May 2017 19:27:11 +0000 (19:27 +0000)
And, some file cleanup.

Change-Id: I804db924bce3b5834f6cda481315dd2da38df5ca
Reviewed-on: https://skia-review.googlesource.com/15226
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Florin Malita <fmalita@chromium.org>
src/effects/gradients/SkGradientShader.cpp
src/effects/gradients/SkGradientShaderPriv.h
src/effects/gradients/SkLinearGradient.cpp
src/effects/gradients/SkLinearGradient.h
src/effects/gradients/SkRadialGradient.h
src/effects/gradients/SkSweepGradient.cpp
src/effects/gradients/SkSweepGradient.h
src/effects/gradients/SkTwoPointConicalGradient.h

index 276eaac..03048db 100644 (file)
@@ -12,8 +12,8 @@
 #include "SkLinearGradient.h"
 #include "SkMallocPixelRef.h"
 #include "SkRadialGradient.h"
-#include "SkTwoPointConicalGradient.h"
 #include "SkSweepGradient.h"
+#include "SkTwoPointConicalGradient.h"
 
 enum GradientSerializationFlags {
     // Bits 29:31 used for various boolean flags
@@ -347,6 +347,155 @@ void SkGradientShaderBase::FlipGradientColors(SkColor* colorDst, Rec* recDst,
     memcpy(colorDst, colorsTemp.get(), count * sizeof(SkColor));
 }
 
+bool SkGradientShaderBase::onAppendStages(
+    SkRasterPipeline* pipeline, SkColorSpace* dstCS, SkArenaAlloc* alloc,
+    const SkMatrix& ctm, const SkPaint& paint,
+    const SkMatrix* localM) const
+{
+    // Local matrix not supported currently.  Remove once we have a generic RP wrapper.
+    if (localM || !getLocalMatrix().isIdentity()) {
+        return false;
+    }
+
+    SkMatrix matrix;
+    if (!ctm.invert(&matrix)) {
+        return false;
+    }
+
+    SkRasterPipeline p;
+    if (!this->adjustMatrixAndAppendStages(alloc, &matrix, &p)) {
+        return false;
+    }
+
+    auto* m = alloc->makeArrayDefault<float>(9);
+    if (matrix.asAffine(m)) {
+        // TODO: mapping y is not needed; split the matrix stages to save some math?
+        pipeline->append(SkRasterPipeline::matrix_2x3, m);
+    } else {
+        matrix.get9(m);
+        pipeline->append(SkRasterPipeline::matrix_perspective, m);
+    }
+
+    pipeline->extend(p);
+
+    const bool premulGrad = fGradFlags & SkGradientShader::kInterpolateColorsInPremul_Flag;
+    auto prepareColor = [premulGrad, dstCS, this](int i) {
+        SkColor4f c = dstCS ? to_colorspace(fOrigColors4f[i], fColorSpace.get(), dstCS)
+                            : SkColor4f_from_SkColor(fOrigColors[i], nullptr);
+        return premulGrad ? c.premul()
+                          : SkPM4f::From4f(Sk4f::Load(&c));
+    };
+
+    // The two-stop case with stops at 0 and 1.
+    if (fColorCount == 2 && fOrigPos == nullptr) {
+        const SkPM4f c_l = prepareColor(0),
+            c_r = prepareColor(1);
+
+        // See F and B below.
+        auto* f_and_b = alloc->makeArrayDefault<SkPM4f>(2);
+        f_and_b[0] = SkPM4f::From4f(c_r.to4f() - c_l.to4f());
+        f_and_b[1] = c_l;
+
+        pipeline->append(SkRasterPipeline::linear_gradient_2stops, f_and_b);
+    } else {
+
+        struct Stop { float t; SkPM4f f, b; };
+        struct Ctx { size_t n; Stop* stops; SkPM4f start; };
+
+        auto* ctx = alloc->make<Ctx>();
+        ctx->start = prepareColor(0);
+
+        // For each stop we calculate a bias B and a scale factor F, such that
+        // for any t between stops n and n+1, the color we want is B[n] + F[n]*t.
+        auto init_stop = [](float t_l, float t_r, SkPM4f c_l, SkPM4f c_r, Stop *stop) {
+            auto F = SkPM4f::From4f((c_r.to4f() - c_l.to4f()) / (t_r - t_l));
+            auto B = SkPM4f::From4f(c_l.to4f() - (F.to4f() * t_l));
+            *stop = {t_l, F, B};
+        };
+
+        if (fOrigPos == nullptr) {
+            // Handle evenly distributed stops.
+
+            float dt = 1.0f / (fColorCount - 1);
+            // In the evenly distributed case, fColorCount is the number of stops. There are no
+            // dummy entries.
+            auto* stopsArray = alloc->makeArrayDefault<Stop>(fColorCount);
+
+            float  t_l = 0;
+            SkPM4f c_l = ctx->start;
+            for (int i = 0; i < fColorCount - 1; i++) {
+                // Use multiply instead of accumulating error using repeated addition.
+                float  t_r = (i + 1) * dt;
+                SkPM4f c_r = prepareColor(i + 1);
+                init_stop(t_l, t_r, c_l, c_r, &stopsArray[i]);
+
+                t_l = t_r;
+                c_l = c_r;
+            }
+
+            // Force the last stop.
+            stopsArray[fColorCount - 1].t = 1;
+            stopsArray[fColorCount - 1].f = SkPM4f::From4f(Sk4f{0});
+            stopsArray[fColorCount - 1].b = prepareColor(fColorCount - 1);
+
+            ctx->n = fColorCount;
+            ctx->stops = stopsArray;
+        } else {
+            // Handle arbitrary stops.
+
+            // Remove the dummy stops inserted by SkGradientShaderBase::SkGradientShaderBase
+            // because they are naturally handled by the search method.
+            int firstStop;
+            int lastStop;
+            if (fColorCount > 2) {
+                firstStop = fOrigColors4f[0] != fOrigColors4f[1] ? 0 : 1;
+                lastStop = fOrigColors4f[fColorCount - 2] != fOrigColors4f[fColorCount - 1]
+                           ? fColorCount - 1 : fColorCount - 2;
+            } else {
+                firstStop = 0;
+                lastStop = 1;
+            }
+            int realCount = lastStop - firstStop + 1;
+
+            // This is the maximum number of stops. There may be fewer stops because the duplicate
+            // points of hard stops are removed.
+            auto* stopsArray = alloc->makeArrayDefault<Stop>(realCount);
+
+            size_t stopCount = 0;
+            float  t_l = fOrigPos[firstStop];
+            SkPM4f c_l = prepareColor(firstStop);
+            // N.B. lastStop is the index of the last stop, not one after.
+            for (int i = firstStop; i < lastStop; i++) {
+                float  t_r = fOrigPos[i + 1];
+                SkPM4f c_r = prepareColor(i + 1);
+                if (t_l < t_r) {
+                    init_stop(t_l, t_r, c_l, c_r, &stopsArray[stopCount]);
+                    stopCount += 1;
+                }
+                t_l = t_r;
+                c_l = c_r;
+            }
+
+            stopsArray[stopCount].t = fOrigPos[lastStop];
+            stopsArray[stopCount].f = SkPM4f::From4f(Sk4f{0});
+            stopsArray[stopCount].b = prepareColor(lastStop);
+            stopCount += 1;
+
+            ctx->n = stopCount;
+            ctx->stops = stopsArray;
+        }
+
+        pipeline->append(SkRasterPipeline::linear_gradient, ctx);
+    }
+
+    if (!premulGrad && !this->colorsAreOpaque()) {
+        pipeline->append(SkRasterPipeline::premul);
+    }
+
+    return true;
+}
+
+
 bool SkGradientShaderBase::isOpaque() const {
     return fColorsAreOpaque;
 }
@@ -1173,7 +1322,7 @@ GrGradientEffect::ColorType GrGradientEffect::determineColorType(
             } else if (SkScalarNearlyEqual(shader.fOrigPos[0], 0.0f) &&
                        SkScalarNearlyEqual(shader.fOrigPos[1], 1.0f) &&
                        SkScalarNearlyEqual(shader.fOrigPos[2], 1.0f)) {
-                
+
                 return kHardStopRightEdged_ColorType;
             }
         }
@@ -1369,7 +1518,7 @@ uint32_t GrGradientEffect::GLSLProcessor::GenBaseGradientKey(const GrProcessor&
     } else if (GrGradientEffect::kHardStopRightEdged_ColorType == e.getColorType()) {
         key |= kHardStopZeroOneOneKey;
     }
-   
+
     if (SkShader::TileMode::kClamp_TileMode == e.fTileMode) {
         key |= kClampTileMode;
     } else if (SkShader::TileMode::kRepeat_TileMode == e.fTileMode) {
index 0feb44b..c1e9c93 100644 (file)
@@ -17,6 +17,8 @@
 #include "SkColorPriv.h"
 #include "SkColorSpace.h"
 #include "SkOnce.h"
+#include "SkPM4fPriv.h"
+#include "SkRasterPipeline.h"
 #include "SkReadBuffer.h"
 #include "SkShader.h"
 #include "SkUtils.h"
@@ -201,28 +203,21 @@ public:
     uint32_t getGradFlags() const { return fGradFlags; }
 
 protected:
+    struct Rec {
+        SkFixed     fPos;   // 0...1
+        uint32_t    fScale; // (1 << 24) / range
+    };
+
     class GradientShaderBase4fContext;
 
     SkGradientShaderBase(SkReadBuffer& );
     void flatten(SkWriteBuffer&) const override;
     SK_TO_STRING_OVERRIDE()
 
-    const SkMatrix fPtsToUnit;
-    TileMode    fTileMode;
-    TileProc    fTileProc;
-    uint8_t     fGradFlags;
-
-    struct Rec {
-        SkFixed     fPos;   // 0...1
-        uint32_t    fScale; // (1 << 24) / range
-    };
-    Rec*        fRecs;
-
     void commonAsAGradient(GradientInfo*, bool flipGrad = false) const;
 
     bool onAsLuminanceColor(SkColor*) const override;
 
-
     void initLinearBitmap(SkBitmap* bitmap) const;
 
     /*
@@ -236,6 +231,14 @@ protected:
                                    SkColor* colorSrc, Rec* recSrc,
                                    int count);
 
+    bool onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS, SkArenaAlloc* alloc,
+                        const SkMatrix& ctm, const SkPaint& paint,
+                        const SkMatrix* localM) const final;
+
+    virtual bool adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                             SkMatrix* matrix,
+                                             SkRasterPipeline* p) const = 0;
+
     template <typename T, typename... Args>
     static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
         auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
@@ -245,6 +248,12 @@ protected:
         return ctx;
     }
 
+    const SkMatrix fPtsToUnit;
+    TileMode       fTileMode;
+    TileProc       fTileProc;
+    uint8_t        fGradFlags;
+    Rec*           fRecs;
+
 private:
     enum {
         kColorStorageCount = 4, // more than this many colors, and we'll use sk_malloc for the space
@@ -277,6 +286,7 @@ private:
     typedef SkShader INHERITED;
 };
 
+
 static inline int init_dither_toggle(int x, int y) {
     x &= 1;
     y = (y & 1) << 1;
index 24cb1b5..0b51da1 100644 (file)
@@ -83,178 +83,31 @@ SkShader::Context* SkLinearGradient::onMakeContext(
            : CheckedMakeContext<  LinearGradientContext>(alloc, *this, rec);
 }
 
-//
-// Stages:
-//
-//   * matrix (map dst -> grad space)
-//   * clamp/repeat/mirror (tiling)
-//   * linear_gradient_2stops (lerp c0/c1)
-//   * optional premul
-//
-bool SkLinearGradient::onAppendStages(SkRasterPipeline* p,
-                                      SkColorSpace* dstCS,
-                                      SkArenaAlloc* alloc,
-                                      const SkMatrix& ctm,
-                                      const SkPaint& paint,
-                                      const SkMatrix* localM) const {
-    // Local matrix not supported currently.  Remove once we have a generic RP wrapper.
-    if (localM || !getLocalMatrix().isIdentity()) {
-        return false;
-    }
-
-    SkMatrix dstToPts;
-    if (!ctm.invert(&dstToPts)) {
-        return false;
-    }
-
-    const auto dstToUnit = SkMatrix::Concat(fPtsToUnit, dstToPts);
-
-    // If the gradient is less than a quarter of a pixel, this falls into the subpixel gradient code
-    // handled on a different path.
-    SkVector dx = dstToUnit.mapVector(1, 0);
-    if (dx.fX >= 4) {
-        return false;
-    }
-
-    auto* m = alloc->makeArrayDefault<float>(9);
-    if (dstToUnit.asAffine(m)) {
-        // TODO: mapping y is not needed; split the matrix stages to save some math?
-        p->append(SkRasterPipeline::matrix_2x3, m);
-    } else {
-        dstToUnit.get9(m);
-        p->append(SkRasterPipeline::matrix_perspective, m);
-    }
+bool SkLinearGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                                   SkMatrix* matrix,
+                                                   SkRasterPipeline* p) const {
+    *matrix = SkMatrix::Concat(fPtsToUnit, *matrix);
+    // If the gradient is less than a quarter of a pixel, this falls into the
+    // subpixel gradient code handled on a different path.
+    SkVector dx = matrix->mapVector(1, 0);
+    if (dx.fX >= 4) { return false; }
 
-    // TODO: clamp/repeat/mirror const 1f stages?
     auto* limit = alloc->make<float>(1.0f);
-
-    const bool premulGrad = fGradFlags & SkGradientShader::kInterpolateColorsInPremul_Flag;
-    auto prepareColor = [premulGrad, dstCS, this](int i) {
-        SkColor4f c = dstCS ? to_colorspace(fOrigColors4f[i], fColorSpace.get(), dstCS)
-                            : SkColor4f_from_SkColor(fOrigColors[i], nullptr);
-        return premulGrad ? c.premul()
-                          : SkPM4f::From4f(Sk4f::Load(&c));
-    };
-
-    // The two-stop case with stops at 0 and 1.
     if (fColorCount == 2 && fOrigPos == nullptr) {
         switch (fTileMode) {
-            case kClamp_TileMode:  p->append(SkRasterPipeline:: clamp_x, limit); break;
+            case kClamp_TileMode:  p->append(SkRasterPipeline::clamp_x, limit);  break;
             case kMirror_TileMode: p->append(SkRasterPipeline::mirror_x, limit); break;
             case kRepeat_TileMode: p->append(SkRasterPipeline::repeat_x, limit); break;
         }
-
-        const SkPM4f c_l = prepareColor(0),
-                     c_r = prepareColor(1);
-
-        // See F and B below.
-        auto* f_and_b = alloc->makeArrayDefault<SkPM4f>(2);
-        f_and_b[0] = SkPM4f::From4f(c_r.to4f() - c_l.to4f());
-        f_and_b[1] = c_l;
-
-        p->append(SkRasterPipeline::linear_gradient_2stops, f_and_b);
     } else {
         switch (fTileMode) {
             // The search strategy does not need clamping. It has implicit hard stops at the
             // first and last stop.
-            case kClamp_TileMode: break;
+            case kClamp_TileMode:  break;
             case kMirror_TileMode: p->append(SkRasterPipeline::mirror_x, limit); break;
             case kRepeat_TileMode: p->append(SkRasterPipeline::repeat_x, limit); break;
         }
-
-        struct Stop { float t; SkPM4f f, b; };
-        struct Ctx { size_t n; Stop* stops; SkPM4f start; };
-
-        auto* ctx = alloc->make<Ctx>();
-        ctx->start = prepareColor(0);
-
-        // For each stop we calculate a bias B and a scale factor F, such that
-        // for any t between stops n and n+1, the color we want is B[n] + F[n]*t.
-        auto init_stop = [](float t_l, float t_r, SkPM4f c_l, SkPM4f c_r, Stop *stop) {
-            auto F = SkPM4f::From4f((c_r.to4f() - c_l.to4f()) / (t_r - t_l));
-            auto B = SkPM4f::From4f(c_l.to4f() - (F.to4f() * t_l));
-            *stop = {t_l, F, B};
-        };
-
-        if (fOrigPos == nullptr) {
-            // Handle evenly distributed stops.
-
-            float dt = 1.0f / (fColorCount - 1);
-            // In the evenly distributed case, fColorCount is the number of stops. There are no
-            // dummy entries.
-            auto* stopsArray = alloc->makeArrayDefault<Stop>(fColorCount);
-
-            float  t_l = 0;
-            SkPM4f c_l = ctx->start;
-            for (int i = 0; i < fColorCount - 1; i++) {
-                // Use multiply instead of accumulating error using repeated addition.
-                float  t_r = (i + 1) * dt;
-                SkPM4f c_r = prepareColor(i + 1);
-                init_stop(t_l, t_r, c_l, c_r, &stopsArray[i]);
-
-                t_l = t_r;
-                c_l = c_r;
-            }
-
-            // Force the last stop.
-            stopsArray[fColorCount - 1].t = 1;
-            stopsArray[fColorCount - 1].f = SkPM4f::From4f(Sk4f{0});
-            stopsArray[fColorCount - 1].b = prepareColor(fColorCount - 1);
-
-            ctx->n = fColorCount;
-            ctx->stops = stopsArray;
-        } else {
-            // Handle arbitrary stops.
-
-            // Remove the dummy stops inserted by SkGradientShaderBase::SkGradientShaderBase
-            // because they are naturally handled by the search method.
-            int firstStop;
-            int lastStop;
-            if (fColorCount > 2) {
-                firstStop = fOrigColors4f[0] != fOrigColors4f[1] ? 0 : 1;
-                lastStop = fOrigColors4f[fColorCount - 2] != fOrigColors4f[fColorCount - 1]
-                           ? fColorCount - 1 : fColorCount - 2;
-            } else {
-                firstStop = 0;
-                lastStop = 1;
-            }
-            int realCount = lastStop - firstStop + 1;
-
-            // This is the maximum number of stops. There may be fewer stops because the duplicate
-            // points of hard stops are removed.
-            auto* stopsArray = alloc->makeArrayDefault<Stop>(realCount);
-
-            size_t stopCount = 0;
-            float  t_l = fOrigPos[firstStop];
-            SkPM4f c_l = prepareColor(firstStop);
-            // N.B. lastStop is the index of the last stop, not one after.
-            for (int i = firstStop; i < lastStop; i++) {
-                float  t_r = fOrigPos[i + 1];
-                SkPM4f c_r = prepareColor(i + 1);
-                if (t_l < t_r) {
-                    init_stop(t_l, t_r, c_l, c_r, &stopsArray[stopCount]);
-                    stopCount += 1;
-                }
-                t_l = t_r;
-                c_l = c_r;
-            }
-
-            stopsArray[stopCount].t = fOrigPos[lastStop];
-            stopsArray[stopCount].f = SkPM4f::From4f(Sk4f{0});
-            stopsArray[stopCount].b = prepareColor(lastStop);
-            stopCount += 1;
-
-            ctx->n = stopCount;
-            ctx->stops = stopsArray;
-        }
-
-        p->append(SkRasterPipeline::linear_gradient, ctx);
-    }
-
-    if (!premulGrad && !this->colorsAreOpaque()) {
-        p->append(SkRasterPipeline::premul);
     }
-
     return true;
 }
 
index f860568..19a965c 100644 (file)
@@ -68,8 +68,10 @@ protected:
     void flatten(SkWriteBuffer& buffer) const override;
     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
 
-    bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
-                        const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
+    bool adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                     SkMatrix* matrix,
+                                     SkRasterPipeline* p) const final;
+
 
     sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
 
index c43df09..f91f343 100644 (file)
@@ -38,6 +38,12 @@ protected:
     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
     sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
 
+    bool adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                     SkMatrix* matrix,
+                                     SkRasterPipeline* p) const final {
+        return false;
+    }
+
 private:
     const SkPoint fCenter;
     const SkScalar fRadius;
index 81fdfe4..b3a24cd 100644 (file)
@@ -311,150 +311,12 @@ void SkSweepGradient::toString(SkString* str) const {
     str->append(")");
 }
 
-bool SkSweepGradient::onAppendStages(SkRasterPipeline* p,
-                                     SkColorSpace* dstCS,
-                                     SkArenaAlloc* alloc,
-                                     const SkMatrix& ctm,
-                                     const SkPaint& paint,
-                                     const SkMatrix* localM) const {
-    // Local matrix not supported currently.  Remove once we have a generic RP wrapper.
-    if (localM || !getLocalMatrix().isIdentity()) {
-        return false;
-    }
-
-    SkMatrix dstToSrc;
-    if (!ctm.invert(&dstToSrc)) {
-        return false;
-    }
-
-    const auto dstToCenter = SkMatrix::Concat(
-            SkMatrix::MakeTrans(-fCenter.fX, -fCenter.fY), dstToSrc);
-
-    auto* m = alloc->makeArrayDefault<float>(9);
-    if (dstToCenter.asAffine(m)) {
-        // TODO: mapping y is not needed; split the matrix stages to save some math?
-        p->append(SkRasterPipeline::matrix_2x3, m);
-    } else {
-        dstToCenter.get9(m);
-        p->append(SkRasterPipeline::matrix_perspective, m);
-    }
-
+bool SkSweepGradient::adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                                  SkMatrix* matrix,
+                                                  SkRasterPipeline* p) const {
+    matrix->postTranslate(-fCenter.fX, -fCenter.fY);
     p->append(SkRasterPipeline::xy_to_polar_unit);
 
-    const bool premulGrad = fGradFlags & SkGradientShader::kInterpolateColorsInPremul_Flag;
-    auto prepareColor = [premulGrad, dstCS, this](int i) {
-        SkColor4f c = dstCS ? to_colorspace(fOrigColors4f[i], fColorSpace.get(), dstCS)
-                            : SkColor4f_from_SkColor(fOrigColors[i], nullptr);
-        return premulGrad ? c.premul()
-                          : SkPM4f::From4f(Sk4f::Load(&c));
-    };
-
-    // The two-stop case with stops at 0 and 1.
-    if (fColorCount == 2 && fOrigPos == nullptr) {
-        const SkPM4f c_l = prepareColor(0),
-                     c_r = prepareColor(1);
-
-        // See F and B below.
-        auto* f_and_b = alloc->makeArrayDefault<SkPM4f>(2);
-        f_and_b[0] = SkPM4f::From4f(c_r.to4f() - c_l.to4f());
-        f_and_b[1] = c_l;
-
-        p->append(SkRasterPipeline::linear_gradient_2stops, f_and_b);
-    } else {
-
-        struct Stop { float t; SkPM4f f, b; };
-        struct Ctx { size_t n; Stop* stops; SkPM4f start; };
-
-        auto* ctx = alloc->make<Ctx>();
-        ctx->start = prepareColor(0);
-
-        // For each stop we calculate a bias B and a scale factor F, such that
-        // for any t between stops n and n+1, the color we want is B[n] + F[n]*t.
-        auto init_stop = [](float t_l, float t_r, SkPM4f c_l, SkPM4f c_r, Stop *stop) {
-            auto F = SkPM4f::From4f((c_r.to4f() - c_l.to4f()) / (t_r - t_l));
-            auto B = SkPM4f::From4f(c_l.to4f() - (F.to4f() * t_l));
-            *stop = {t_l, F, B};
-        };
-
-        if (fOrigPos == nullptr) {
-            // Handle evenly distributed stops.
-
-            float dt = 1.0f / (fColorCount - 1);
-            // In the evenly distributed case, fColorCount is the number of stops. There are no
-            // dummy entries.
-            auto* stopsArray = alloc->makeArrayDefault<Stop>(fColorCount);
-
-            float  t_l = 0;
-            SkPM4f c_l = ctx->start;
-            for (int i = 0; i < fColorCount - 1; i++) {
-                // Use multiply instead of accumulating error using repeated addition.
-                float  t_r = (i + 1) * dt;
-                SkPM4f c_r = prepareColor(i + 1);
-                init_stop(t_l, t_r, c_l, c_r, &stopsArray[i]);
-
-                t_l = t_r;
-                c_l = c_r;
-            }
-
-            // Force the last stop.
-            stopsArray[fColorCount - 1].t = 1;
-            stopsArray[fColorCount - 1].f = SkPM4f::From4f(Sk4f{0});
-            stopsArray[fColorCount - 1].b = prepareColor(fColorCount - 1);
-
-            ctx->n = fColorCount;
-            ctx->stops = stopsArray;
-        } else {
-            // Handle arbitrary stops.
-
-            // Remove the dummy stops inserted by SkGradientShaderBase::SkGradientShaderBase
-            // because they are naturally handled by the search method.
-            int firstStop;
-            int lastStop;
-            if (fColorCount > 2) {
-                firstStop = fOrigColors4f[0] != fOrigColors4f[1] ? 0 : 1;
-                lastStop = fOrigColors4f[fColorCount - 2] != fOrigColors4f[fColorCount - 1]
-                           ? fColorCount - 1 : fColorCount - 2;
-            } else {
-                firstStop = 0;
-                lastStop = 1;
-            }
-            int realCount = lastStop - firstStop + 1;
-
-            // This is the maximum number of stops. There may be fewer stops because the duplicate
-            // points of hard stops are removed.
-            auto* stopsArray = alloc->makeArrayDefault<Stop>(realCount);
-
-            size_t stopCount = 0;
-            float  t_l = fOrigPos[firstStop];
-            SkPM4f c_l = prepareColor(firstStop);
-            // N.B. lastStop is the index of the last stop, not one after.
-            for (int i = firstStop; i < lastStop; i++) {
-                float  t_r = fOrigPos[i + 1];
-                SkPM4f c_r = prepareColor(i + 1);
-                if (t_l < t_r) {
-                    init_stop(t_l, t_r, c_l, c_r, &stopsArray[stopCount]);
-                    stopCount += 1;
-                }
-                t_l = t_r;
-                c_l = c_r;
-            }
-
-            stopsArray[stopCount].t = fOrigPos[lastStop];
-            stopsArray[stopCount].f = SkPM4f::From4f(Sk4f{0});
-            stopsArray[stopCount].b = prepareColor(lastStop);
-            stopCount += 1;
-
-            ctx->n = stopCount;
-            ctx->stops = stopsArray;
-        }
-
-        p->append(SkRasterPipeline::linear_gradient, ctx);
-    }
-
-    if (!premulGrad && !this->colorsAreOpaque()) {
-        p->append(SkRasterPipeline::premul);
-    }
-
     return true;
 }
 
index 45c4233..5f12744 100644 (file)
@@ -38,9 +38,9 @@ protected:
     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
     sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
 
-    bool onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* space, SkArenaAlloc* alloc,
-                        const SkMatrix& matrix, const SkPaint& paint,
-                        const SkMatrix* localM) const override;
+    bool adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                     SkMatrix* matrix,
+                                     SkRasterPipeline* p) const final;
 
 private:
     const SkPoint fCenter;
index b32f52c..d24dbd4 100644 (file)
@@ -78,6 +78,11 @@ protected:
     void flatten(SkWriteBuffer& buffer) const override;
     Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
     sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
+    bool adjustMatrixAndAppendStages(SkArenaAlloc* alloc,
+                                     SkMatrix* matrix,
+                                     SkRasterPipeline* p) const final {
+        return false;
+    }
 
 private:
     SkPoint fCenter1;