| Index: src/effects/SkGaussianEdgeShader.cpp
|
| diff --git a/src/effects/SkGaussianEdgeShader.cpp b/src/effects/SkGaussianEdgeShader.cpp
|
| index 01b0606c01b02d09d27854ba2783d87a5aa9734b..a7c27004be8459e43351875612f18e378aba15f0 100644
|
| --- a/src/effects/SkGaussianEdgeShader.cpp
|
| +++ b/src/effects/SkGaussianEdgeShader.cpp
|
| @@ -12,14 +12,26 @@
|
| /** \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.
|
| +
|
| + LargerBlur will be removed once Android is migrated to the updated shader.
|
| */
|
| class SkGaussianEdgeShaderImpl : public SkShader {
|
| public:
|
| - SkGaussianEdgeShaderImpl() {}
|
| + SkGaussianEdgeShaderImpl()
|
| + : fLargerBlur(false) {}
|
| +
|
| + SkGaussianEdgeShaderImpl(bool largerBlur)
|
| + : fLargerBlur(largerBlur) {}
|
|
|
| bool isOpaque() const override;
|
|
|
| @@ -35,6 +47,7 @@ protected:
|
|
|
| private:
|
| friend class SkGaussianEdgeShader;
|
| + bool fLargerBlur;
|
|
|
| typedef SkShader INHERITED;
|
| };
|
| @@ -55,7 +68,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 +77,7 @@ public:
|
|
|
| class GLSLGaussianEdgeFP : public GrGLSLFragmentProcessor {
|
| public:
|
| - GLSLGaussianEdgeFP() {}
|
| + GLSLGaussianEdgeFP(bool largerBlur) : fLargerBlur(largerBlur) {}
|
|
|
| void emitCode(EmitArgs& args) override {
|
| GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
| @@ -74,28 +87,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 +133,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 +173,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);
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|