/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "src/gpu/effects/GrTextureEffect.h"

#include "src/gpu/GrTexture.h"
#include "src/gpu/GrTexturePriv.h"
#include "src/gpu/effects/GrMatrixEffect.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
#include "src/sksl/SkSLCPP.h"
#include "src/sksl/SkSLUtil.h"

using Mode = GrSamplerState::WrapMode;
using Filter = GrSamplerState::Filter;

struct GrTextureEffect::Sampling {
    GrSamplerState fHWSampler;
    ShaderMode fShaderModes[2] = {ShaderMode::kNone, ShaderMode::kNone};
    SkRect fShaderSubset = {0, 0, 0, 0};
    SkRect fShaderClamp  = {0, 0, 0, 0};
    float fBorder[4] = {0, 0, 0, 0};
    Sampling(GrSamplerState::Filter filter) : fHWSampler(filter) {}
    Sampling(const GrSurfaceProxy& proxy,
             GrSamplerState sampler,
             const SkRect&,
             const SkRect*,
             const float border[4],
             const GrCaps&,
             SkVector bilerpInset = {0.5f, 0.5f});
    inline bool hasBorderAlpha() const;
};

GrTextureEffect::Sampling::Sampling(const GrSurfaceProxy& proxy,
                                    GrSamplerState sampler,
                                    const SkRect& subset,
                                    const SkRect* domain,
                                    const float border[4],
                                    const GrCaps& caps,
                                    SkVector bilerpInset) {
    struct Span {
        float fA = 0.f, fB = 0.f;

        Span makeInset(float o) const {
            Span r = {fA + o, fB - o};
            if (r.fA > r.fB) {
                r.fA = r.fB = (r.fA + r.fB) / 2;
            }
            return r;
        }

        bool contains(Span r) const { return fA <= r.fA && fB >= r.fB; }
    };
    struct Result1D {
        ShaderMode fShaderMode;
        Span fShaderSubset;
        Span fShaderClamp;
        Mode fHWMode;
    };

    auto type = proxy.asTextureProxy()->textureType();
    auto filter = sampler.filter();

    auto resolve = [&](int size, Mode mode, Span subset, Span domain, float bilerpInset) {
        Result1D r;
        bool canDoModeInHW = true;
        // TODO: Use HW border color when available.
        if (mode == Mode::kClampToBorder &&
            (!caps.clampToBorderSupport() || border[0] || border[1] || border[2] || border[3])) {
            canDoModeInHW = false;
        } else if (mode != Mode::kClamp && !caps.npotTextureTileSupport() && !SkIsPow2(size)) {
            canDoModeInHW = false;
        } else if (type != GrTextureType::k2D &&
                   !(mode == Mode::kClamp || mode == Mode::kClampToBorder)) {
            canDoModeInHW = false;
        }
        if (canDoModeInHW && size > 0 && subset.fA <= 0 && subset.fB >= size) {
            r.fShaderMode = ShaderMode::kNone;
            r.fHWMode = mode;
            r.fShaderSubset = r.fShaderClamp = {0, 0};
            return r;
        }

        r.fShaderSubset = subset;
        bool domainIsSafe = false;
        if (filter == Filter::kNearest) {
            Span isubset{sk_float_floor(subset.fA), sk_float_ceil(subset.fB)};
            if (domain.fA > isubset.fA && domain.fB < isubset.fB) {
                domainIsSafe = true;
            }
            // This inset prevents sampling neighboring texels that could occur when
            // texture coords fall exactly at texel boundaries (depending on precision
            // and GPU-specific snapping at the boundary).
            r.fShaderClamp = isubset.makeInset(0.5f);
        } else {
            r.fShaderClamp = subset.makeInset(bilerpInset);
            if (r.fShaderClamp.contains(domain)) {
                domainIsSafe = true;
            }
        }
        if (domainIsSafe) {
            // The domain of coords that will be used won't access texels outside of the subset.
            // So the wrap mode effectively doesn't matter. We use kClamp since it is always
            // supported.
            r.fShaderMode = ShaderMode::kNone;
            r.fHWMode = Mode::kClamp;
            r.fShaderSubset = r.fShaderClamp = {0, 0};
            return r;
        }
        r.fShaderMode = GetShaderMode(mode, filter);
        r.fHWMode = Mode::kClamp;
        return r;
    };

    SkISize dim = proxy.isFullyLazy() ? SkISize{-1, -1} : proxy.backingStoreDimensions();

    Span subsetX{subset.fLeft, subset.fRight};
    auto domainX = domain ? Span{domain->fLeft, domain->fRight}
                          : Span{SK_FloatNegativeInfinity, SK_FloatInfinity};
    auto x = resolve(dim.width(), sampler.wrapModeX(), subsetX, domainX, bilerpInset.fX);

    Span subsetY{subset.fTop, subset.fBottom};
    auto domainY = domain ? Span{domain->fTop, domain->fBottom}
                          : Span{SK_FloatNegativeInfinity, SK_FloatInfinity};
    auto y = resolve(dim.height(), sampler.wrapModeY(), subsetY, domainY, bilerpInset.fY);

    fHWSampler = {x.fHWMode, y.fHWMode, filter};
    fShaderModes[0] = x.fShaderMode;
    fShaderModes[1] = y.fShaderMode;
    fShaderSubset = {x.fShaderSubset.fA, y.fShaderSubset.fA,
                     x.fShaderSubset.fB, y.fShaderSubset.fB};
    fShaderClamp = {x.fShaderClamp.fA, y.fShaderClamp.fA,
                    x.fShaderClamp.fB, y.fShaderClamp.fB};
    std::copy_n(border, 4, fBorder);
}

