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