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 13 std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::Make(GrRecordingContext* context, 14 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[kSkBlurRRectMaxDivisions]; 32 int ignoredSize; 33 uint32_t ignored32; 34 35 bool ninePatchable = SkComputeBlurredRRectParams( 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, kHalf_GrSLType, 72 "cornerRadius"); 73 fProxyRectVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType, 74 "proxyRect"); 75 fBlurRadiusVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf_GrSLType, 76 "blurRadius"); 77 fragBuilder->codeAppendf( 78 "\nhalf2 translatedFragPos = half2(sk_FragCoord.xy - %s.xy);\nhalf threshold = %s " 79 "+ 2.0 * %s;\nhalf2 middle = half2((%s.zw - %s.xy) - float(2.0 * threshold));\nif " 80 "(translatedFragPos.x >= threshold && translatedFragPos.x < middle.x + threshold) " 81 "{\n translatedFragPos.x = threshold;\n} else if (translatedFragPos.x >= " 82 "middle.x + threshold) {\n translatedFragPos.x -= middle.x - 1.0;\n}\nif " 83 "(translatedFragPos.y > threshold && translatedFragPos.y < middle.y + threshold) " 84 "{\n translatedFragPos.y = threshold;", 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 "\n} else if (translatedFragPos.y >= middle.y + threshold) {\n " 92 "translatedFragPos.y -= middle.y - 1.0;\n}\nhalf2 proxyDims = half2(2.0 * " 93 "threshold + 1.0);\nhalf2 texCoord = translatedFragPos / proxyDims;\n%s = %s * " 94 "texture(%s, float2(texCoord)).%s;\n", 95 args.fOutputColor, args.fInputColor, 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.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->setTextureSamplerCnt(1); 151 } 152 std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::clone() const { 153 return std::unique_ptr<GrFragmentProcessor>(new GrRRectBlurEffect(*this)); 154 } 155 const GrFragmentProcessor::TextureSampler& GrRRectBlurEffect::onTextureSampler(int index) const { 156 return IthTextureSampler(index, fNinePatchSampler); 157 } 158 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrRRectBlurEffect); 159 #if GR_TEST_UTILS 160 std::unique_ptr<GrFragmentProcessor> GrRRectBlurEffect::TestCreate(GrProcessorTestData* d) { 161 SkScalar w = d->fRandom->nextRangeScalar(100.f, 1000.f); 162 SkScalar h = d->fRandom->nextRangeScalar(100.f, 1000.f); 163 SkScalar r = d->fRandom->nextRangeF(1.f, 9.f); 164 SkScalar sigma = d->fRandom->nextRangeF(1.f, 10.f); 165 SkRRect rrect; 166 rrect.setRectXY(SkRect::MakeWH(w, h), r, r); 167 return GrRRectBlurEffect::Make(d->context(), sigma, sigma, rrect, rrect); 168 } 169 #endif 170