GrShadowGeoProc.cpp revision c59034145862bf6dc0c503cb1e47eecd321ffa8c
1/*
2 * Copyright 2016 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 "GrShadowGeoProc.h"
9
10#include "glsl/GrGLSLFragmentShaderBuilder.h"
11#include "glsl/GrGLSLGeometryProcessor.h"
12#include "glsl/GrGLSLUniformHandler.h"
13#include "glsl/GrGLSLVarying.h"
14#include "glsl/GrGLSLVertexShaderBuilder.h"
15
16class GrGLSLRRectShadowGeoProc : public GrGLSLGeometryProcessor {
17public:
18    GrGLSLRRectShadowGeoProc() {}
19
20    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
21        const GrRRectShadowGeoProc& rsgp = args.fGP.cast<GrRRectShadowGeoProc>();
22        GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
23        GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
24        GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
25        GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
26
27        // emit attributes
28        varyingHandler->emitAttributes(rsgp);
29        fragBuilder->codeAppend("vec4 shadowParams;");
30        varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
31
32        // setup pass through color
33        varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor);
34
35        // Setup position
36        this->setupPosition(vertBuilder, gpArgs, rsgp.inPosition()->fName);
37
38        // emit transforms
39        this->emitTransforms(vertBuilder,
40                             varyingHandler,
41                             uniformHandler,
42                             gpArgs->fPositionVar,
43                             rsgp.inPosition()->fName,
44                             rsgp.localMatrix(),
45                             args.fFPCoordTransformHandler);
46
47        fragBuilder->codeAppend("float d = length(shadowParams.xy);");
48        fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);");
49
50        fragBuilder->codeAppend("float radius = shadowParams.w;");
51
52        fragBuilder->codeAppend("float factor = 1.0 - clamp(distance/radius, 0.0, 1.0);");
53        fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
54        fragBuilder->codeAppendf("%s = vec4(factor);",
55                                 args.fOutputCoverage);
56    }
57
58    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
59                 FPCoordTransformIter&& transformIter) override {
60        this->setTransformDataHelper(proc.cast<GrRRectShadowGeoProc>().localMatrix(),
61                                     pdman, &transformIter);
62    }
63
64    static inline void GenKey(const GrGeometryProcessor& gp,
65                              const GrGLSLCaps&,
66                              GrProcessorKeyBuilder* b) {
67        const GrRRectShadowGeoProc& rsgp = gp.cast<GrRRectShadowGeoProc>();
68        uint16_t key;
69        key = rsgp.localMatrix().hasPerspective() ? 0x1 : 0x0;
70        b->add32(key);
71    }
72
73private:
74    typedef GrGLSLGeometryProcessor INHERITED;
75};
76
77///////////////////////////////////////////////////////////////////////////////
78
79GrRRectShadowGeoProc::GrRRectShadowGeoProc(const SkMatrix& localMatrix)
80    : fLocalMatrix(localMatrix) {
81
82    this->initClassID<GrRRectShadowGeoProc>();
83    fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
84                                         kHigh_GrSLPrecision);
85    fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
86    fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec4f_GrVertexAttribType);
87}
88
89void GrRRectShadowGeoProc::getGLSLProcessorKey(const GrGLSLCaps& caps,
90                                               GrProcessorKeyBuilder* b) const {
91    GrGLSLRRectShadowGeoProc::GenKey(*this, caps, b);
92}
93
94GrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrGLSLCaps&) const {
95    return new GrGLSLRRectShadowGeoProc();
96}
97
98///////////////////////////////////////////////////////////////////////////////
99
100GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc);
101
102sk_sp<GrGeometryProcessor> GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) {
103    return GrRRectShadowGeoProc::Make(GrTest::TestMatrix(d->fRandom));
104}
105