Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2017 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 /**************************************************************************************************
      9  *** This file was autogenerated from GrCircleEffect.fp; do not modify.
     10  **************************************************************************************************/
     11 #include "GrCircleEffect.h"
     12 #if SK_SUPPORT_GPU
     13 #include "glsl/GrGLSLFragmentProcessor.h"
     14 #include "glsl/GrGLSLFragmentShaderBuilder.h"
     15 #include "glsl/GrGLSLProgramBuilder.h"
     16 #include "GrTexture.h"
     17 #include "SkSLCPP.h"
     18 #include "SkSLUtil.h"
     19 class GrGLSLCircleEffect : public GrGLSLFragmentProcessor {
     20 public:
     21     GrGLSLCircleEffect() {}
     22     void emitCode(EmitArgs& args) override {
     23         GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
     24         const GrCircleEffect& _outer = args.fFp.cast<GrCircleEffect>();
     25         (void)_outer;
     26         auto edgeType = _outer.edgeType();
     27         (void)edgeType;
     28         auto center = _outer.center();
     29         (void)center;
     30         auto radius = _outer.radius();
     31         (void)radius;
     32         prevRadius = -1.0;
     33         fCircleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
     34                                                       kDefault_GrSLPrecision, "circle");
     35         fragBuilder->codeAppendf(
     36                 "half2 prevCenter;\nhalf prevRadius = %f;\nhalf d;\n@if (%d == 2 || %d == 3) {\n   "
     37                 " d = (float(length((%s.xy - half2(sk_FragCoord.xy)) * %s.w)) - 1.0) * %s.z;\n} "
     38                 "else {\n    d = half((1.0 - float(length((%s.xy - half2(sk_FragCoord.xy)) * "
     39                 "%s.w))) * float(%s.z));\n}\n@if ((%d == 1 || %d == 3) || %d == 4) {\n    d = "
     40                 "half(clamp(float(d), 0.0, 1.0));\n} else {\n    d = half(float(d) > 0.5 ? 1.0 : "
     41                 "0.0);\n}\n%s = %s * d;\n",
     42                 prevRadius, (int)_outer.edgeType(), (int)_outer.edgeType(),
     43                 args.fUniformHandler->getUniformCStr(fCircleVar),
     44                 args.fUniformHandler->getUniformCStr(fCircleVar),
     45                 args.fUniformHandler->getUniformCStr(fCircleVar),
     46                 args.fUniformHandler->getUniformCStr(fCircleVar),
     47                 args.fUniformHandler->getUniformCStr(fCircleVar),
     48                 args.fUniformHandler->getUniformCStr(fCircleVar), (int)_outer.edgeType(),
     49                 (int)_outer.edgeType(), (int)_outer.edgeType(), args.fOutputColor,
     50                 args.fInputColor ? args.fInputColor : "half4(1)");
     51     }
     52 
     53 private:
     54     void onSetData(const GrGLSLProgramDataManager& pdman,
     55                    const GrFragmentProcessor& _proc) override {
     56         const GrCircleEffect& _outer = _proc.cast<GrCircleEffect>();
     57         auto edgeType = _outer.edgeType();
     58         (void)edgeType;
     59         auto center = _outer.center();
     60         (void)center;
     61         auto radius = _outer.radius();
     62         (void)radius;
     63         UniformHandle& circle = fCircleVar;
     64         (void)circle;
     65 
     66         if (radius != prevRadius || center != prevCenter) {
     67             SkScalar effectiveRadius = radius;
     68             if (GrProcessorEdgeTypeIsInverseFill((GrClipEdgeType)edgeType)) {
     69                 effectiveRadius -= 0.5f;
     70                 // When the radius is 0.5 effectiveRadius is 0 which causes an inf * 0 in the
     71                 // shader.
     72                 effectiveRadius = SkTMax(0.001f, effectiveRadius);
     73             } else {
     74                 effectiveRadius += 0.5f;
     75             }
     76             pdman.set4f(circle, center.fX, center.fY, effectiveRadius,
     77                         SkScalarInvert(effectiveRadius));
     78             prevCenter = center;
     79             prevRadius = radius;
     80         }
     81     }
     82     SkPoint prevCenter = half2(0);
     83     float prevRadius = 0;
     84     UniformHandle fCircleVar;
     85 };
     86 GrGLSLFragmentProcessor* GrCircleEffect::onCreateGLSLInstance() const {
     87     return new GrGLSLCircleEffect();
     88 }
     89 void GrCircleEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
     90                                            GrProcessorKeyBuilder* b) const {
     91     b->add32((int32_t)fEdgeType);
     92 }
     93 bool GrCircleEffect::onIsEqual(const GrFragmentProcessor& other) const {
     94     const GrCircleEffect& that = other.cast<GrCircleEffect>();
     95     (void)that;
     96     if (fEdgeType != that.fEdgeType) return false;
     97     if (fCenter != that.fCenter) return false;
     98     if (fRadius != that.fRadius) return false;
     99     return true;
    100 }
    101 GrCircleEffect::GrCircleEffect(const GrCircleEffect& src)
    102         : INHERITED(kGrCircleEffect_ClassID, src.optimizationFlags())
    103         , fEdgeType(src.fEdgeType)
    104         , fCenter(src.fCenter)
    105         , fRadius(src.fRadius) {}
    106 std::unique_ptr<GrFragmentProcessor> GrCircleEffect::clone() const {
    107     return std::unique_ptr<GrFragmentProcessor>(new GrCircleEffect(*this));
    108 }
    109 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCircleEffect);
    110 #if GR_TEST_UTILS
    111 std::unique_ptr<GrFragmentProcessor> GrCircleEffect::TestCreate(GrProcessorTestData* testData) {
    112     SkPoint center;
    113     center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
    114     center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
    115     SkScalar radius = testData->fRandom->nextRangeF(1.f, 1000.f);
    116     GrClipEdgeType et;
    117     do {
    118         et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
    119     } while (GrClipEdgeType::kHairlineAA == et);
    120     return GrCircleEffect::Make(et, center, radius);
    121 }
    122 #endif
    123 #endif
    124