Chromium Code Reviews| Index: src/effects/SkGaussianEdgeShader.cpp |
| diff --git a/src/effects/SkGaussianEdgeShader.cpp b/src/effects/SkGaussianEdgeShader.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..cdf08a542f3f45f8d3f5d7a1d9a1139d86727c99 |
| --- /dev/null |
| +++ b/src/effects/SkGaussianEdgeShader.cpp |
| @@ -0,0 +1,156 @@ |
| +/* |
| + * Copyright 2016 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#include "SkGaussianEdgeShader.h" |
| +#include "SkReadBuffer.h" |
| +#include "SkWriteBuffer.h" |
| + |
| + /** \class SkGaussianEdgeShaderImpl |
| + This subclass of shader applies a Gaussian to shadow edge |
| + */ |
| +class SkGaussianEdgeShaderImpl : public SkShader { |
| +public: |
|
robertphillips
2016/08/16 17:56:07
Ditch comment ?
jvanverth1
2016/08/16 19:14:11
Done.
|
| + /** Create a new lighting shader that uses the provided normal map and |
| + lights to light the diffuse bitmap. |
| + @param diffuseShader the shader that provides the diffuse colors |
| + */ |
| + SkGaussianEdgeShaderImpl() {} |
| + |
| + bool isOpaque() const override; |
| + |
| +#if SK_SUPPORT_GPU |
| + sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; |
| +#endif |
| + |
| + SK_TO_STRING_OVERRIDE() |
| + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkGaussianEdgeShaderImpl) |
| + |
| +protected: |
| + void flatten(SkWriteBuffer&) const override; |
| + |
| +private: |
| + friend class SkGaussianEdgeShader; |
| + |
| + typedef SkShader INHERITED; |
| +}; |
| + |
| +//////////////////////////////////////////////////////////////////////////// |
| + |
| +#if SK_SUPPORT_GPU |
| + |
| +#include "GrCoordTransform.h" |
| +#include "GrFragmentProcessor.h" |
| +#include "GrInvariantOutput.h" |
| +#include "glsl/GrGLSLFragmentProcessor.h" |
| +#include "glsl/GrGLSLFragmentShaderBuilder.h" |
| +#include "glsl/GrGLSLProgramDataManager.h" |
| +#include "glsl/GrGLSLUniformHandler.h" |
| +#include "SkGr.h" |
| +#include "SkGrPriv.h" |
| + |
| +class GaussianEdgeFP : public GrFragmentProcessor { |
| +public: |
| + GaussianEdgeFP() { |
| + this->initClassID<GaussianEdgeFP>(); |
| + |
|
robertphillips
2016/08/16 17:56:07
delete ?
jvanverth1
2016/08/16 19:14:11
No, it's needed.
|
| + fUsesDistanceVectorField = true; |
| + } |
| + |
| + class GLSLGaussianEdgeFP : public GrGLSLFragmentProcessor { |
| + public: |
| + GLSLGaussianEdgeFP() {} |
| + |
| + void emitCode(EmitArgs& args) override { |
| + |
| + GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; |
| + |
| + fragBuilder->codeAppendf("vec4 output = %s;", args.fInputColor); |
| + // outside the outer edge |
| + fragBuilder->codeAppendf("if (%s.z <= 0) {", fragBuilder->distanceVectorName()); |
| + fragBuilder->codeAppend("output *= 0.0;"); |
| + // inside the stroke |
| + fragBuilder->codeAppendf("} else if (%s.w > 0) {", fragBuilder->distanceVectorName()); |
| + fragBuilder->codeAppendf("float factor = %s.w/(%s.z + %s.w);", |
| + fragBuilder->distanceVectorName(), |
| + fragBuilder->distanceVectorName(), |
| + fragBuilder->distanceVectorName()); |
| + fragBuilder->codeAppend("factor = exp(-factor * factor * 4.0) - 0.018;"); |
| + fragBuilder->codeAppend("output *= factor;"); |
| + fragBuilder->codeAppend("}"); |
| + fragBuilder->codeAppendf("%s = output;", args.fOutputColor); |
| + } |
| + |
| + static void GenKey(const GrProcessor& proc, const GrGLSLCaps&, |
| + GrProcessorKeyBuilder* b) { |
|
robertphillips
2016/08/16 17:56:07
kill dead code ?
jvanverth1
2016/08/16 19:14:11
Done.
|
| + // const GaussianEdgeFP& GaussianEdgeFP = proc.cast<GaussianEdgeFP>(); |
| + // only one shader generated currently |
| + b->add32(0x0); |
| + } |
| + |
| + protected: |
| + void onSetData(const GrGLSLProgramDataManager& pdman, const GrProcessor& proc) override {} |
| + }; |
| + |
| + void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { |
| + GLSLGaussianEdgeFP::GenKey(*this, caps, b); |
| + } |
| + |
| + const char* name() const override { return "GaussianEdgeFP"; } |
| + |
| + void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| + inout->mulByUnknownFourComponents(); |
| + } |
| + |
| +private: |
| + GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new GLSLGaussianEdgeFP; } |
| + |
| + bool onIsEqual(const GrFragmentProcessor& proc) const override { return true; } |
| +}; |
| + |
| +//////////////////////////////////////////////////////////////////////////// |
| + |
| +sk_sp<GrFragmentProcessor> SkGaussianEdgeShaderImpl::asFragmentProcessor(const AsFPArgs& args) const { |
| + return sk_make_sp<GaussianEdgeFP>(); |
| +} |
| + |
| +#endif |
| + |
|
robertphillips
2016/08/16 17:56:07
Does raster crash ?
jvanverth1
2016/08/16 19:14:11
Nope, just draws nothing. Added to comment.
|
| +//////////////////////////////////////////////////////////////////////////// |
| + |
| +bool SkGaussianEdgeShaderImpl::isOpaque() const { |
| + return false; |
| +} |
| + |
| +//////////////////////////////////////////////////////////////////////////// |
| + |
| +#ifndef SK_IGNORE_TO_STRING |
| +void SkGaussianEdgeShaderImpl::toString(SkString* str) const { |
| + str->appendf("GaussianEdgeShader: ()"); |
| +} |
| +#endif |
| + |
| +sk_sp<SkFlattenable> SkGaussianEdgeShaderImpl::CreateProc(SkReadBuffer& buf) { |
| + return sk_make_sp<SkGaussianEdgeShaderImpl>(); |
| +} |
| + |
| +void SkGaussianEdgeShaderImpl::flatten(SkWriteBuffer& buf) const { |
| + this->INHERITED::flatten(buf); |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +sk_sp<SkShader> SkGaussianEdgeShader::Make() { |
| + return sk_make_sp<SkGaussianEdgeShaderImpl>(); |
| +} |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| +SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGaussianEdgeShader) |
| +SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkGaussianEdgeShaderImpl) |
| +SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |