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"
14c17bf32a1bf2f79a8c4a281c2ad312a3cdb610cdChris Dalton#include "glsl/GrGLSLVertexGeoBuilder.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;
25602836138e02935885c77f9dd93dcb51a3ec9a64Chris Dalton        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
26c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
27c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        // emit attributes
28c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        varyingHandler->emitAttributes(rsgp);
29f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas        fragBuilder->codeAppend("half4 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
367f23543d1d27452ac1ddc21cc0c9f88479920cdeBrian Salomon        this->writeOutputPosition(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,
4204460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon                             rsgp.inPosition()->asShaderVar(),
43c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                             args.fFPCoordTransformHandler);
44c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
45f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas        fragBuilder->codeAppend("half d = length(shadowParams.xy);");
46f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas        fragBuilder->codeAppend("half distance = shadowParams.z * (1.0 - d);");
47c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
48f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas        fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, shadowParams.w);");
49c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth        fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
50f7b8820dc813d1eb0b6b43fe4581dded0da38cafEthan Nicholas        fragBuilder->codeAppendf("%s = half4(factor);",
51c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                                 args.fOutputCoverage);
52c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    }
53c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
54c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
55c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth                 FPCoordTransformIter&& transformIter) override {
560596909b055eb9493ba429cc09eae4a2ec53f158Brian Salomon        this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
57c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    }
58c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
59c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verthprivate:
60c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    typedef GrGLSLGeometryProcessor INHERITED;
61c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth};
62c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
63c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth///////////////////////////////////////////////////////////////////////////////
64c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
65abff956455637b12eab374fd44b99e1338799113Ethan NicholasGrRRectShadowGeoProc::GrRRectShadowGeoProc()
66abff956455637b12eab374fd44b99e1338799113Ethan Nicholas: INHERITED(kGrRRectShadowGeoProc_ClassID) {
67fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas    fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
68fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas    fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
69fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas    fInShadowParams = &this->addVertexAttrib("inShadowParams", kHalf4_GrVertexAttribType);
70c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
71c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
7294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian SalomonGrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrShaderCaps&) const {
73c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth    return new GrGLSLRRectShadowGeoProc();
74c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
75c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
76c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth///////////////////////////////////////////////////////////////////////////////
77c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
78c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van VerthGR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc);
79c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth
806f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#if GR_TEST_UTILS
81c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verthsk_sp<GrGeometryProcessor> GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) {
820596909b055eb9493ba429cc09eae4a2ec53f158Brian Salomon    return GrRRectShadowGeoProc::Make();
83c59034145862bf6dc0c503cb1e47eecd321ffa8cJim Van Verth}
846f6961ebad65c582318564b3688e78e5c99f3935Hal Canary#endif
85