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 16 class GrGLSLRRectShadowGeoProc : public GrGLSLGeometryProcessor { 17 public: 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 GrShaderCaps&, 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 73 private: 74 typedef GrGLSLGeometryProcessor INHERITED; 75 }; 76 77 /////////////////////////////////////////////////////////////////////////////// 78 79 GrRRectShadowGeoProc::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 89 void GrRRectShadowGeoProc::getGLSLProcessorKey(const GrShaderCaps& caps, 90 GrProcessorKeyBuilder* b) const { 91 GrGLSLRRectShadowGeoProc::GenKey(*this, caps, b); 92 } 93 94 GrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrShaderCaps&) const { 95 return new GrGLSLRRectShadowGeoProc(); 96 } 97 98 /////////////////////////////////////////////////////////////////////////////// 99 100 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc); 101 102 #if GR_TEST_UTILS 103 sk_sp<GrGeometryProcessor> GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) { 104 return GrRRectShadowGeoProc::Make(GrTest::TestMatrix(d->fRandom)); 105 } 106 #endif 107