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
19class GrMatrixConvolutionEffect : public GrSingleTextureEffect {
20public:
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
54    const SkIRect& bounds() const { return fBounds; }
55    const SkISize& kernelSize() const { return fKernelSize; }
56    const float* kernelOffset() const { return fKernelOffset; }
57    const float* kernel() const { return fKernel; }
58    float gain() const { return fGain; }
59    float bias() const { return fBias; }
60    bool convolveAlpha() const { return fConvolveAlpha; }
61    const GrTextureDomain& domain() const { return fDomain; }
62
63    const char* name() const override { return "MatrixConvolution"; }
64
65    void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
66
67    GrGLFragmentProcessor* createGLInstance() const override;
68
69private:
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
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