1 /*
2  * Copyright 2017 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 #include "effects/GrBlurredEdgeFragmentProcessor.h"
9 
10 #include "glsl/GrGLSLFragmentProcessor.h"
11 #include "glsl/GrGLSLFragmentShaderBuilder.h"
12 
13 class GLSLBlurredEdgeFP : public GrGLSLFragmentProcessor {
14 public:
GLSLBlurredEdgeFP()15     GLSLBlurredEdgeFP() {}
16 
emitCode(EmitArgs & args)17     void emitCode(EmitArgs& args) override {
18 
19         GrBlurredEdgeFP::Mode mode = args.fFp.cast<GrBlurredEdgeFP>().mode();
20 
21         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
22 
23         fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor);
24         if (!args.fGpImplementsDistanceVector) {
25             fragBuilder->codeAppendf("// assuming interpolant is set in vertex colors\n");
26             fragBuilder->codeAppendf("float factor = 1.0 - color.b;");
27         } else {
28             fragBuilder->codeAppendf("// using distance to edge to compute interpolant\n");
29             fragBuilder->codeAppend("float radius = color.r*256.0*64.0 + color.g*64.0;");
30             fragBuilder->codeAppend("float pad = color.b*64.0;");
31 
32             fragBuilder->codeAppendf("float factor = 1.0 - clamp((%s.z - pad)/radius, 0.0, 1.0);",
33                                      fragBuilder->distanceVectorName());
34         }
35         switch (mode) {
36             case GrBlurredEdgeFP::kGaussian_Mode:
37                 fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
38                 break;
39             case GrBlurredEdgeFP::kSmoothstep_Mode:
40                 fragBuilder->codeAppend("factor = smoothstep(factor, 0.0, 1.0);");
41                 break;
42         }
43         if (!args.fGpImplementsDistanceVector) {
44             fragBuilder->codeAppendf("%s = vec4(factor*color.g);", args.fOutputColor);
45         } else {
46             fragBuilder->codeAppendf("%s = vec4(factor*color.a);", args.fOutputColor);
47         }
48     }
49 
50 protected:
onSetData(const GrGLSLProgramDataManager & pdman,const GrProcessor & proc)51     void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {}
52 
53     GrBlurredEdgeFP::Mode fMode;
54 };
55 
onCreateGLSLInstance() const56 GrGLSLFragmentProcessor* GrBlurredEdgeFP::onCreateGLSLInstance() const {
57     return new GLSLBlurredEdgeFP();
58 }
59 
onGetGLSLProcessorKey(const GrShaderCaps & caps,GrProcessorKeyBuilder * b) const60 void GrBlurredEdgeFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
61                                             GrProcessorKeyBuilder* b) const {
62     b->add32(fMode);
63 }
64 
onIsEqual(const GrFragmentProcessor & other) const65 bool GrBlurredEdgeFP::onIsEqual(const GrFragmentProcessor& other) const {
66     const GrBlurredEdgeFP& that = other.cast<GrBlurredEdgeFP>();
67     return that.fMode == fMode;
68 }
69 
70 
71