bool GrTextureEffect::Sampling::hasBorderAlpha() const {
    if (fHWSampler.wrapModeX() == GrSamplerState::WrapMode::kClampToBorder ||
        fHWSampler.wrapModeY() == GrSamplerState::WrapMode::kClampToBorder) {
        return true;
    }
    if (ShaderModeIsClampToBorder(fShaderModes[0]) || ShaderModeIsClampToBorder(fShaderModes[1])) {
        return fBorder[3] < 1.f;
    }
    return false;
}

static void get_matrix(const SkMatrix& preMatrix, const GrSurfaceProxyView& view,
                       SkMatrix* outMatrix, bool* outLazyProxyNormalization) {
    SkMatrix combined = preMatrix;
    bool normalize = view.proxy()->backendFormat().textureType() != GrTextureType::kRectangle;
    if (normalize) {
        if (view.proxy()->isFullyLazy()) {
            *outLazyProxyNormalization = true;
        } else {
            SkMatrixPriv::PostIDiv(&combined, view.proxy()->backingStoreDimensions().fWidth,
                                              view.proxy()->backingStoreDimensions().fHeight);
            *outLazyProxyNormalization = false;
        }
    } else {
        *outLazyProxyNormalization = false;
    }
    if (view.origin() == kBottomLeft_GrSurfaceOrigin) {
        if (normalize) {
            // combined.postScale(1,-1);
            // combined.postTranslate(0,1);
            combined.set(SkMatrix::kMSkewY,
                         combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
            combined.set(SkMatrix::kMScaleY,
                         combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
            combined.set(SkMatrix::kMTransY,
                         combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
        } else {
            // combined.postScale(1, -1);
            // combined.postTranslate(0,1);
            SkScalar h = view.proxy()->backingStoreDimensions().fHeight;
            combined.set(SkMatrix::kMSkewY,
                         h * combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
            combined.set(SkMatrix::kMScaleY,
                         h * combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
            combined.set(SkMatrix::kMTransY,
                         h * combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
        }
    }
    *outMatrix = combined;
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
                                                           SkAlphaType alphaType,
                                                           const SkMatrix& matrix,
                                                           Filter filter) {
    SkMatrix final;
    bool lazyProxyNormalization;
    get_matrix(matrix, view, &final, &lazyProxyNormalization);
    return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
                                                      new GrTextureEffect(std::move(view),
                                                                          alphaType,
                                                                          Sampling(filter),
                                                                          lazyProxyNormalization)));
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
                                                           SkAlphaType alphaType,
                                                           const SkMatrix& matrix,
                                                           GrSamplerState sampler,
                                                           const GrCaps& caps,
                                                           const float border[4]) {
    Sampling sampling(*view.proxy(), sampler, SkRect::Make(view.proxy()->dimensions()), nullptr,
                      border, caps);
    SkMatrix final;
    bool lazyProxyNormalization;
    get_matrix(matrix, view, &final, &lazyProxyNormalization);
    return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
                                                      new GrTextureEffect(std::move(view),
                                                                          alphaType,
                                                                          sampling,
                                                                          lazyProxyNormalization)));
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
                                                                 SkAlphaType alphaType,
                                                                 const SkMatrix& matrix,
                                                                 GrSamplerState sampler,
                                                                 const SkRect& subset,
                                                                 const GrCaps& caps,
                                                                 const float border[4]) {
    Sampling sampling(*view.proxy(), sampler, subset, nullptr, border, caps);
    SkMatrix final;
    bool lazyProxyNormalization;
    get_matrix(matrix, view, &final, &lazyProxyNormalization);
    return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
                                                      new GrTextureEffect(std::move(view),
                                                                          alphaType,
                                                                          sampling,
                                                                          lazyProxyNormalization)));
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
                                                                 SkAlphaType alphaType,
                                                                 const SkMatrix& matrix,
                                                                 GrSamplerState sampler,
                                                                 const SkRect& subset,
                                                                 const SkRect& domain,
                                                                 const GrCaps& caps,
                                                                 const float border[4]) {
    Sampling sampling(*view.proxy(), sampler, subset, &domain, border, caps);
    SkMatrix final;
    bool lazyProxyNormalization;
    get_matrix(matrix, view, &final, &lazyProxyNormalization);
    return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
                                                      new GrTextureEffect(std::move(view),
                                                                          alphaType,
                                                                          sampling,
                                                                          lazyProxyNormalization)));
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeBilerpWithInset(
        GrSurfaceProxyView view,
        SkAlphaType alphaType,
        const SkMatrix& matrix,
        GrSamplerState::WrapMode wx,
        GrSamplerState::WrapMode wy,
        const SkRect& subset,
        SkVector inset,
        const GrCaps& caps,
        const float border[4]) {
    GrSamplerState sampler(wx, wy, GrSamplerState::Filter::kBilerp);
    Sampling sampling(*view.proxy(), sampler, subset, nullptr, border, caps, inset);
    SkMatrix final;
    bool lazyProxyNormalization;
    get_matrix(matrix, view, &final, &lazyProxyNormalization);
    return GrMatrixEffect::Make(
            final, std::unique_ptr<GrFragmentProcessor>(new GrTextureEffect(
                           std::move(view), alphaType, sampling, lazyProxyNormalization)));
}

GrTextureEffect::ShaderMode GrTextureEffect::GetShaderMode(GrSamplerState::WrapMode mode,
                                                           GrSamplerState::Filter filter) {
    switch (mode) {
        case GrSamplerState::WrapMode::kMirrorRepeat:
            return ShaderMode::kMirrorRepeat;
        case GrSamplerState::WrapMode::kClamp:
            return ShaderMode::kClamp;
        case GrSamplerState::WrapMode::kRepeat:
            switch (filter) {
                case GrSamplerState::Filter::kNearest:
                    return ShaderMode::kRepeatNearest;
                case GrSamplerState::Filter::kBilerp:
                    return ShaderMode::kRepeatBilerp;
                case GrSamplerState::Filter::kMipMap:
                    return ShaderMode::kRepeatMipMap;
            }
            SkUNREACHABLE;
        case GrSamplerState::WrapMode::kClampToBorder:
            return filter == GrSamplerState::Filter::kNearest ? ShaderMode::kClampToBorderNearest
                                                              : ShaderMode::kClampToBorderFilter;
    }
    SkUNREACHABLE;
}

inline bool GrTextureEffect::ShaderModeIsClampToBorder(ShaderMode m) {
    return m == ShaderMode::kClampToBorderNearest || m == ShaderMode::kClampToBorderFilter;
}

