1c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth/*
2c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth * Copyright 2016 Google Inc.
3c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth *
4c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth * Use of this source code is governed by a BSD-style license that can be
5c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth * found in the LICENSE file.
6c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth */
7c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
8c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth#include "GrShadowGeoProc.h"
9c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
10c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth#include "glsl/GrGLSLFragmentShaderBuilder.h"
11c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth#include "glsl/GrGLSLGeometryProcessor.h"
12c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth#include "glsl/GrGLSLUniformHandler.h"
13c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth#include "glsl/GrGLSLVarying.h"
14c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth#include "glsl/GrGLSLVertexShaderBuilder.h"
15c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
16c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verthclass GrGLSLRRectShadowGeoProc : public GrGLSLGeometryProcessor {
17c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verthpublic:
18c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    GrGLSLRRectShadowGeoProc() {}
19c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
20c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
21c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        const GrRRectShadowGeoProc& rsgp = args.fGP.cast<GrRRectShadowGeoProc>();
22c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
23c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
24c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
25c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder;
26c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
27c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        // emit attributes
28c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        varyingHandler->emitAttributes(rsgp);
29c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("vec4 shadowParams;");
30c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        varyingHandler->addPassThroughAttribute(rsgp.inShadowParams(), "shadowParams");
31c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
32c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        // setup pass through color
33c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        varyingHandler->addPassThroughAttribute(rsgp.inColor(), args.fOutputColor);
34c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
35c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        // Setup position
36c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        this->setupPosition(vertBuilder, gpArgs, rsgp.inPosition()->fName);
37c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
38c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        // emit transforms
39c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        this->emitTransforms(vertBuilder,
40c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             varyingHandler,
41c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             uniformHandler,
42c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             gpArgs->fPositionVar,
43c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             rsgp.inPosition()->fName,
44c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             rsgp.localMatrix(),
45c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             args.fFPCoordTransformHandler);
46c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
47c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("float d = length(shadowParams.xy);");
48c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("float distance = shadowParams.z * (1.0 - d);");
49c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
50c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("float radius = shadowParams.w;");
51c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
52c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("float factor = 1.0 - clamp(distance/radius, 0.0, 1.0);");
53c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
54c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppendf("%s = vec4(factor);",
55c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                                 args.fOutputCoverage);
56c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    }
57c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
58c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
59c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                 FPCoordTransformIter&& transformIter) override {
60c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        this->setTransformDataHelper(proc.cast<GrRRectShadowGeoProc>().localMatrix(),
61c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                                     pdman, &transformIter);
62c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    }
63c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
64c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    static inline void GenKey(const GrGeometryProcessor& gp,
6594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon                              const GrShaderCaps&,
66c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                              GrProcessorKeyBuilder* b) {
67c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        const GrRRectShadowGeoProc& rsgp = gp.cast<GrRRectShadowGeoProc>();
68c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        uint16_t key;
69c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        key = rsgp.localMatrix().hasPerspective() ? 0x1 : 0x0;
70c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        b->add32(key);
71c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    }
72c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
73c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verthprivate:
74c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    typedef GrGLSLGeometryProcessor INHERITED;
75c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth};
76c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
77c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth///////////////////////////////////////////////////////////////////////////////
78c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
79c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van VerthGrRRectShadowGeoProc::GrRRectShadowGeoProc(const SkMatrix& localMatrix)
80c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    : fLocalMatrix(localMatrix) {
81c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
82c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    this->initClassID<GrRRectShadowGeoProc>();
83c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    fInPosition = &this->addVertexAttrib("inPosition", kVec2f_GrVertexAttribType,
84c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                                         kHigh_GrSLPrecision);
85c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    fInColor = &this->addVertexAttrib("inColor", kVec4ub_GrVertexAttribType);
86c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    fInShadowParams = &this->addVertexAttrib("inShadowParams", kVec4f_GrVertexAttribType);
87c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
88c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
8994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonvoid GrRRectShadowGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps,
90c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                                               GrProcessorKeyBuilder* b) const {
91c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    GrGLSLRRectShadowGeoProc::GenKey(*this, caps, b);
92c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
93c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
9494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian SalomonGrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrShaderCaps&) const {
95c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    return new GrGLSLRRectShadowGeoProc();
96c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
97c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
98c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth///////////////////////////////////////////////////////////////////////////////
99c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
100c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van VerthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc);
101c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
1026f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
103c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verthsk_sp<GrGeometryProcessor> GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) {
104c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    return GrRRectShadowGeoProc::Make(GrTest::TestMatrix(d->fRandom));
105c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
1066f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
107