| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrCircleBlurFragmentProcessor_DEFINED |
| #define GrCircleBlurFragmentProcessor_DEFINED |
| |
| #include "SkString.h" |
| #include "SkTypes.h" |
| |
| #if SK_SUPPORT_GPU |
| |
| #include "GrFragmentProcessor.h" |
| #include "GrProcessorUnitTest.h" |
| |
| class GrTextureProvider; |
| |
| // This FP handles the special case of a blurred circle. It uses a 1D |
| // profile that is just rotated about the origin of the circle. |
| class GrCircleBlurFragmentProcessor : public GrFragmentProcessor { |
| public: |
| ~GrCircleBlurFragmentProcessor() override {}; |
| |
| const char* name() const override { return "CircleBlur"; } |
| |
| SkString dumpInfo() const override { |
| SkString str; |
| str.appendf("Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f], Sigma %.2f, Offset: %.2f", |
| fCircle.fLeft, fCircle.fTop, fCircle.fRight, fCircle.fBottom, |
| fSigma, fOffset); |
| return str; |
| } |
| |
| static const GrFragmentProcessor* Create(GrTextureProvider*textureProvider, |
| const SkRect& circle, float sigma) { |
| float offset; |
| |
| SkAutoTUnref<GrTexture> blurProfile(CreateCircleBlurProfileTexture(textureProvider, |
| circle, |
| sigma, |
| &offset)); |
| if (!blurProfile) { |
| return nullptr; |
| } |
| return new GrCircleBlurFragmentProcessor(circle, sigma, offset, blurProfile); |
| } |
| |
| const SkRect& circle() const { return fCircle; } |
| float sigma() const { return fSigma; } |
| float offset() const { return fOffset; } |
| int profileSize() const { return fBlurProfileAccess.getTexture()->width(); } |
| |
| private: |
| GrCircleBlurFragmentProcessor(const SkRect& circle, float sigma, |
| float offset, GrTexture* blurProfile); |
| |
| GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; |
| |
| void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override; |
| |
| bool onIsEqual(const GrFragmentProcessor& other) const override { |
| const GrCircleBlurFragmentProcessor& cbfp = other.cast<GrCircleBlurFragmentProcessor>(); |
| // fOffset is computed from the circle width and the sigma |
| return this->circle().width() == cbfp.circle().width() && fSigma == cbfp.fSigma; |
| } |
| |
| void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
| |
| static GrTexture* CreateCircleBlurProfileTexture(GrTextureProvider*, |
| const SkRect& circle, |
| float sigma, float* offset); |
| |
| SkRect fCircle; |
| float fSigma; |
| float fOffset; |
| GrTextureAccess fBlurProfileAccess; |
| |
| GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| |
| typedef GrFragmentProcessor INHERITED; |
| }; |
| |
| #endif |
| #endif |