GrGLSLFragmentProcessor* GrTextureEffect::onCreateGLSLInstance() const {
    class Impl : public GrGLSLFragmentProcessor {
        UniformHandle fSubsetUni;
        UniformHandle fClampUni;
        UniformHandle fNormUni;
        UniformHandle fBorderUni;

    public:
        void emitCode(EmitArgs& args) override {
            auto& te = args.fFp.cast<GrTextureEffect>();
            auto* fb = args.fFragBuilder;

            if (te.fShaderModes[0] == ShaderMode::kNone &&
                te.fShaderModes[1] == ShaderMode::kNone) {
                fb->codeAppendf("%s = ", args.fOutputColor);
                if (te.fLazyProxyNormalization) {
                    const char* norm = nullptr;
                    fNormUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
                                                                kFloat4_GrSLType, "norm", &norm);
                    fb->appendTextureLookupAndBlend(args.fInputColor, SkBlendMode::kModulate,
                                                    args.fTexSamplers[0],
                                                    SkStringPrintf("%s * %s.zw", args.fSampleCoord,
                                                                   norm).c_str());
                } else {
                    fb->appendTextureLookupAndBlend(args.fInputColor, SkBlendMode::kModulate,
                                                    args.fTexSamplers[0], args.fSampleCoord);
                }
                fb->codeAppendf(";");
            } else {
                // Tripping this assert means we have a normalized fully lazy proxy with a
                // non-default ShaderMode. There's nothing fundamentally wrong with doing that, but
                // it hasn't been tested and this code path probably won't handle normalization
                // properly in that case.
                SkASSERT(!te.fLazyProxyNormalization);
                // Here is the basic flow of the various ShaderModes are implemented in a series of
                // steps. Not all the steps apply to all the modes. We try to emit only the steps
                // that are necessary for the given x/y shader modes.
                //
                // 0) Start with interpolated coordinates (unnormalize if doing anything
                //    complicated).
                // 1) Map the coordinates into the subset range [Repeat and MirrorRepeat], or pass
                //    through output of 0).
                // 2) Clamp the coordinates to a 0.5 inset of the subset rect [Clamp, Repeat, and
                //    MirrorRepeat always or ClampToBorder only when filtering] or pass through
                //    output of 1). The clamp rect collapses to a line or point it if the subset
                //    rect is less than one pixel wide/tall.
                // 3) Look up texture with output of 2) [All]
                // 3) Use the difference between 1) and 2) to apply filtering at edge [Repeat or
                //    ClampToBorder]. In the Repeat case this requires extra texture lookups on the
                //    other side of the subset (up to 3 more reads). Or if ClampToBorder and not
                //    filtering do a hard less than/greater than test with the subset rect.

                // Convert possible projective texture coordinates into non-homogeneous half2.
                fb->codeAppendf("float2 inCoord = %s;", args.fSampleCoord);

                const auto& m = te.fShaderModes;
                GrTextureType textureType = te.fSampler.proxy()->backendFormat().textureType();
                bool normCoords = textureType != GrTextureType::kRectangle;

                const char* borderName = nullptr;
                if (te.hasClampToBorderShaderMode()) {
                    fBorderUni = args.fUniformHandler->addUniform(
                            &te, kFragment_GrShaderFlag, kHalf4_GrSLType, "border", &borderName);
                }
                auto modeUsesSubset = [](ShaderMode m) {
                    switch (m) {
                        case ShaderMode::kNone:                     return false;
                        case ShaderMode::kClamp:                    return false;
                        case ShaderMode::kRepeatNearest:            return true;
                        case ShaderMode::kRepeatBilerp:             return true;
                        case ShaderMode::kRepeatMipMap:             return true;
                        case ShaderMode::kMirrorRepeat:             return true;
                        case ShaderMode::kClampToBorderNearest:     return true;
                        case ShaderMode::kClampToBorderFilter:      return true;
                    }
                    SkUNREACHABLE;
                };

                auto modeUsesClamp = [](ShaderMode m) {
                    switch (m) {
                        case ShaderMode::kNone:                     return false;
                        case ShaderMode::kClamp:                    return true;
                        case ShaderMode::kRepeatNearest:            return true;
                        case ShaderMode::kRepeatBilerp:             return true;
                        case ShaderMode::kRepeatMipMap:             return true;
                        case ShaderMode::kMirrorRepeat:             return true;
                        case ShaderMode::kClampToBorderNearest:     return false;
                        case ShaderMode::kClampToBorderFilter:      return true;
                    }
                    SkUNREACHABLE;
                };

                // To keep things a little simpler, when we have filtering logic in the shader we
                // operate on unnormalized texture coordinates. We will add a uniform that stores
                // {w, h, 1/w, 1/h} in a float4 below.
                auto modeRequiresUnormCoords = [](ShaderMode m) {
                  switch (m) {
                      case ShaderMode::kNone:                     return false;
                      case ShaderMode::kClamp:                    return false;
                      case ShaderMode::kRepeatNearest:            return false;
                      case ShaderMode::kRepeatBilerp:             return true;
                      case ShaderMode::kRepeatMipMap:             return true;
                      case ShaderMode::kMirrorRepeat:             return false;
                      case ShaderMode::kClampToBorderNearest:     return true;
                      case ShaderMode::kClampToBorderFilter:      return true;
                  }
                  SkUNREACHABLE;
                };

                bool useSubset[2] = {modeUsesSubset(m[0]), modeUsesSubset(m[1])};
                bool useClamp [2] = {modeUsesClamp (m[0]), modeUsesClamp (m[1])};

                const char* subsetName = nullptr;
                if (useSubset[0] || useSubset[1]) {
                    fSubsetUni = args.fUniformHandler->addUniform(
                            &te, kFragment_GrShaderFlag, kFloat4_GrSLType, "subset", &subsetName);
                }

                const char* clampName = nullptr;
                if (useClamp[0] || useClamp[1]) {
                    fClampUni = args.fUniformHandler->addUniform(
                            &te, kFragment_GrShaderFlag, kFloat4_GrSLType, "clamp", &clampName);
                }

                const char* norm = nullptr;
                if (normCoords && (modeRequiresUnormCoords(m[0]) ||
                                   modeRequiresUnormCoords(m[1]))) {
                    // TODO: Detect support for textureSize() or polyfill textureSize() in SkSL and
                    // always use?
                    fNormUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
                                                                kFloat4_GrSLType, "norm", &norm);
                    // TODO: Remove the normalization from the CoordTransform to skip unnormalizing
                    // step here.
                    fb->codeAppendf("inCoord *= %s.xy;", norm);
                }

                // Generates a string to read at a coordinate, normalizing coords if necessary.
                auto read = [&](const char* coord) {
                    SkString result;
                    SkString normCoord;
                    if (norm) {
                        normCoord.printf("(%s) * %s.zw", coord, norm);
                    } else {
                        normCoord = coord;
                    }
                    fb->appendTextureLookup(&result, args.fTexSamplers[0], normCoord.c_str());
                    return result;
                };

                // Implements coord wrapping for kRepeat and kMirrorRepeat
                auto subsetCoord = [&](ShaderMode mode,
                                       const char* coordSwizzle,
                                       const char* subsetStartSwizzle,
                                       const char* subsetStopSwizzle,
                                       const char* extraCoord,
                                       const char* coordWeight) {
                    switch (mode) {
                        // These modes either don't use the subset rect or don't need to map the
                        // coords to be within the subset.
                        case ShaderMode::kNone:
                        case ShaderMode::kClampToBorderNearest:
                        case ShaderMode::kClampToBorderFilter:
                        case ShaderMode::kClamp:
                            fb->codeAppendf("subsetCoord.%s = inCoord.%s;", coordSwizzle,
                                            coordSwizzle);
                            break;
                        case ShaderMode::kRepeatNearest:
                        case ShaderMode::kRepeatBilerp:
                            fb->codeAppendf(
                                    "subsetCoord.%s = mod(inCoord.%s - %s.%s, %s.%s - %s.%s) + "
                                    "%s.%s;",
                                    coordSwizzle, coordSwizzle, subsetName, subsetStartSwizzle,
                                    subsetName, subsetStopSwizzle, subsetName, subsetStartSwizzle,
                                    subsetName, subsetStartSwizzle);
                            break;
                        case ShaderMode::kRepeatMipMap:
                            // The approach here is to generate two sets of texture coords that
                            // are both "moving" at the same speed (if not direction) as
                            // inCoords. We accomplish that by using two out of phase mirror
                            // repeat coords. We will always sample using both coords but the
                            // read from the upward sloping one is selected using a weight
                            // that transitions from one set to the other near the reflection
                            // point. Like the coords, the weight is a saw-tooth function,
                            // phase-shifted, vertically translated, and then clamped to 0..1.
                            // TODO: Skip this and use textureGrad() when available.
                            SkASSERT(extraCoord);
                            SkASSERT(coordWeight);
                            fb->codeAppend("{");
                            fb->codeAppendf("float w = %s.%s - %s.%s;", subsetName,
                                            subsetStopSwizzle, subsetName, subsetStartSwizzle);
                            fb->codeAppendf("float w2 = 2 * w;");
                            fb->codeAppendf("float d = inCoord.%s - %s.%s;", coordSwizzle,
                                            subsetName, subsetStartSwizzle);
                            fb->codeAppend("float m = mod(d, w2);");
                            fb->codeAppend("float o = mix(m, w2 - m, step(w, m));");
                            fb->codeAppendf("subsetCoord.%s = o + %s.%s;", coordSwizzle, subsetName,
                                            subsetStartSwizzle);
                            fb->codeAppendf("%s = w - o + %s.%s;", extraCoord, subsetName,
                                            subsetStartSwizzle);
                            // coordWeight is used as the third param of mix() to blend between a
                            // sample taken using subsetCoord and a sample at extraCoord.
                            fb->codeAppend("float hw = w/2;");
                            fb->codeAppend("float n = mod(d - hw, w2);");
                            fb->codeAppendf(
                                    "%s = saturate(half(mix(n, w2 - n, step(w, n)) - hw + "
                                    "0.5));",
                                    coordWeight);
                            fb->codeAppend("}");
                            break;
                        case ShaderMode::kMirrorRepeat:
                            fb->codeAppend("{");
                            fb->codeAppendf("float w = %s.%s - %s.%s;", subsetName,
                                            subsetStopSwizzle, subsetName, subsetStartSwizzle);
                            fb->codeAppendf("float w2 = 2 * w;");
                            fb->codeAppendf("float m = mod(inCoord.%s - %s.%s, w2);", coordSwizzle,
                                            subsetName, subsetStartSwizzle);
                            fb->codeAppendf("subsetCoord.%s = mix(m, w2 - m, step(w, m)) + %s.%s;",
                                            coordSwizzle, subsetName, subsetStartSwizzle);
                            fb->codeAppend("}");
                            break;
                    }
                };

                auto clampCoord = [&](bool clamp,
                                      const char* coordSwizzle,
                                      const char* clampStartSwizzle,
                                      const char* clampStopSwizzle) {
                    if (clamp) {
                        fb->codeAppendf("clampedCoord.%s = clamp(subsetCoord.%s, %s.%s, %s.%s);",
                                        coordSwizzle, coordSwizzle, clampName, clampStartSwizzle,
                                        clampName, clampStopSwizzle);
                    } else {
                        fb->codeAppendf("clampedCoord.%s = subsetCoord.%s;", coordSwizzle,
                                        coordSwizzle);
                    }
                };

                // Insert vars for extra coords and blending weights for kRepeatMipMap.
                const char* extraRepeatCoordX  = nullptr;
                const char* repeatCoordWeightX = nullptr;
                const char* extraRepeatCoordY  = nullptr;
                const char* repeatCoordWeightY = nullptr;
                if (m[0] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppend("float extraRepeatCoordX; half repeatCoordWeightX;");
                    extraRepeatCoordX   = "extraRepeatCoordX";
                    repeatCoordWeightX  = "repeatCoordWeightX";
                }
                if (m[1] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppend("float extraRepeatCoordY; half repeatCoordWeightY;");
                    extraRepeatCoordY   = "extraRepeatCoordY";
                    repeatCoordWeightY  = "repeatCoordWeightY";
                }

                // Apply subset rect and clamp rect to coords.
                fb->codeAppend("float2 subsetCoord;");
                subsetCoord(te.fShaderModes[0], "x", "x", "z", extraRepeatCoordX,
                            repeatCoordWeightX);
                subsetCoord(te.fShaderModes[1], "y", "y", "w", extraRepeatCoordY,
                            repeatCoordWeightY);
                fb->codeAppend("float2 clampedCoord;");
                clampCoord(useClamp[0], "x", "x", "z");
                clampCoord(useClamp[1], "y", "y", "w");

                // Additional clamping for the extra coords for kRepeatMipMap.
                if (m[0] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppendf("extraRepeatCoordX = clamp(extraRepeatCoordX, %s.x, %s.z);",
                                    clampName, clampName);
                }
                if (m[1] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppendf("extraRepeatCoordY = clamp(extraRepeatCoordY, %s.y, %s.w);",
                                    clampName, clampName);
                }

                // Do the 2 or 4 texture reads for kRepeatMipMap and then apply the weight(s)
                // to blend between them. If neither direction is kRepeatMipMap do a single
                // read at clampedCoord.
                if (m[0] == ShaderMode::kRepeatMipMap && m[1] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppendf(
                            "half4 textureColor ="
                            "   mix(mix(%s, %s, repeatCoordWeightX),"
                            "       mix(%s, %s, repeatCoordWeightX),"
                            "       repeatCoordWeightY);",
                            read("clampedCoord").c_str(),
                            read("float2(extraRepeatCoordX, clampedCoord.y)").c_str(),
                            read("float2(clampedCoord.x, extraRepeatCoordY)").c_str(),
                            read("float2(extraRepeatCoordX, extraRepeatCoordY)").c_str());

                } else if (m[0] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppendf("half4 textureColor = mix(%s, %s, repeatCoordWeightX);",
                                    read("clampedCoord").c_str(),
                                    read("float2(extraRepeatCoordX, clampedCoord.y)").c_str());
                } else if (m[1] == ShaderMode::kRepeatMipMap) {
                    fb->codeAppendf("half4 textureColor = mix(%s, %s, repeatCoordWeightY);",
                                    read("clampedCoord").c_str(),
                                    read("float2(clampedCoord.x, extraRepeatCoordY)").c_str());
                } else {
                    fb->codeAppendf("half4 textureColor = %s;", read("clampedCoord").c_str());
                }

                // Strings for extra texture reads used only in kRepeatBilerp
                SkString repeatBilerpReadX;
                SkString repeatBilerpReadY;

                // Calculate the amount the coord moved for clamping. This will be used
                // to implement shader-based filtering for kClampToBorder and kRepeat.

                if (m[0] == ShaderMode::kRepeatBilerp || m[0] == ShaderMode::kClampToBorderFilter) {
                    fb->codeAppend("half errX = half(subsetCoord.x - clampedCoord.x);");
                    fb->codeAppendf("float repeatCoordX = errX > 0 ? %s.x : %s.z;", clampName,
                                    clampName);
                    repeatBilerpReadX = read("float2(repeatCoordX, clampedCoord.y)");
                }
                if (m[1] == ShaderMode::kRepeatBilerp || m[1] == ShaderMode::kClampToBorderFilter) {
                    fb->codeAppend("half errY = half(subsetCoord.y - clampedCoord.y);");
                    fb->codeAppendf("float repeatCoordY = errY > 0 ? %s.y : %s.w;", clampName,
                                    clampName);
                    repeatBilerpReadY = read("float2(clampedCoord.x, repeatCoordY)");
                }

                // Add logic for kRepeatBilerp. Do 1 or 3 more texture reads depending
                // on whether both modes are kRepeat and whether we're near a single subset edge
                // or a corner. Then blend the multiple reads using the err values calculated
                // above.
                const char* ifStr = "if";
                if (m[0] == ShaderMode::kRepeatBilerp && m[1] == ShaderMode::kRepeatBilerp) {
                    auto repeatBilerpReadXY = read("float2(repeatCoordX, repeatCoordY)");
                    fb->codeAppendf(
                            "if (errX != 0 && errY != 0) {"
                            "    errX = abs(errX);"
                            "    textureColor = mix(mix(textureColor, %s, errX),"
                            "                       mix(%s, %s, errX),"
                            "                       abs(errY));"
                            "}",
                            repeatBilerpReadX.c_str(), repeatBilerpReadY.c_str(),
                            repeatBilerpReadXY.c_str());
                    ifStr = "else if";
                }
                if (m[0] == ShaderMode::kRepeatBilerp) {
                    fb->codeAppendf(
                            "%s (errX != 0) {"
                            "    textureColor = mix(textureColor, %s, abs(errX));"
                            "}",
                            ifStr, repeatBilerpReadX.c_str());
                }
                if (m[1] == ShaderMode::kRepeatBilerp) {
                    fb->codeAppendf(
                            "%s (errY != 0) {"
                            "    textureColor = mix(textureColor, %s, abs(errY));"
                            "}",
                            ifStr, repeatBilerpReadY.c_str());
                }

                // Do soft edge shader filtering against border color for kClampToBorderFilter using
                // the err values calculated above.
                if (m[0] == ShaderMode::kClampToBorderFilter) {
                    fb->codeAppendf("textureColor = mix(textureColor, %s, min(abs(errX), 1));",
                                    borderName);
                }
                if (m[1] == ShaderMode::kClampToBorderFilter) {
                    fb->codeAppendf("textureColor = mix(textureColor, %s, min(abs(errY), 1));",
                                    borderName);
                }

                // Do hard-edge shader transition to border color for kClampToBorderNearest at the
                // subset boundaries. Snap the input coordinates to nearest neighbor (with an
                // epsilon) before comparing to the subset rect to avoid GPU interpolation errors
                if (m[0] == ShaderMode::kClampToBorderNearest) {
                    fb->codeAppendf(
                            "float snappedX = floor(inCoord.x + 0.001) + 0.5;"
                            "if (snappedX < %s.x || snappedX > %s.z) {"
                            "    textureColor = %s;"
                            "}",
                            subsetName, subsetName, borderName);
                }
                if (m[1] == ShaderMode::kClampToBorderNearest) {
                    fb->codeAppendf(
                            "float snappedY = floor(inCoord.y + 0.001) + 0.5;"
                            "if (snappedY < %s.y || snappedY > %s.w) {"
                            "    textureColor = %s;"
                            "}",
                            subsetName, subsetName, borderName);
                }
                fb->codeAppendf("%s = %s * textureColor;", args.fOutputColor, args.fInputColor);
            }
        }

    protected:
        void onSetData(const GrGLSLProgramDataManager& pdm,
                       const GrFragmentProcessor& fp) override {
            const auto& te = fp.cast<GrTextureEffect>();

            const float w = te.fSampler.peekTexture()->width();
            const float h = te.fSampler.peekTexture()->height();
            const auto& s = te.fSubset;
            const auto& c = te.fClamp;

            auto type = te.fSampler.peekTexture()->texturePriv().textureType();

            float norm[4] = {w, h, 1.f/w, 1.f/h};

            if (fNormUni.isValid()) {
                pdm.set4fv(fNormUni, 1, norm);
                SkASSERT(type != GrTextureType::kRectangle);
            }

            auto pushRect = [&](float rect[4], UniformHandle uni) {
                if (te.fSampler.view().origin() == kBottomLeft_GrSurfaceOrigin) {
                    rect[1] = h - rect[1];
                    rect[3] = h - rect[3];
                    std::swap(rect[1], rect[3]);
                }
                if (!fNormUni.isValid() && type != GrTextureType::kRectangle) {
                    rect[0] *= norm[2];
                    rect[2] *= norm[2];
                    rect[1] *= norm[3];
                    rect[3] *= norm[3];
                }
                pdm.set4fv(uni, 1, rect);
            };

            if (fSubsetUni.isValid()) {
                float subset[] = {s.fLeft, s.fTop, s.fRight, s.fBottom};
                pushRect(subset, fSubsetUni);
            }
            if (fClampUni.isValid()) {
                float subset[] = {c.fLeft, c.fTop, c.fRight, c.fBottom};
                pushRect(subset, fClampUni);
            }
            if (fBorderUni.isValid()) {
                pdm.set4fv(fBorderUni, 1, te.fBorder);
            }
        }
    };
    return new Impl;
}

