1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8/**************************************************************************************************
9 *** This file was autogenerated from GrRectBlurEffect.fp; do not modify.
10 **************************************************************************************************/
11#include "GrRectBlurEffect.h"
12#if SK_SUPPORT_GPU
13#include "glsl/GrGLSLFragmentProcessor.h"
14#include "glsl/GrGLSLFragmentShaderBuilder.h"
15#include "glsl/GrGLSLProgramBuilder.h"
16#include "GrTexture.h"
17#include "SkSLCPP.h"
18#include "SkSLUtil.h"
19class GrGLSLRectBlurEffect : public GrGLSLFragmentProcessor {
20public:
21    GrGLSLRectBlurEffect() {}
22    void emitCode(EmitArgs& args) override {
23        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
24        const GrRectBlurEffect& _outer = args.fFp.cast<GrRectBlurEffect>();
25        (void)_outer;
26        auto rect = _outer.rect();
27        (void)rect;
28        auto sigma = _outer.sigma();
29        (void)sigma;
30        highPrecision = ((((abs(rect.left()) > 16000.0 || abs(rect.top()) > 16000.0) ||
31                           abs(rect.right()) > 16000.0) ||
32                          abs(rect.bottom()) > 16000.0) ||
33                         abs(rect.right() - rect.left()) > 16000.0) ||
34                        abs(rect.bottom() - rect.top()) > 16000.0;
35        fRectVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
36                                                    kDefault_GrSLPrecision, "rect");
37        if (!highPrecision) {
38            fProxyRectHalfVar =
39                    args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
40                                                     kDefault_GrSLPrecision, "proxyRectHalf");
41        }
42        if (highPrecision) {
43            fProxyRectFloatVar =
44                    args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
45                                                     kDefault_GrSLPrecision, "proxyRectFloat");
46        }
47        fProfileSizeVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType,
48                                                           kDefault_GrSLPrecision, "profileSize");
49        fragBuilder->codeAppendf(
50                "bool highPrecision = %s;\n@if (highPrecision) {\n    float2 translatedPos = "
51                "sk_FragCoord.xy - %s.xy;\n    float width = %s.z - %s.x;\n    float height = %s.w "
52                "- %s.y;\n    float2 smallDims = float2(width - float(%s), height - float(%s));\n  "
53                "  float center = 2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0;\n    float2 wh "
54                "= smallDims - float2(center, center);\n    half hcoord = "
55                "half((abs(translatedPos.x - 0.5 * width) - 0.5 * wh.x) / float(%s));\n    half "
56                "hlookup = texture(%s, float2(float(hcoord), 0.5)).%s.w",
57                (highPrecision ? "true" : "false"), args.fUniformHandler->getUniformCStr(fRectVar),
58                args.fUniformHandler->getUniformCStr(fRectVar),
59                args.fUniformHandler->getUniformCStr(fRectVar),
60                args.fUniformHandler->getUniformCStr(fRectVar),
61                args.fUniformHandler->getUniformCStr(fRectVar),
62                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
63                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
64                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
65                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
66                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
67                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
68        fragBuilder->codeAppendf(
69                ";\n    half vcoord = half((abs(translatedPos.y - 0.5 * height) - 0.5 * wh.y) / "
70                "float(%s));\n    half vlookup = texture(%s, float2(float(vcoord), 0.5)).%s.w;\n   "
71                " %s = (%s * hlookup) * vlookup;\n} else {\n    half2 translatedPos = "
72                "half2(sk_FragCoord.xy - %s.xy);\n    half width = half(%s.z - %s.x);\n    half "
73                "height = half(%s.w - %s.y);\n    half2 smallDims = half2(width - %s, height - "
74                "%s);\n    half center = half(2.0 * floor(float(float(%s / 2.0) + 0.25)) - 1.0);\n "
75                "   half2 wh = smallDims - half2(float2(floa",
76                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
77                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
78                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
79                args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)",
80                args.fUniformHandler->getUniformCStr(fRectVar),
81                args.fUniformHandler->getUniformCStr(fRectVar),
82                args.fUniformHandler->getUniformCStr(fRectVar),
83                args.fUniformHandler->getUniformCStr(fRectVar),
84                args.fUniformHandler->getUniformCStr(fRectVar),
85                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
86                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
87                args.fUniformHandler->getUniformCStr(fProfileSizeVar));
88        fragBuilder->codeAppendf(
89                "t(center), float(center)));\n    half hcoord = "
90                "half((abs(float(float(translatedPos.x) - 0.5 * float(width))) - 0.5 * "
91                "float(wh.x)) / float(%s));\n    half hlookup = texture(%s, float2(float(hcoord), "
92                "0.5)).%s.w;\n    half vcoord = half((abs(float(float(translatedPos.y) - 0.5 * "
93                "float(height))) - 0.5 * float(wh.y)) / float(%s));\n    half vlookup = "
94                "texture(%s, float2(float(vcoord), 0.5)).%s.w;\n    %s = (%s * hlookup) * "
95                "vlookup;\n}\n",
96                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
97                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
98                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
99                args.fUniformHandler->getUniformCStr(fProfileSizeVar),
100                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
101                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(),
102                args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)");
103    }
104
105private:
106    void onSetData(const GrGLSLProgramDataManager& pdman,
107                   const GrFragmentProcessor& _proc) override {
108        const GrRectBlurEffect& _outer = _proc.cast<GrRectBlurEffect>();
109        {
110            const SkRect rectValue = _outer.rect();
111            pdman.set4fv(fRectVar, 1, (float*)&rectValue);
112        }
113        UniformHandle& rect = fRectVar;
114        (void)rect;
115        auto sigma = _outer.sigma();
116        (void)sigma;
117        GrSurfaceProxy& blurProfileProxy = *_outer.textureSampler(0).proxy();
118        GrTexture& blurProfile = *blurProfileProxy.priv().peekTexture();
119        (void)blurProfile;
120        UniformHandle& proxyRectHalf = fProxyRectHalfVar;
121        (void)proxyRectHalf;
122        UniformHandle& proxyRectFloat = fProxyRectFloatVar;
123        (void)proxyRectFloat;
124        UniformHandle& profileSize = fProfileSizeVar;
125        (void)profileSize;
126
127        pdman.set1f(profileSize, SkScalarCeilToScalar(6 * sigma));
128    }
129    bool highPrecision = false;
130    UniformHandle fProxyRectHalfVar;
131    UniformHandle fProxyRectFloatVar;
132    UniformHandle fProfileSizeVar;
133    UniformHandle fRectVar;
134};
135GrGLSLFragmentProcessor* GrRectBlurEffect::onCreateGLSLInstance() const {
136    return new GrGLSLRectBlurEffect();
137}
138void GrRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
139                                             GrProcessorKeyBuilder* b) const {}
140bool GrRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const {
141    const GrRectBlurEffect& that = other.cast<GrRectBlurEffect>();
142    (void)that;
143    if (fRect != that.fRect) return false;
144    if (fSigma != that.fSigma) return false;
145    if (fBlurProfile != that.fBlurProfile) return false;
146    return true;
147}
148GrRectBlurEffect::GrRectBlurEffect(const GrRectBlurEffect& src)
149        : INHERITED(kGrRectBlurEffect_ClassID, src.optimizationFlags())
150        , fRect(src.fRect)
151        , fSigma(src.fSigma)
152        , fBlurProfile(src.fBlurProfile) {
153    this->addTextureSampler(&fBlurProfile);
154}
155std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::clone() const {
156    return std::unique_ptr<GrFragmentProcessor>(new GrRectBlurEffect(*this));
157}
158GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRectBlurEffect);
159#if GR_TEST_UTILS
160std::unique_ptr<GrFragmentProcessor> GrRectBlurEffect::TestCreate(GrProcessorTestData* data) {
161    float sigma = data->fRandom->nextRangeF(3, 8);
162    float width = data->fRandom->nextRangeF(200, 300);
163    float height = data->fRandom->nextRangeF(200, 300);
164    return GrRectBlurEffect::Make(data->proxyProvider(), SkRect::MakeWH(width, height), sigma);
165}
166#endif
167#endif
168