• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 GrConvolutionEffect_DEFINED
9 #define GrConvolutionEffect_DEFINED
10 
11 #include "Gr1DKernelEffect.h"
12 #include "GrInvariantOutput.h"
13 
14 /**
15  * A convolution effect. The kernel is specified as an array of 2 * half-width
16  * + 1 weights. Each texel is multiplied by it's weight and summed to determine
17  * the output color. The output color is modulated by the input color.
18  */
19 class GrConvolutionEffect : public Gr1DKernelEffect {
20 
21 public:
22 
23     /// Convolve with an arbitrary user-specified kernel
Create(GrTexture * tex,Direction dir,int halfWidth,const float * kernel,bool useBounds,float bounds[2])24     static GrFragmentProcessor* Create(GrTexture* tex,
25                                        Direction dir,
26                                        int halfWidth,
27                                        const float* kernel,
28                                        bool useBounds,
29                                        float bounds[2]) {
30         return new GrConvolutionEffect(tex, dir, halfWidth, kernel, useBounds, bounds);
31     }
32 
33     /// Convolve with a Gaussian kernel
CreateGaussian(GrTexture * tex,Direction dir,int halfWidth,float gaussianSigma,bool useBounds,float bounds[2])34     static GrFragmentProcessor* CreateGaussian(GrTexture* tex,
35                                                Direction dir,
36                                                int halfWidth,
37                                                float gaussianSigma,
38                                                bool useBounds,
39                                                float bounds[2]) {
40         return new GrConvolutionEffect(tex, dir, halfWidth, gaussianSigma, useBounds, bounds);
41     }
42 
43     virtual ~GrConvolutionEffect();
44 
kernel()45     const float* kernel() const { return fKernel; }
46 
bounds()47     const float* bounds() const { return fBounds; }
useBounds()48     bool useBounds() const { return fUseBounds; }
49 
name()50     const char* name() const override { return "Convolution"; }
51 
52     enum {
53         // This was decided based on the min allowed value for the max texture
54         // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
55         // on a blur filter gives a kernel width of 25 while a sigma of 5.0
56         // would exceed a 32 wide kernel.
57         kMaxKernelRadius = 12,
58         // With a C++11 we could have a constexpr version of WidthFromRadius()
59         // and not have to duplicate this calculation.
60         kMaxKernelWidth = 2 * kMaxKernelRadius + 1,
61     };
62 
63 protected:
64 
65     float fKernel[kMaxKernelWidth];
66     bool fUseBounds;
67     float fBounds[2];
68 
69 private:
70     GrConvolutionEffect(GrTexture*, Direction,
71                         int halfWidth,
72                         const float* kernel,
73                         bool useBounds,
74                         float bounds[2]);
75 
76     /// Convolve with a Gaussian kernel
77     GrConvolutionEffect(GrTexture*, Direction,
78                         int halfWidth,
79                         float gaussianSigma,
80                         bool useBounds,
81                         float bounds[2]);
82 
83     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
84 
85     void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
86 
87     bool onIsEqual(const GrFragmentProcessor&) const override;
88 
onComputeInvariantOutput(GrInvariantOutput * inout)89     void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
90         // If the texture was opaque we could know that the output color if we knew the sum of the
91         // kernel values.
92         inout->mulByUnknownFourComponents();
93     }
94 
95     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
96 
97     typedef Gr1DKernelEffect INHERITED;
98 };
99 
100 #endif
101