void GrTextureEffect::onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const {
    auto m0 = static_cast<uint32_t>(fShaderModes[0]);
    auto m1 = static_cast<uint32_t>(fShaderModes[1]);
    b->add32((m0 << 16) | m1);
}

bool GrTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
    auto& that = other.cast<GrTextureEffect>();
    if (fShaderModes[0] != that.fShaderModes[0] || fShaderModes[1] != that.fShaderModes[1]) {
        return false;
    }
    if (fSubset != that.fSubset) {
        return false;
    }
    if (this->hasClampToBorderShaderMode() && !std::equal(fBorder, fBorder + 4, that.fBorder)) {
        return false;
    }
    return true;
}

GrTextureEffect::GrTextureEffect(GrSurfaceProxyView view, SkAlphaType alphaType,
                                 const Sampling& sampling, bool lazyProxyNormalization)
        : GrFragmentProcessor(kGrTextureEffect_ClassID,
                              ModulateForSamplerOptFlags(alphaType, sampling.hasBorderAlpha()))
        , fSampler(std::move(view), sampling.fHWSampler)
        , fSubset(sampling.fShaderSubset)
        , fClamp(sampling.fShaderClamp)
        , fShaderModes{sampling.fShaderModes[0], sampling.fShaderModes[1]}
        , fLazyProxyNormalization(lazyProxyNormalization) {
    // We always compare the range even when it isn't used so assert we have canonical don't care
    // values.
    SkASSERT(fShaderModes[0] != ShaderMode::kNone || (fSubset.fLeft == 0 && fSubset.fRight == 0));
    SkASSERT(fShaderModes[1] != ShaderMode::kNone || (fSubset.fTop == 0 && fSubset.fBottom == 0));
    this->setTextureSamplerCnt(1);
    this->setUsesSampleCoordsDirectly();
    std::copy_n(sampling.fBorder, 4, fBorder);
}

