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

/**************************************************************************************************
 *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
 **************************************************************************************************/
#include "GrRectBlurEffect.h"

#include "include/gpu/GrTexture.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"
class GrGLSLRectBlurEffect : public GrGLSLFragmentProcessor {
public:
    GrGLSLRectBlurEffect() {}
    void emitCode(EmitArgs& args) override {
        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
        const GrRectBlurEffect& _outer = args.fFp.cast<GrRectBlurEffect>();
        (void)_outer;
        auto rect = _outer.rect;
        (void)rect;
        auto sigma = _outer.sigma;
        (void)sigma;
        highPrecision = ((((abs(rect.left()) > 16000.0 || abs(rect.top()) > 16000.0) ||
                           abs(rect.right()) > 16000.0) ||
                          abs(rect.bottom()) > 16000.0) ||
                         abs(rect.right() - rect.left()) > 16000.0) ||
                        abs(rect.bottom() - rect.top()) > 16000.0;
        rectVar =
                args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType, "rect");
        if (!highPrecision) {
            proxyRectHalfVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
                                                                kHalf4_GrSLType, "proxyRectHalf");
        }
        if (highPrecision) {
            proxyRectFloatVar = args.fUniformHandler->addUniform(
                    kFragment_GrShaderFlag, kFloat4_GrSLType, "proxyRectFloat");
        }
        profileSizeVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
                                                          "profileSize");
        fragBuilder->codeAppendf(
                "/* key */ bool highPrecision = %s;\n@if (highPrecision) {\n    float2 "
                "translatedPos = sk_FragCoord.xy - %s.xy;\n    float width = %s.z - %s.x;\n    "
                "float height = %s.w - %s.y;\n    float2 smallDims = float2(width - float(%s), "
                "height - float(%s));\n    float center = float(2.0 * floor(%s / 2.0 + 0.25) - "
                "1.0);\n    float2 wh = smallDims - float2(center, center);\n    half hcoord = "
                "half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n    half "
                "hlookup = sample(%s, float2(float(hcoord), 0.5)).%s",
                (highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
        fragBuilder->codeAppendf(
                ".w;\n    half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / "
                "float(%s));\n    half vlookup = sample(%s, float2(float(vcoord), 0.5)).%s.w;\n    "
                "%s = (%s * hlookup) * vlookup;\n} else {\n    half2 translatedPos = "
                "half2(sk_FragCoord.xy - %s.xy);\n    half width = half(%s.z - %s.x);\n    half "
                "height = half(%s.w - %s.y);\n    half2 smallDims = half2(width - %s, height - "
                "%s);\n    half center = 2.0 * floor(%s / 2.0 + 0.25) - 1.0;\n    half2 wh = "
                "smallDims - half2(center, center);\n    half hco",
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
                args.fOutputColor, args.fInputColor, args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(rectVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                args.fUniformHandler->getUniformCStr(profileSizeVar));
        fragBuilder->codeAppendf(
                "ord = (abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / %s;\n    half hlookup = "
                "sample(%s, float2(float(hcoord), 0.5)).%s.w;\n    half vcoord = "
                "(abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / %s;\n    half vlookup = "
                "sample(%s, float2(float(vcoord), 0.5)).%s.w;\n    %s = (%s * hlookup) * "
                "vlookup;\n}\n",
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
                args.fUniformHandler->getUniformCStr(profileSizeVar),
                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
                args.fOutputColor, args.fInputColor);
    }

private:
    void onSetData(const GrGLSLProgramDataManager& pdman,
                   const GrFragmentProcessor& _proc) override {
        const GrRectBlurEffect& _outer = _proc.cast<GrRectBlurEffect>();
        { pdman.set4fv(rectVar, 1, reinterpret_cast<const float*>(&(_outer.rect))); }
        UniformHandle& rect = rectVar;
        (void)rect;
        auto sigma = _outer.sigma;
        (void)sigma;
        GrSurfaceProxy& blurProfileProxy = *_outer.textureSampler(0).proxy();
        GrTexture& blurProfile = *blurProfileProxy.peekTexture();
        (void)blurProfile;
        UniformHandle& proxyRectHalf = proxyRectHalfVar;
        (void)proxyRectHalf;
        UniformHandle& proxyRectFloat = proxyRectFloatVar;
        (void)proxyRectFloat;
        UniformHandle& profileSize = profileSizeVar;
        (void)profileSize;

        pdman.set1f(profileSize, SkScalarCeilToScalar(6 * sigma));
    }
    bool highPrecision = false;
    UniformHandle proxyRectHalfVar;
    UniformHandle proxyRectFloatVar;
    UniformHandle profileSizeVar;
    UniformHandle rectVar;
};
GrGLSLFragmentProcessor* GrRectBlurEffect::onCreateGLSLInstance() const {
    return new GrGLSLRectBlurEffect();
}
void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                             GrProcessorKeyBuilder* b) const {
    bool highPrecision = ((((abs(rect.left()) > 16000.0 || abs(rect.top()) > 16000.0) ||
                            abs(rect.right()) > 16000.0) ||
                           abs(rect.bottom()) > 16000.0) ||
                          abs(rect.right() - rect.left()) > 16000.0) ||
                         abs(rect.bottom() - rect.top()) > 16000.0;
    b->add32((int32_t)highPrecision);
}
bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
    const GrRectBlurEffect& that = other.cast<GrRectBlurEffect>();
    (void)that;
    if (rect != that.rect) return false;
    if (sigma != that.sigma) return false;
    if (blurProfile != that.blurProfile) return false;
    return true;
}
GrRectBlurEffect::GrRectBlurEffect(const GrRectBlurEffect& src)
        : INHERITED(kGrRectBlurEffect_ClassID, src.optimizationFlags())
        , rect(src.rect)
        , sigma(src.sigma)
        , blurProfile(src.blurProfile) {
    this->setTextureSamplerCnt(1);
}
std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::clone() const {
    return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(*this));
}
const GrFragmentProcessor::TextureSampler& GrRectBlurEffect::onTextureSampler(int index) const {
    return IthTextureSampler(index, blurProfile);
}
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* data) {
    float sigma = data->fRandom->nextRangeF(3, 8);
    float width = data->fRandom->nextRangeF(200, 300);
    float height = data->fRandom->nextRangeF(200, 300);
    return GrRectBlurEffect::Make(data->proxyProvider(), *data->caps()->shaderCaps(),
                                  SkRect::MakeWH(width, height), sigma);
}
#endif
