/*
 * 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/ganesh/effects/GrTextureEffect.h"

#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrTypes.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkMath.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/base/SkRandom.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/KeyBuilder.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrTestUtils.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/effects/GrMatrixEffect.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLProgramDataManager.h"
#include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"

#include <algorithm>
#include <utility>

enum SkAlphaType : int;
struct GrShaderCaps;

using Wrap = GrSamplerState::WrapMode;
using Filter = GrSamplerState::Filter;
using MipmapMode = GrSamplerState::MipmapMode;

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(Filter filter, MipmapMode mm) : fHWSampler(filter, mm) {}
    Sampling(const GrSurfaceProxy& proxy,
             GrSamplerState wrap,
             const SkRect&,
             const SkRect*,
             const float border[4],
             bool alwaysUseShaderTileMode,
             const GrCaps&,
             SkVector linearFilterInset = {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],
                                    bool alwaysUseShaderTileMode,
                                    const GrCaps& caps,
                                    SkVector linearFilterInset) {
    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 = ShaderMode::kNone;
        Span fShaderSubset     = {};
        Span fShaderClamp      = {};
        Wrap fHWWrap           = Wrap::kClamp;
    };

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

    auto canDoWrapInHW = [&](int size, Wrap wrap) {
        if (alwaysUseShaderTileMode) {
            return false;
        }
        // TODO: Use HW border color when available.
        if (wrap == Wrap::kClampToBorder &&
            (!caps.clampToBorderSupport() || border[0] || border[1] || border[2] || border[3])) {
            return false;
        }
        if (wrap != Wrap::kClamp && !caps.npotTextureTileSupport() && !SkIsPow2(size)) {
            return false;
        }
        if (type != GrTextureType::k2D &&
                   !(wrap == Wrap::kClamp || wrap == Wrap::kClampToBorder)) {
            return false;
        }
        return true;
    };

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

    // TODO: Right now if we use shader based subsetting for any reason we just completely drop
    // aniso. Longer term allow shader subsetting, reusing the special repeat mode LOD selection
    // logic for mip maps, and simply don't attempt to restrict ansiso's computed samples to the
    // subset. That is use "subsetting" but not "clamping"/insetting in terms of the shader gen
    // logic.
    bool aniso = sampler.isAniso();
    SkASSERT(!aniso || caps.anisoSupport());
    if (aniso) {
        bool anisoSubset = !subset.contains(proxy.backingStoreBoundsRect()) &&
                           (!domain || !subset.contains(*domain));
        bool needsShaderWrap = !canDoWrapInHW(dim.width(),  sampler.wrapModeX()) ||
                               !canDoWrapInHW(dim.height(), sampler.wrapModeY());
        if (needsShaderWrap || anisoSubset) {
            MipmapMode newMM = proxy.asTextureProxy()->mipmapped() == GrMipmapped::kYes
                                    ? MipmapMode::kLinear
                                    : MipmapMode::kNone;
            sampler = GrSamplerState(sampler.wrapModeX(),
                                     sampler.wrapModeY(),
                                     SkFilterMode::kLinear,
                                     newMM);
            aniso = false;
        }
    }

    auto resolve = [&](int size, Wrap wrap, Span subset, Span domain, float linearFilterInset) {
        Result1D r;
        bool canDoModeInHW = canDoWrapInHW(size, wrap);
        if (canDoModeInHW && size > 0 && subset.fA <= 0 && subset.fB >= size) {
            r.fShaderMode = ShaderMode::kNone;
            r.fHWWrap = wrap;
            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(linearFilterInset);
            if (r.fShaderClamp.contains(domain)) {
                domainIsSafe = true;
            }
        }
        if (!alwaysUseShaderTileMode && 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.fHWWrap = Wrap::kClamp;
            r.fShaderSubset = r.fShaderClamp = {0, 0};
            return r;
        }
        r.fShaderMode = GetShaderMode(wrap, filter, mm);
        r.fHWWrap = Wrap::kClamp;
        return r;
    };

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

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

    fHWSampler = aniso ? GrSamplerState::Aniso(x.fHWWrap,
                                               y.fHWWrap,
                                               sampler.maxAniso(),
                                               proxy.asTextureProxy()->mipmapped())
                       : GrSamplerState{x.fHWWrap, y.fHWWrap, filter, mm};
    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() == Wrap::kClampToBorder ||
        fHWSampler.wrapModeY() == Wrap::kClampToBorder) {
        return true;
    }
    if (ShaderModeIsClampToBorder(fShaderModes[0]) || ShaderModeIsClampToBorder(fShaderModes[1])) {
        return fBorder[3] < 1.f;
    }
    return false;
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
                                                           SkAlphaType alphaType,
                                                           const SkMatrix& matrix,
                                                           Filter filter,
                                                           MipmapMode mm) {
    Sampling sampling = Sampling(filter, mm);
    std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
                                                                alphaType,
                                                                sampling));
    return GrMatrixEffect::Make(matrix, std::move(te));
}

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,
                      false,
                      caps);
    std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
                                                                alphaType,
                                                                sampling));
    return GrMatrixEffect::Make(matrix, std::move(te));
}

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],
                                                                 bool alwaysUseShaderTileMode) {
    Sampling sampling(*view.proxy(),
                      sampler,
                      subset,
                      nullptr,
                      border,
                      alwaysUseShaderTileMode,
                      caps);
    std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
                                                                alphaType,
                                                                sampling));
    return GrMatrixEffect::Make(matrix, std::move(te));
}

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, false, caps);
    std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
                                                                alphaType,
                                                                sampling));
    return GrMatrixEffect::Make(matrix, std::move(te));
}

std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeCustomLinearFilterInset(
        GrSurfaceProxyView view,
        SkAlphaType alphaType,
        const SkMatrix& matrix,
        Wrap wx,
        Wrap wy,
        const SkRect& subset,
        const SkRect* domain,
        SkVector inset,
        const GrCaps& caps,
        const float border[4]) {
    GrSamplerState sampler(wx, wy, Filter::kLinear);
    Sampling sampling(*view.proxy(), sampler, subset, domain, border, false, caps, inset);
    std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
                                                                alphaType,
                                                                sampling));
    return GrMatrixEffect::Make(matrix, std::move(te));
}

SkMatrix GrTextureEffect::coordAdjustmentMatrix() const {
    SkMatrix m;
    GrTexture* texture = this->texture();
    SkISize d = texture->dimensions();
    if (this->matrixEffectShouldNormalize()) {
        if (fView.origin() == kBottomLeft_GrSurfaceOrigin) {
            m.setScaleTranslate(1.f / d.width(), -1.f / d.height(), 0, 1);
        } else {
            m.setScale(1.f / d.width(), 1.f / d.height());
        }
    } else {
        if (fView.origin() == kBottomLeft_GrSurfaceOrigin) {
            m.setScaleTranslate(1.f, -1.f, 0, d.height());
        }
    }
    return m;
}

GrTextureEffect::ShaderMode GrTextureEffect::GetShaderMode(Wrap wrap,
                                                           Filter filter,
                                                           MipmapMode mm) {
    switch (wrap) {
        case Wrap::kMirrorRepeat:
            return ShaderMode::kMirrorRepeat;
        case Wrap::kClamp:
            return ShaderMode::kClamp;
        case Wrap::kRepeat:
            switch (mm) {
                case MipmapMode::kNone:
                    switch (filter) {
                        case Filter::kNearest: return ShaderMode::kRepeat_Nearest_None;
                        case Filter::kLinear:  return ShaderMode::kRepeat_Linear_None;
                    }
                    SkUNREACHABLE;
                case MipmapMode::kNearest:
                case MipmapMode::kLinear:
                    switch (filter) {
                        case Filter::kNearest: return ShaderMode::kRepeat_Nearest_Mipmap;
                        case Filter::kLinear:  return ShaderMode::kRepeat_Linear_Mipmap;
                    }
                    SkUNREACHABLE;
            }
            SkUNREACHABLE;
        case Wrap::kClampToBorder:
            return filter == Filter::kNearest ? ShaderMode::kClampToBorder_Nearest
                                              : ShaderMode::kClampToBorder_Filter;
    }
    SkUNREACHABLE;
}

inline bool GrTextureEffect::ShaderModeIsClampToBorder(ShaderMode m) {
    return m == ShaderMode::kClampToBorder_Nearest || m == ShaderMode::kClampToBorder_Filter;
}

bool GrTextureEffect::ShaderModeRequiresUnormCoord(ShaderMode m) {
    switch (m) {
        case ShaderMode::kNone:                     return false;
        case ShaderMode::kClamp:                    return false;
        case ShaderMode::kRepeat_Nearest_None:      return false;
        case ShaderMode::kRepeat_Linear_None:       return true;
        case ShaderMode::kRepeat_Nearest_Mipmap:    return true;
        case ShaderMode::kRepeat_Linear_Mipmap:     return true;
        case ShaderMode::kMirrorRepeat:             return false;
        case ShaderMode::kClampToBorder_Nearest:    return true;
        case ShaderMode::kClampToBorder_Filter:     return true;
    }
    SkUNREACHABLE;
}

void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
    using ShaderMode = GrTextureEffect::ShaderMode;

    auto& te = args.fFp.cast<GrTextureEffect>();
    auto* fb = args.fFragBuilder;

    if (te.fShaderModes[0] == ShaderMode::kNone &&
        te.fShaderModes[1] == ShaderMode::kNone) {
        fb->codeAppendf("return ");
        fb->appendTextureLookup(fSamplerHandle, args.fSampleCoord);
        fb->codeAppendf(";");
    } else {
        // 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;

        const char* borderName = nullptr;
        if (te.hasClampToBorderShaderMode()) {
            fBorderUni = args.fUniformHandler->addUniform(
                    &te, kFragment_GrShaderFlag, SkSLType::kHalf4, "border", &borderName);
        }
        auto modeUsesSubset = [](ShaderMode m) {
          switch (m) {
              case ShaderMode::kNone:                     return false;
              case ShaderMode::kClamp:                    return false;
              case ShaderMode::kRepeat_Nearest_None:      return true;
              case ShaderMode::kRepeat_Linear_None:       return true;
              case ShaderMode::kRepeat_Nearest_Mipmap:    return true;
              case ShaderMode::kRepeat_Linear_Mipmap:     return true;
              case ShaderMode::kMirrorRepeat:             return true;
              case ShaderMode::kClampToBorder_Nearest:    return true;
              case ShaderMode::kClampToBorder_Filter:     return true;
          }
          SkUNREACHABLE;
        };

        auto modeUsesClamp = [](ShaderMode m) {
          switch (m) {
              case ShaderMode::kNone:                     return false;
              case ShaderMode::kClamp:                    return true;
              case ShaderMode::kRepeat_Nearest_None:      return true;
              case ShaderMode::kRepeat_Linear_None:       return true;
              case ShaderMode::kRepeat_Nearest_Mipmap:    return true;
              case ShaderMode::kRepeat_Linear_Mipmap:     return true;
              case ShaderMode::kMirrorRepeat:             return true;
              case ShaderMode::kClampToBorder_Nearest:    return false;
              case ShaderMode::kClampToBorder_Filter:     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, SkSLType::kFloat4, "subset", &subsetName);
        }

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

        bool unormCoordsRequiredForShaderMode = ShaderModeRequiresUnormCoord(m[0]) ||
                                                ShaderModeRequiresUnormCoord(m[1]);
        // We should not pre-normalize the input coords with GrMatrixEffect if we're going to
        // operate on unnormalized coords and then normalize after the shader mode.
        SkASSERT(!(unormCoordsRequiredForShaderMode && te.matrixEffectShouldNormalize()));
        bool sampleCoordsMustBeNormalized =
                te.fView.asTextureProxy()->textureType() != GrTextureType::kRectangle;

        const char* idims = nullptr;
        if (unormCoordsRequiredForShaderMode && sampleCoordsMustBeNormalized) {
            // TODO: Detect support for textureSize() or polyfill textureSize() in SkSL and
            // always use?
            fIDimsUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
                                                         SkSLType::kFloat2, "idims", &idims);
        }

        // Generates a string to read at a coordinate, normalizing coords if necessary.
        auto read = [&](const char* coord) {
            SkString result;
            SkString normCoord;
            if (idims) {
                normCoord.printf("(%s) * %s", coord, idims);
            } else {
                normCoord = coord;
            }
            fb->appendTextureLookup(&result, fSamplerHandle, 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::kClampToBorder_Nearest:
                case ShaderMode::kClampToBorder_Filter:
                case ShaderMode::kClamp:
                    fb->codeAppendf("subsetCoord.%s = inCoord.%s;", coordSwizzle, coordSwizzle);
                    break;
                case ShaderMode::kRepeat_Nearest_None:
                case ShaderMode::kRepeat_Linear_None:
                    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::kRepeat_Nearest_Mipmap:
                case ShaderMode::kRepeat_Linear_Mipmap:
                    // 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 repeat + mip map.
        const char* extraRepeatCoordX  = nullptr;
        const char* repeatCoordWeightX = nullptr;
        const char* extraRepeatCoordY  = nullptr;
        const char* repeatCoordWeightY = nullptr;

        bool mipmapRepeatX = m[0] == ShaderMode::kRepeat_Nearest_Mipmap ||
                             m[0] == ShaderMode::kRepeat_Linear_Mipmap;
        bool mipmapRepeatY = m[1] == ShaderMode::kRepeat_Nearest_Mipmap ||
                             m[1] == ShaderMode::kRepeat_Linear_Mipmap;

        if (mipmapRepeatX || mipmapRepeatY) {
            fb->codeAppend("float2 extraRepeatCoord;");
        }
        if (mipmapRepeatX) {
            fb->codeAppend("half repeatCoordWeightX;");
            extraRepeatCoordX   = "extraRepeatCoord.x";
            repeatCoordWeightX  = "repeatCoordWeightX";
        }
        if (mipmapRepeatY) {
            fb->codeAppend("half repeatCoordWeightY;");
            extraRepeatCoordY   = "extraRepeatCoord.y";
            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;");
        if (useClamp[0] == useClamp[1]) {
            clampCoord(useClamp[0], "", ".xy", ".zw");
        } else {
            clampCoord(useClamp[0], ".x", ".x", ".z");
            clampCoord(useClamp[1], ".y", ".y", ".w");
        }
        // Additional clamping for the extra coords for kRepeat with mip maps.
        if (mipmapRepeatX && mipmapRepeatY) {
            fb->codeAppendf("extraRepeatCoord = clamp(extraRepeatCoord, %s.xy, %s.zw);",
                            clampName, clampName);
        } else if (mipmapRepeatX) {
            fb->codeAppendf("extraRepeatCoord.x = clamp(extraRepeatCoord.x, %s.x, %s.z);",
                            clampName, clampName);
        } else if (mipmapRepeatY) {
            fb->codeAppendf("extraRepeatCoord.y = clamp(extraRepeatCoord.y, %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 repeat or not using mip maps do a single
        // read at clampedCoord.
        if (mipmapRepeatX && mipmapRepeatY) {
            fb->codeAppendf(
                    "half4 textureColor ="
                    "   mix(mix(%s, %s, repeatCoordWeightX),"
                    "       mix(%s, %s, repeatCoordWeightX),"
                    "       repeatCoordWeightY);",
                    read("clampedCoord").c_str(),
                    read("float2(extraRepeatCoord.x, clampedCoord.y)").c_str(),
                    read("float2(clampedCoord.x, extraRepeatCoord.y)").c_str(),
                    read("float2(extraRepeatCoord.x, extraRepeatCoord.y)").c_str());

        } else if (mipmapRepeatX) {
            fb->codeAppendf("half4 textureColor = mix(%s, %s, repeatCoordWeightX);",
                            read("clampedCoord").c_str(),
                            read("float2(extraRepeatCoord.x, clampedCoord.y)").c_str());
        } else if (mipmapRepeatY) {
            fb->codeAppendf("half4 textureColor = mix(%s, %s, repeatCoordWeightY);",
                            read("clampedCoord").c_str(),
                            read("float2(clampedCoord.x, extraRepeatCoord.y)").c_str());
        } else {
            fb->codeAppendf("half4 textureColor = %s;", read("clampedCoord").c_str());
        }

        // Strings for extra texture reads used only in kRepeatLinear
        SkString repeatLinearReadX;
        SkString repeatLinearReadY;

        // Calculate the amount the coord moved for clamping. This will be used
        // to implement shader-based filtering for kClampToBorder and kRepeat.
        bool repeatLinearFilterX = m[0] == ShaderMode::kRepeat_Linear_None ||
                                   m[0] == ShaderMode::kRepeat_Linear_Mipmap;
        bool repeatLinearFilterY = m[1] == ShaderMode::kRepeat_Linear_None ||
                                   m[1] == ShaderMode::kRepeat_Linear_Mipmap;
        if (repeatLinearFilterX || m[0] == ShaderMode::kClampToBorder_Filter) {
            fb->codeAppend("half errX = half(subsetCoord.x - clampedCoord.x);");
            if (repeatLinearFilterX) {
                fb->codeAppendf("float repeatCoordX = errX > 0 ? %s.x : %s.z;",
                                clampName, clampName);
                repeatLinearReadX = read("float2(repeatCoordX, clampedCoord.y)");
            }
        }
        if (repeatLinearFilterY || m[1] == ShaderMode::kClampToBorder_Filter) {
            fb->codeAppend("half errY = half(subsetCoord.y - clampedCoord.y);");
            if (repeatLinearFilterY) {
                fb->codeAppendf("float repeatCoordY = errY > 0 ? %s.y : %s.w;",
                                clampName, clampName);
                repeatLinearReadY = read("float2(clampedCoord.x, repeatCoordY)");
            }
        }

        // Add logic for kRepeat + linear filter. 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 (repeatLinearFilterX && repeatLinearFilterY) {
            auto repeatLinearReadXY = 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));"
                    "}",
                    repeatLinearReadX.c_str(), repeatLinearReadY.c_str(),
                    repeatLinearReadXY.c_str());
            ifStr = "else if";
        }
        if (repeatLinearFilterX) {
            fb->codeAppendf(
                    "%s (errX != 0) {"
                    "    textureColor = mix(textureColor, %s, abs(errX));"
                    "}",
                    ifStr, repeatLinearReadX.c_str());
        }
        if (repeatLinearFilterY) {
            fb->codeAppendf(
                    "%s (errY != 0) {"
                    "    textureColor = mix(textureColor, %s, abs(errY));"
                    "}",
                    ifStr, repeatLinearReadY.c_str());
        }

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

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

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

    auto type = te.texture()->textureType();

    float idims[2] = {1.f/w, 1.f/h};

    if (fIDimsUni.isValid()) {
        pdm.set2fv(fIDimsUni, 1, idims);
        SkASSERT(type != GrTextureType::kRectangle);
    }

    auto pushRect = [&](float rect[4], UniformHandle uni) {
        if (te.view().origin() == kBottomLeft_GrSurfaceOrigin) {
            rect[1] = h - rect[1];
            rect[3] = h - rect[3];
            std::swap(rect[1], rect[3]);
        }
        if (!fIDimsUni.isValid() && type != GrTextureType::kRectangle) {
            rect[0] *= idims[0];
            rect[2] *= idims[0];
            rect[1] *= idims[1];
            rect[3] *= idims[1];
        }
        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);
    }
}

std::unique_ptr<GrFragmentProcessor::ProgramImpl> GrTextureEffect::onMakeProgramImpl() const {
    return std::make_unique<Impl>();
}

void GrTextureEffect::onAddToKey(const GrShaderCaps&, skgpu::KeyBuilder* b) const {
    auto m0 = static_cast<uint32_t>(fShaderModes[0]);
    b->addBits(8, m0, "shaderMode0");

    auto m1 = static_cast<uint32_t>(fShaderModes[1]);
    b->addBits(8, m1, "shaderMode1");
}

bool GrTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
    auto& that = other.cast<GrTextureEffect>();
    if (fView != that.fView) {
        return false;
    }
    if (fSamplerState != that.fSamplerState) {
        return false;
    }
    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;
}

bool GrTextureEffect::matrixEffectShouldNormalize() const {
    return fView.asTextureProxy()->textureType() != GrTextureType::kRectangle &&
           !ShaderModeRequiresUnormCoord(fShaderModes[0])                     &&
           !ShaderModeRequiresUnormCoord(fShaderModes[1]);
}

GrTextureEffect::GrTextureEffect(GrSurfaceProxyView view,
                                 SkAlphaType alphaType,
                                 const Sampling& sampling)
        : GrFragmentProcessor(kGrTextureEffect_ClassID,
                              ModulateForSamplerOptFlags(alphaType, sampling.hasBorderAlpha()))
        , fView(std::move(view))
        , fSamplerState(sampling.fHWSampler)
        , fSubset(sampling.fShaderSubset)
        , fClamp(sampling.fShaderClamp)
        , fShaderModes{sampling.fShaderModes[0], sampling.fShaderModes[1]} {
    // 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->setUsesSampleCoordsDirectly();
    std::copy_n(sampling.fBorder, 4, fBorder);
}

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

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

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

    Filter filter = testData->fRandom->nextBool() ? Filter::kLinear : Filter::kNearest;
    MipmapMode mm = MipmapMode::kNone;
    if (view.asTextureProxy()->mipmapped() == GrMipmapped::kYes) {
        mm = testData->fRandom->nextBool() ? MipmapMode::kLinear : MipmapMode::kNone;
    }
    GrSamplerState params(wrapModes, filter, mm);

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