Chromium Code Reviews| Index: src/effects/SkGaussianEdgeShader.cpp |
| diff --git a/src/effects/SkGaussianEdgeShader.cpp b/src/effects/SkGaussianEdgeShader.cpp |
| index 01b0606c01b02d09d27854ba2783d87a5aa9734b..2c59a17fc75738fef7408bb4771651dfbf1f5976 100644 |
| --- a/src/effects/SkGaussianEdgeShader.cpp |
| +++ b/src/effects/SkGaussianEdgeShader.cpp |
| @@ -12,14 +12,25 @@ |
| /** \class SkGaussianEdgeShaderImpl |
| This subclass of shader applies a Gaussian to shadow edge |
| + If largerBlur is false: |
| The radius of the Gaussian blur is specified by the g value of the color, in 6.2 fixed point. |
| For spot shadows, we increase the stroke width to set the shadow against the shape. This pad |
| is specified by b, also in 6.2 fixed point. The r value represents the max final alpha. |
| The incoming alpha should be 1. |
| + |
| + If largerBlur is true: |
| + The radius of the Gaussian blur is specified by the r & g values of the color in 14.2 fixed point. |
| + For spot shadows, we increase the stroke width to set the shadow against the shape. This pad |
| + is specified by b, also in 6.2 fixed point. The a value represents the max final alpha. |
| + |
|
herb_g
2016/09/09 21:06:47
Add a TODO about removing largerBlur when the dep
|
| */ |
| class SkGaussianEdgeShaderImpl : public SkShader { |
| public: |
| - SkGaussianEdgeShaderImpl() {} |
| + SkGaussianEdgeShaderImpl() |
| + : fLargerBlur(false) {} |
| + |
| + SkGaussianEdgeShaderImpl(bool largerBlur) |
| + : fLargerBlur(largerBlur) {} |
| bool isOpaque() const override; |
| @@ -35,6 +46,7 @@ protected: |
| private: |
| friend class SkGaussianEdgeShader; |
| + bool fLargerBlur; |
| typedef SkShader INHERITED; |
| }; |
| @@ -55,7 +67,7 @@ private: |
| class GaussianEdgeFP : public GrFragmentProcessor { |
| public: |
| - GaussianEdgeFP() { |
| + GaussianEdgeFP(bool largerBlur) : fLargerBlur(largerBlur) { |
| this->initClassID<GaussianEdgeFP>(); |
| // enable output of distance information for shape |
| @@ -64,7 +76,7 @@ public: |
| class GLSLGaussianEdgeFP : public GrGLSLFragmentProcessor { |
| public: |
| - GLSLGaussianEdgeFP() {} |
| + GLSLGaussianEdgeFP(bool largerBlur) : fLargerBlur(largerBlur) {} |
| void emitCode(EmitArgs& args) override { |
| GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| @@ -74,28 +86,39 @@ public: |
| " returning grey in GLSLGaussianEdgeFP\n"); |
| fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor); |
| fragBuilder->codeAppendf("%s = vec4(0, 0, 0, color.r);", args.fOutputColor); |
| + } else if (fLargerBlur) { |
| + fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor); |
| + fragBuilder->codeAppend("float radius = color.r*256*64 + color.g*64;"); |
| + fragBuilder->codeAppend("float pad = color.b*64;"); |
| + |
| + fragBuilder->codeAppendf("float factor = 1 - clamp((%s.z - pad)/radius, 0, 1);", |
| + fragBuilder->distanceVectorName()); |
| + fragBuilder->codeAppend("factor = exp(-factor * factor * 4) - 0.018;"); |
| + fragBuilder->codeAppendf("%s = factor*vec4(0, 0, 0, color.a);", |
| + args.fOutputColor); |
| } else { |
| fragBuilder->codeAppendf("vec4 color = %s;", args.fInputColor); |
| - fragBuilder->codeAppend("float radius = color.g*64.0;"); |
| - fragBuilder->codeAppend("float pad = color.b*64.0;"); |
| + fragBuilder->codeAppend("float radius = color.g*64;"); |
| + fragBuilder->codeAppend("float pad = color.b*64;"); |
| - fragBuilder->codeAppendf("float factor = 1.0 - clamp((%s.z - pad)/radius," |
| - "0.0, 1.0);", |
| + fragBuilder->codeAppendf("float factor = 1 - clamp((%s.z - pad)/radius, 0, 1);", |
| fragBuilder->distanceVectorName()); |
| - fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); |
| - fragBuilder->codeAppendf("%s = factor*vec4(0.0, 0.0, 0.0, color.r);", |
| + fragBuilder->codeAppend("factor = exp(-factor * factor * 4) - 0.018;"); |
| + fragBuilder->codeAppendf("%s = factor*vec4(0, 0, 0, color.r);", |
| args.fOutputColor); |
| } |
| } |
| static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
| GrProcessorKeyBuilder* b) { |
| - // only one shader generated currently |
| - b->add32(0x0); |
| + const GaussianEdgeFP& gefp = proc.cast<GaussianEdgeFP>(); |
| + b->add32(gefp.fLargerBlur ? 0x1 : 0x0); |
| } |
| protected: |
| void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {} |
| + |
| + bool fLargerBlur; |
| }; |
| void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { |
| @@ -109,15 +132,19 @@ public: |
| } |
| private: |
| - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLGaussianEdgeFP; } |
| + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
| + return new GLSLGaussianEdgeFP(fLargerBlur); |
| + } |
| bool onIsEqual(const GrFragmentProcessor& proc) const override { return true; } |
| + |
| + bool fLargerBlur; |
| }; |
| //////////////////////////////////////////////////////////////////////////// |
| sk_sp<GrFragmentProcessor> SkGaussianEdgeShaderImpl::asFragmentProcessor(const AsFPArgs& args) const { |
| - return sk_make_sp<GaussianEdgeFP>(); |
| + return sk_make_sp<GaussianEdgeFP>(fLargerBlur); |
| } |
| #endif |
| @@ -145,8 +172,8 @@ void SkGaussianEdgeShaderImpl::flatten(SkWriteBuffer& buf) const { |
| /////////////////////////////////////////////////////////////////////////////// |
| -sk_sp<SkShader> SkGaussianEdgeShader::Make() { |
| - return sk_make_sp<SkGaussianEdgeShaderImpl>(); |
| +sk_sp<SkShader> SkGaussianEdgeShader::Make(bool largerBlur) { |
| + return sk_make_sp<SkGaussianEdgeShaderImpl>(largerBlur); |
| } |
| /////////////////////////////////////////////////////////////////////////////// |