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/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