1 /* 2 * Copyright 2018 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 GrRRectBlurEffect.fp; do not modify. 10 **************************************************************************************************/ 11 #include "GrRRectBlurEffect.h" 12 #if SK_SUPPORT_GPU 13 14 std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(GrContext* context, float sigma, 15 float xformedSigma, 16 const SkRRect& srcRRect, 17 const SkRRect& devRRect) { 18 SkASSERT(!SkRRectPriv::IsCircle(devRRect) && 19 !devRRect.isRect()); // Should've been caught up-stream 20 21 // TODO: loosen this up 22 if (!SkRRectPriv::IsSimpleCircular(devRRect)) { 23 return nullptr; 24 } 25 26 // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be 27 // sufficiently small relative to both the size of the corner radius and the 28 // width (and height) of the rrect. 29 SkRRect rrectToDraw; 30 SkISize size; 31 SkScalar ignored[SkBlurMaskFilter::kMaxDivisions]; 32 int ignoredSize; 33 uint32_t ignored32; 34 35 bool ninePatchable = SkBlurMaskFilter::ComputeBlurredRRectParams( 36 srcRRect, devRRect, SkRect::MakeEmpty(), sigma, xformedSigma, &rrectToDraw, &size, 37 ignored, ignored, ignored, ignored, &ignoredSize, &ignoredSize, &ignored32); 38 if (!ninePatchable) { 39 return nullptr; 40 } 41 42 sk_sp<GrTextureProxy> mask( 43 find_or_create_rrect_blur_mask(context, rrectToDraw, size, xformedSigma)); 44 if (!mask) { 45 return nullptr; 46 } 47 48 return std::unique_ptr<GrFragmentProcessor>( 49 new GrRRectBlurEffect(xformedSigma, devRRect.getBounds(), 50 SkRRectPriv::GetSimpleRadii(devRRect).fX, std::move(mask))); 51 } 52 #include "glsl/GrGLSLFragmentProcessor.h" 53 #include "glsl/GrGLSLFragmentShaderBuilder.h" 54 #include "glsl/GrGLSLProgramBuilder.h" 55 #include "GrTexture.h" 56 #include "SkSLCPP.h" 57 #include "SkSLUtil.h" 58 class GrGLSLRRectBlurEffect : public GrGLSLFragmentProcessor { 59 public: 60 GrGLSLRRectBlurEffect() {} 61 void emitCode(EmitArgs& args) override { 62 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 63 const GrRRectBlurEffect& _outer = args.fFp.cast<GrRRectBlurEffect>(); 64 (void)_outer; 65 auto sigma = _outer.sigma(); 66 (void)sigma; 67 auto rect = _outer.rect(); 68 (void)rect; 69 auto cornerRadius = _outer.cornerRadius(); 70 (void)cornerRadius; 71 fCornerRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, 72 kDefault_GrSLPrecision, "cornerRadius"); 73 fProxyRectVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType, 74 kDefault_GrSLPrecision, "proxyRect"); 75 fBlurRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, 76 kDefault_GrSLPrecision, "blurRadius"); 77 fragBuilder->codeAppendf( 78 "\nhalf2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf threshold = " 79 "half(%s + 2.0 * float(%s));\nhalf2 middle = half2((%s.zw - %s.xy) - 2.0 * " 80 "float(threshold));\nif (translatedFragPos.x >= threshold && translatedFragPos.x < " 81 "middle.x + threshold) {\n translatedFragPos.x = threshold;\n} else if " 82 "(translatedFragPos.x >= middle.x + threshold) {\n translatedFragPos.x -= " 83 "float(middle.x) - 1.0;\n}\nif (translatedFragPos.y > threshold && " 84 "translatedFragPos.y < middle.y + threshold) {\n translatedFr", 85 args.fUniformHandler->getUniformCStr(fProxyRectVar), 86 args.fUniformHandler->getUniformCStr(fCornerRadiusVar), 87 args.fUniformHandler->getUniformCStr(fBlurRadiusVar), 88 args.fUniformHandler->getUniformCStr(fProxyRectVar), 89 args.fUniformHandler->getUniformCStr(fProxyRectVar)); 90 fragBuilder->codeAppendf( 91 "agPos.y = threshold;\n} else if (translatedFragPos.y >= middle.y + threshold) {\n " 92 " translatedFragPos.y -= float(middle.y) - 1.0;\n}\nhalf2 proxyDims = " 93 "half2(half(2.0 * float(threshold) + 1.0));\nhalf2 texCoord = translatedFragPos / " 94 "proxyDims;\n%s = %s * texture(%s, float2(texCoord)).%s;\n", 95 args.fOutputColor, args.fInputColor ? args.fInputColor : "half4(1)", 96 fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), 97 fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str()); 98 } 99 100 private: 101 void onSetData(const GrGLSLProgramDataManager& pdman, 102 const GrFragmentProcessor& _proc) override { 103 const GrRRectBlurEffect& _outer = _proc.cast<GrRRectBlurEffect>(); 104 { pdman.set1f(fCornerRadiusVar, _outer.cornerRadius()); } 105 auto sigma = _outer.sigma(); 106 (void)sigma; 107 auto rect = _outer.rect(); 108 (void)rect; 109 UniformHandle& cornerRadius = fCornerRadiusVar; 110 (void)cornerRadius; 111 GrSurfaceProxy& ninePatchSamplerProxy = *_outer.textureSampler(0).proxy(); 112 GrTexture& ninePatchSampler = *ninePatchSamplerProxy.priv().peekTexture(); 113 (void)ninePatchSampler; 114 UniformHandle& proxyRect = fProxyRectVar; 115 (void)proxyRect; 116 UniformHandle& blurRadius = fBlurRadiusVar; 117 (void)blurRadius; 118 119 float blurRadiusValue = 3.f * SkScalarCeilToScalar(sigma - 1 / 6.0f); 120 pdman.set1f(blurRadius, blurRadiusValue); 121 122 SkRect outset = rect; 123 outset.outset(blurRadiusValue, blurRadiusValue); 124 pdman.set4f(proxyRect, outset.fLeft, outset.fTop, outset.fRight, outset.fBottom); 125 } 126 UniformHandle fProxyRectVar; 127 UniformHandle fBlurRadiusVar; 128 UniformHandle fCornerRadiusVar; 129 }; 130 GrGLSLFragmentProcessor* GrRRectBlurEffect::onCreateGLSLInstance() const { 131 return new GrGLSLRRectBlurEffect(); 132 } 133 void GrRRectBlurEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, 134 GrProcessorKeyBuilder* b) const {} 135 bool GrRRectBlurEffect::onIsEqual(const GrFragmentProcessor& other) const { 136 const GrRRectBlurEffect& that = other.cast<GrRRectBlurEffect>(); 137 (void)that; 138 if (fSigma != that.fSigma) return false; 139 if (fRect != that.fRect) return false; 140 if (fCornerRadius != that.fCornerRadius) return false; 141 if (fNinePatchSampler != that.fNinePatchSampler) return false; 142 return true; 143 } 144 GrRRectBlurEffect::GrRRectBlurEffect(const GrRRectBlurEffect& src) 145 : INHERITED(kGrRRectBlurEffect_ClassID, src.optimizationFlags()) 146 , fSigma(src.fSigma) 147 , fRect(src.fRect) 148 , fCornerRadius(src.fCornerRadius) 149 , fNinePatchSampler(src.fNinePatchSampler) { 150 this->addTextureSampler(&fNinePatchSampler); 151 } 152 std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::clone() const { 153 return std::unique_ptr<GrFragmentProcessor>(new GrRRectBlurEffect(*this)); 154 } 155 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); 156 #if GR_TEST_UTILS 157 std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d) { 158 SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f); 159 SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f); 160 SkScalar r = d->fRandom->nextRangeF(1.f, 9.f); 161 SkScalar sigma = d->fRandom->nextRangeF(1.f, 10.f); 162 SkRRect rrect; 163 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); 164 return GrRRectBlurEffect::Make(d->context(), sigma, sigma, rrect, rrect); 165 } 166 #endif 167 #endif 168