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