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 new GrMatrixConvolutionEffect(texture, bounds, kernelSize, kernel, gain, bias,
31                                              kernelOffset, tileMode, convolveAlpha);
32     }
33 
34     static GrFragmentProcessor* CreateGaussian(GrTexture* texture,
35                                                const SkIRect& bounds,
36                                                const SkISize& kernelSize,
37                                                SkScalar gain,
38                                                SkScalar bias,
39                                                const SkIPoint& kernelOffset,
40                                                GrTextureDomain::Mode tileMode,
41                                                bool convolveAlpha,
42                                                SkScalar sigmaX,
43                                                SkScalar sigmaY);
44 
bounds()45     const SkIRect& bounds() const { return fBounds; }
kernelSize()46     const SkISize& kernelSize() const { return fKernelSize; }
kernelOffset()47     const float* kernelOffset() const { return fKernelOffset; }
kernel()48     const float* kernel() const { return fKernel; }
gain()49     float gain() const { return fGain; }
bias()50     float bias() const { return fBias; }
convolveAlpha()51     bool convolveAlpha() const { return fConvolveAlpha; }
domain()52     const GrTextureDomain& domain() const { return fDomain; }
53 
name()54     const char* name() const override { return "MatrixConvolution"; }
55 
56 private:
57     GrMatrixConvolutionEffect(GrTexture*,
58                               const SkIRect& bounds,
59                               const SkISize& kernelSize,
60                               const SkScalar* kernel,
61                               SkScalar gain,
62                               SkScalar bias,
63                               const SkIPoint& kernelOffset,
64                               GrTextureDomain::Mode tileMode,
65                               bool convolveAlpha);
66 
67     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
68 
69     void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
70 
71     bool onIsEqual(const GrFragmentProcessor&) const override;
72 
onComputeInvariantOutput(GrInvariantOutput * inout)73     void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
74         // TODO: Try to do better?
75         inout->mulByUnknownFourComponents();
76     }
77 
78     SkIRect         fBounds;
79     SkISize         fKernelSize;
80     float           fKernel[MAX_KERNEL_SIZE];
81     float           fGain;
82     float           fBias;
83     float           fKernelOffset[2];
84     bool            fConvolveAlpha;
85     GrTextureDomain fDomain;
86 
87     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
88 
89     typedef GrSingleTextureEffect INHERITED;
90 };
91 
92 #endif
93