GrTextureEffect::GrTextureEffect(const GrTextureEffect& src)
        : INHERITED(kGrTextureEffect_ClassID, src.optimizationFlags())
        , fSampler(src.fSampler)
        , fSubset(src.fSubset)
        , fClamp(src.fClamp)
        , fShaderModes{src.fShaderModes[0], src.fShaderModes[1]}
        , fLazyProxyNormalization(src.fLazyProxyNormalization) {
    std::copy_n(src.fBorder, 4, fBorder);
    this->setTextureSamplerCnt(1);
    this->setUsesSampleCoordsDirectly();
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrTextureEffect(*this));
}

const GrFragmentProcessor::TextureSampler& GrTextureEffect::onTextureSampler(int) const {
    return fSampler;
}

GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrTextureEffect);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::TestCreate(GrProcessorTestData* testData) {
    auto [view, ct, at] = testData->randomView();
    Mode wrapModes[2];
    GrTest::TestWrapModes(testData->fRandom, wrapModes);

    Filter filter;
    if (view.asTextureProxy()->mipMapped() == GrMipMapped::kYes) {
        switch (testData->fRandom->nextULessThan(3)) {
            case 0:
                filter = Filter::kNearest;
                break;
            case 1:
                filter = Filter::kBilerp;
                break;
            default:
                filter = Filter::kMipMap;
                break;
        }
    } else {
        filter = testData->fRandom->nextBool() ? Filter::kBilerp : Filter::kNearest;
    }
    GrSamplerState params(wrapModes, filter);

    const SkMatrix& matrix = GrTest::TestMatrix(testData->fRandom);
    return GrTextureEffect::Make(std::move(view), at, matrix, params, *testData->caps());
}
#endif
