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