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