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 GrEllipseEffect.fp; do not modify. 10 **************************************************************************************************/ 11#include "GrEllipseEffect.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" 19class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor { 20public: 21 GrGLSLEllipseEffect() {} 22 void emitCode(EmitArgs& args) override { 23 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 24 const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>(); 25 (void)_outer; 26 auto edgeType = _outer.edgeType(); 27 (void)edgeType; 28 auto center = _outer.center(); 29 (void)center; 30 auto radii = _outer.radii(); 31 (void)radii; 32 prevRadii = float2(-1.0); 33 useScale = !sk_Caps.floatIs32Bits; 34 fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType, 35 kDefault_GrSLPrecision, "ellipse"); 36 if (useScale) { 37 fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat2_GrSLType, 38 kDefault_GrSLPrecision, "scale"); 39 } 40 fragBuilder->codeAppendf( 41 "float2 prevCenter;\nfloat2 prevRadii = float2(%f, %f);\nbool useScale = " 42 "%s;\nfloat2 d = sk_FragCoord.xy - %s.xy;\n@if (useScale) {\n d *= " 43 "%s.y;\n}\nfloat2 Z = d * %s.zw;\nfloat implicit = dot(Z, d) - 1.0;\nfloat " 44 "grad_dot = 4.0 * dot(Z, Z);\ngrad_dot = max(grad_dot, 0.0001);\nfloat approx_dist " 45 "= implicit * inversesqrt(grad_dot);\n@if (useScale) {\n approx_dist *= " 46 "%s.x;\n}\nhalf alpha;\n@switch (%d) {\n case 0:\n alpha = " 47 "half(approx_dist > 0.0 ? 0.0 : 1.0);\n break;\n case 1:\n ", 48 prevRadii.fX, prevRadii.fY, (useScale ? "true" : "false"), 49 args.fUniformHandler->getUniformCStr(fEllipseVar), 50 fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)", 51 args.fUniformHandler->getUniformCStr(fEllipseVar), 52 fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "float2(0)", 53 (int)_outer.edgeType()); 54 fragBuilder->codeAppendf( 55 " alpha = half(clamp(0.5 - approx_dist, 0.0, 1.0));\n break;\n case " 56 "2:\n alpha = half(approx_dist > 0.0 ? 1.0 : 0.0);\n break;\n " 57 "case 3:\n alpha = half(clamp(0.5 + approx_dist, 0.0, 1.0));\n " 58 "break;\n default:\n discard;\n}\n%s = %s * alpha;\n", 59 args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)"); 60 } 61 62private: 63 void onSetData(const GrGLSLProgramDataManager& pdman, 64 const GrFragmentProcessor& _proc) override { 65 const GrEllipseEffect& _outer = _proc.cast<GrEllipseEffect>(); 66 auto edgeType = _outer.edgeType(); 67 (void)edgeType; 68 auto center = _outer.center(); 69 (void)center; 70 auto radii = _outer.radii(); 71 (void)radii; 72 UniformHandle& ellipse = fEllipseVar; 73 (void)ellipse; 74 UniformHandle& scale = fScaleVar; 75 (void)scale; 76 77 if (radii != prevRadii || center != prevCenter) { 78 float invRXSqd; 79 float invRYSqd; 80 // If we're using a scale factor to work around precision issues, choose the larger 81 // radius as the scale factor. The inv radii need to be pre-adjusted by the scale 82 // factor. 83 if (scale.isValid()) { 84 if (radii.fX > radii.fY) { 85 invRXSqd = 1.f; 86 invRYSqd = (radii.fX * radii.fX) / (radii.fY * radii.fY); 87 pdman.set2f(scale, radii.fX, 1.f / radii.fX); 88 } else { 89 invRXSqd = (radii.fY * radii.fY) / (radii.fX * radii.fX); 90 invRYSqd = 1.f; 91 pdman.set2f(scale, radii.fY, 1.f / radii.fY); 92 } 93 } else { 94 invRXSqd = 1.f / (radii.fX * radii.fX); 95 invRYSqd = 1.f / (radii.fY * radii.fY); 96 } 97 pdman.set4f(ellipse, center.fX, center.fY, invRXSqd, invRYSqd); 98 prevCenter = center; 99 prevRadii = radii; 100 } 101 } 102 SkPoint prevCenter = float2(0); 103 SkPoint prevRadii = float2(0); 104 bool useScale = false; 105 UniformHandle fEllipseVar; 106 UniformHandle fScaleVar; 107}; 108GrGLSLFragmentProcessor* GrEllipseEffect::onCreateGLSLInstance() const { 109 return new GrGLSLEllipseEffect(); 110} 111void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, 112 GrProcessorKeyBuilder* b) const { 113 b->add32((int32_t)fEdgeType); 114} 115bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const { 116 const GrEllipseEffect& that = other.cast<GrEllipseEffect>(); 117 (void)that; 118 if (fEdgeType != that.fEdgeType) return false; 119 if (fCenter != that.fCenter) return false; 120 if (fRadii != that.fRadii) return false; 121 return true; 122} 123GrEllipseEffect::GrEllipseEffect(const GrEllipseEffect& src) 124 : INHERITED(kGrEllipseEffect_ClassID, src.optimizationFlags()) 125 , fEdgeType(src.fEdgeType) 126 , fCenter(src.fCenter) 127 , fRadii(src.fRadii) {} 128std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::clone() const { 129 return std::unique_ptr<GrFragmentProcessor>(new GrEllipseEffect(*this)); 130} 131GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect); 132#if GR_TEST_UTILS 133std::unique_ptr<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) { 134 SkPoint center; 135 center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f); 136 center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f); 137 SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f); 138 SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f); 139 GrClipEdgeType et; 140 do { 141 et = (GrClipEdgeType)testData->fRandom->nextULessThan(kGrClipEdgeTypeCnt); 142 } while (GrClipEdgeType::kHairlineAA == et); 143 return GrEllipseEffect::Make(et, center, SkPoint::Make(rx, ry), 144 *testData->caps()->shaderCaps()); 145} 146#endif 147#endif 148