Home | History | Annotate | Download | only in effects
      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
     25     static GrFragmentProcessor* Create(GrTexture* tex,
     26                                        Direction dir,
     27                                        int halfWidth,
     28                                        const float* kernel,
     29                                        bool useBounds,
     30                                        float bounds[2]) {
     31         return SkNEW_ARGS(GrConvolutionEffect, (tex,
     32                                                 dir,
     33                                                 halfWidth,
     34                                                 kernel,
     35                                                 useBounds,
     36                                                 bounds));
     37     }
     38 
     39     /// Convolve with a Gaussian kernel
     40     static GrFragmentProcessor* CreateGaussian(GrTexture* tex,
     41                                                Direction dir,
     42                                                int halfWidth,
     43                                                float gaussianSigma,
     44                                                bool useBounds,
     45                                                float bounds[2]) {
     46         return SkNEW_ARGS(GrConvolutionEffect, (tex,
     47                                                 dir,
     48                                                 halfWidth,
     49                                                 gaussianSigma,
     50                                                 useBounds,
     51                                                 bounds));
     52     }
     53 
     54     virtual ~GrConvolutionEffect();
     55 
     56     const float* kernel() const { return fKernel; }
     57 
     58     const float* bounds() const { return fBounds; }
     59     bool useBounds() const { return fUseBounds; }
     60 
     61     static const char* Name() { return "Convolution"; }
     62 
     63     typedef GrGLConvolutionEffect GLProcessor;
     64 
     65     virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;
     66 
     67     virtual void getConstantColorComponents(GrColor*, uint32_t* validFlags) const {
     68         // If the texture was opaque we could know that the output color if we knew the sum of the
     69         // kernel values.
     70         *validFlags = 0;
     71     }
     72 
     73     enum {
     74         // This was decided based on the min allowed value for the max texture
     75         // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
     76         // on a blur filter gives a kernel width of 25 while a sigma of 5.0
     77         // would exceed a 32 wide kernel.
     78         kMaxKernelRadius = 12,
     79         // With a C++11 we could have a constexpr version of WidthFromRadius()
     80         // and not have to duplicate this calculation.
     81         kMaxKernelWidth = 2 * kMaxKernelRadius + 1,
     82     };
     83 
     84 protected:
     85 
     86     float fKernel[kMaxKernelWidth];
     87     bool fUseBounds;
     88     float fBounds[2];
     89 
     90 private:
     91     GrConvolutionEffect(GrTexture*, Direction,
     92                         int halfWidth,
     93                         const float* kernel,
     94                         bool useBounds,
     95                         float bounds[2]);
     96 
     97     /// Convolve with a Gaussian kernel
     98     GrConvolutionEffect(GrTexture*, Direction,
     99                         int halfWidth,
    100                         float gaussianSigma,
    101                         bool useBounds,
    102                         float bounds[2]);
    103 
    104     virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE;
    105 
    106     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
    107 
    108     typedef Gr1DKernelEffect INHERITED;
    109 };
    110 
    111 #endif
    112