1 /*
2  * Copyright 2014 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 GrMatrixConvolutionEffect_DEFINED
9 #define GrMatrixConvolutionEffect_DEFINED
10 
11 #include "GrSingleTextureEffect.h"
12 #include "GrInvariantOutput.h"
13 #include "GrTextureDomain.h"
14 
15 // A little bit less than the minimum # uniforms required by DX9SM2 (32).
16 // Allows for a 5x5 kernel (or 25x1, for that matter).
17 #define MAX_KERNEL_SIZE 25
18 
19 class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
20 public:
Create(GrTexture * texture,const SkIRect & bounds,const SkISize & kernelSize,const SkScalar * kernel,SkScalar gain,SkScalar bias,const SkIPoint & kernelOffset,GrTextureDomain::Mode tileMode,bool convolveAlpha)21     static GrFragmentProcessor* Create(GrTexture* texture,
22                                        const SkIRect& bounds,
23                                        const SkISize& kernelSize,
24                                        const SkScalar* kernel,
25                                        SkScalar gain,
26                                        SkScalar bias,
27                                        const SkIPoint& kernelOffset,
28                                        GrTextureDomain::Mode tileMode,
29                                        bool convolveAlpha) {
30         return SkNEW_ARGS(GrMatrixConvolutionEffect, (texture,
31                                                       bounds,
32                                                       kernelSize,
33                                                       kernel,
34                                                       gain,
35                                                       bias,
36                                                       kernelOffset,
37                                                       tileMode,
38                                                       convolveAlpha));
39     }
40 
41     static GrFragmentProcessor* CreateGaussian(GrTexture* texture,
42                                                const SkIRect& bounds,
43                                                const SkISize& kernelSize,
44                                                SkScalar gain,
45                                                SkScalar bias,
46                                                const SkIPoint& kernelOffset,
47                                                GrTextureDomain::Mode tileMode,
48                                                bool convolveAlpha,
49                                                SkScalar sigmaX,
50                                                SkScalar sigmaY);
51 
52     virtual ~GrMatrixConvolutionEffect();
53 
bounds()54     const SkIRect& bounds() const { return fBounds; }
kernelSize()55     const SkISize& kernelSize() const { return fKernelSize; }
kernelOffset()56     const float* kernelOffset() const { return fKernelOffset; }
kernel()57     const float* kernel() const { return fKernel; }
gain()58     float gain() const { return fGain; }
bias()59     float bias() const { return fBias; }
convolveAlpha()60     bool convolveAlpha() const { return fConvolveAlpha; }
domain()61     const GrTextureDomain& domain() const { return fDomain; }
62 
name()63     const char* name() const override { return "MatrixConvolution"; }
64 
65     void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
66 
67     GrGLFragmentProcessor* createGLInstance() const override;
68 
69 private:
70     GrMatrixConvolutionEffect(GrTexture*,
71                               const SkIRect& bounds,
72                               const SkISize& kernelSize,
73                               const SkScalar* kernel,
74                               SkScalar gain,
75                               SkScalar bias,
76                               const SkIPoint& kernelOffset,
77                               GrTextureDomain::Mode tileMode,
78                               bool convolveAlpha);
79 
80     bool onIsEqual(const GrFragmentProcessor&) const override;
81 
onComputeInvariantOutput(GrInvariantOutput * inout)82     void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
83         // TODO: Try to do better?
84         inout->mulByUnknownFourComponents();
85     }
86 
87     SkIRect         fBounds;
88     SkISize         fKernelSize;
89     float           fKernel[MAX_KERNEL_SIZE];
90     float           fGain;
91     float           fBias;
92     float           fKernelOffset[2];
93     bool            fConvolveAlpha;
94     GrTextureDomain fDomain;
95 
96     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
97 
98     typedef GrSingleTextureEffect INHERITED;
99 };
100 
101 #endif
102