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