Line data Source code
1 : /*
2 : * Copyright 2012 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 : #ifndef GrGaussianConvolutionFragmentProcessor_DEFINED
9 : #define GrGaussianConvolutionFragmentProcessor_DEFINED
10 :
11 : #include "Gr1DKernelEffect.h"
12 :
13 : /**
14 : * A 1D Gaussian convolution effect. The kernel is computed as an array of 2 * half-width weights.
15 : * Each texel is multiplied by it's weight and summed to determine the filtered color. The output
16 : * color is set to a modulation of the filtered and input colors.
17 : */
18 : class GrGaussianConvolutionFragmentProcessor : public Gr1DKernelEffect {
19 : public:
20 : /// Convolve with a Gaussian kernel
21 0 : static sk_sp<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
22 : sk_sp<GrTextureProxy> proxy,
23 : Direction dir,
24 : int halfWidth,
25 : float gaussianSigma,
26 : bool useBounds,
27 : int* bounds) {
28 : return sk_sp<GrFragmentProcessor>(new GrGaussianConvolutionFragmentProcessor(
29 0 : resourceProvider, std::move(proxy), dir, halfWidth, gaussianSigma, useBounds, bounds));
30 : }
31 :
32 : ~GrGaussianConvolutionFragmentProcessor() override;
33 :
34 0 : const float* kernel() const { return fKernel; }
35 :
36 0 : const int* bounds() const { return fBounds; }
37 0 : bool useBounds() const { return fUseBounds; }
38 :
39 0 : const char* name() const override { return "GaussianConvolution"; }
40 :
41 : // This was decided based on the min allowed value for the max texture
42 : // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
43 : // on a blur filter gives a kernel width of 25 while a sigma of 5.0
44 : // would exceed a 32 wide kernel.
45 : static const int kMaxKernelRadius = 12;
46 : // With a C++11 we could have a constexpr version of WidthFromRadius()
47 : // and not have to duplicate this calculation.
48 : static const int kMaxKernelWidth = 2 * kMaxKernelRadius + 1;
49 :
50 : private:
51 : /// Convolve with a Gaussian kernel
52 : GrGaussianConvolutionFragmentProcessor(GrResourceProvider*, sk_sp<GrTextureProxy>, Direction,
53 : int halfWidth, float gaussianSigma, bool useBounds,
54 : int bounds[2]);
55 :
56 : GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
57 :
58 : void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
59 :
60 : bool onIsEqual(const GrFragmentProcessor&) const override;
61 :
62 : GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
63 :
64 : // TODO: Inline the kernel constants into the generated shader code. This may involve pulling
65 : // some of the logic from SkGpuBlurUtils into this class related to radius/sigma calculations.
66 : float fKernel[kMaxKernelWidth];
67 : bool fUseBounds;
68 : int fBounds[2];
69 :
70 : typedef Gr1DKernelEffect INHERITED;
71 : };
72 :
73 : #endif
|