Home | History | Annotate | Download | only in effects
      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/GrGLSLVertexGeoBuilder.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         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
     26 
     27         // emit attributes
     28         varyingHandler->emitAttributes(rsgp);
     29         fragBuilder->codeAppend("half4 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->writeOutputPosition(vertBuilder, gpArgs, rsgp.inPosition()->fName);
     37 
     38         // emit transforms
     39         this->emitTransforms(vertBuilder,
     40                              varyingHandler,
     41                              uniformHandler,
     42                              rsgp.inPosition()->asShaderVar(),
     43                              args.fFPCoordTransformHandler);
     44 
     45         fragBuilder->codeAppend("half d = length(shadowParams.xy);");
     46         fragBuilder->codeAppend("half distance = shadowParams.z * (1.0 - d);");
     47 
     48         fragBuilder->codeAppend("half factor = 1.0 - clamp(distance, 0.0, shadowParams.w);");
     49         fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;");
     50         fragBuilder->codeAppendf("%s = half4(factor);",
     51                                  args.fOutputCoverage);
     52     }
     53 
     54     void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& proc,
     55                  FPCoordTransformIter&& transformIter) override {
     56         this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter);
     57     }
     58 
     59 private:
     60     typedef GrGLSLGeometryProcessor INHERITED;
     61 };
     62 
     63 ///////////////////////////////////////////////////////////////////////////////
     64 
     65 GrRRectShadowGeoProc::GrRRectShadowGeoProc()
     66 : INHERITED(kGrRRectShadowGeoProc_ClassID) {
     67     fInPosition = &this->addVertexAttrib("inPosition", kFloat2_GrVertexAttribType);
     68     fInColor = &this->addVertexAttrib("inColor", kUByte4_norm_GrVertexAttribType);
     69     fInShadowParams = &this->addVertexAttrib("inShadowParams", kHalf4_GrVertexAttribType);
     70 }
     71 
     72 GrGLSLPrimitiveProcessor* GrRRectShadowGeoProc::createGLSLInstance(const GrShaderCaps&) const {
     73     return new GrGLSLRRectShadowGeoProc();
     74 }
     75 
     76 ///////////////////////////////////////////////////////////////////////////////
     77 
     78 GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrRRectShadowGeoProc);
     79 
     80 #if GR_TEST_UTILS
     81 sk_sp<GrGeometryProcessor> GrRRectShadowGeoProc::TestCreate(GrProcessorTestData* d) {
     82     return GrRRectShadowGeoProc::Make();
     83 }
     84 #endif
     85