Home | History | Annotate | Download | only in effects
      1 /*
      2  * Copyright 2013 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 GrBicubicTextureEffect_DEFINED
      9 #define GrBicubicTextureEffect_DEFINED
     10 
     11 #include "GrSingleTextureEffect.h"
     12 #include "GrTextureDomain.h"
     13 #include "GrDrawEffect.h"
     14 #include "gl/GrGLEffect.h"
     15 #include "GrTBackendEffectFactory.h"
     16 
     17 class GrGLBicubicEffect;
     18 
     19 class GrBicubicEffect : public GrSingleTextureEffect {
     20 public:
     21     enum {
     22         kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of
     23                              // surrounding texels are needed by the kernel in x and y.
     24     };
     25     virtual ~GrBicubicEffect();
     26 
     27     static const char* Name() { return "Bicubic"; }
     28     const float* coefficients() const { return fCoefficients; }
     29 
     30     typedef GrGLBicubicEffect GLEffect;
     31 
     32     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
     33     virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
     34 
     35     const GrTextureDomain& domain() const { return fDomain; }
     36 
     37     /**
     38      * Create a simple filter effect with custom bicubic coefficients and optional domain.
     39      */
     40     static GrEffectRef* Create(GrTexture* tex, const SkScalar coefficients[16],
     41                                const SkRect* domain = NULL) {
     42         if (NULL == domain) {
     43             static const SkShader::TileMode kTileModes[] = { SkShader::kClamp_TileMode,
     44                                                              SkShader::kClamp_TileMode };
     45             return Create(tex, coefficients, MakeDivByTextureWHMatrix(tex), kTileModes);
     46         } else {
     47             AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, coefficients,
     48                                                                 MakeDivByTextureWHMatrix(tex),
     49                                                                 *domain)));
     50             return CreateEffectRef(effect);
     51         }
     52     }
     53 
     54     /**
     55      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
     56      */
     57     static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix,
     58                                SkShader::TileMode tileModes[2]) {
     59         return Create(tex, gMitchellCoefficients, matrix, tileModes);
     60     }
     61 
     62     /**
     63      * Create a filter effect with custom bicubic coefficients, the texture matrix, and the x/y
     64      * tilemodes.
     65      */
     66     static GrEffectRef* Create(GrTexture* tex, const SkScalar coefficients[16],
     67                                const SkMatrix& matrix, const SkShader::TileMode tileModes[2]) {
     68         AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, coefficients, matrix, tileModes)));
     69         return CreateEffectRef(effect);
     70     }
     71 
     72     /**
     73      * Create a Mitchell filter effect with a texture matrix and a domain.
     74      */
     75     static GrEffectRef* Create(GrTexture* tex, const SkMatrix& matrix, const SkRect& domain) {
     76         AutoEffectUnref effect(SkNEW_ARGS(GrBicubicEffect, (tex, gMitchellCoefficients, matrix,
     77                                                             domain)));
     78         return CreateEffectRef(effect);
     79     }
     80 
     81     /**
     82      * Determines whether the bicubic effect should be used based on the transformation from the
     83      * local coords to the device. Returns true if the bicubic effect should be used. filterMode
     84      * is set to appropriate filtering mode to use regardless of the return result (e.g. when this
     85      * returns false it may indicate that the best fallback is to use kMipMap, kBilerp, or
     86      * kNearest).
     87      */
     88     static bool ShouldUseBicubic(const SkMatrix& localCoordsToDevice,
     89                                  GrTextureParams::FilterMode* filterMode);
     90 
     91 private:
     92     GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
     93                     const SkMatrix &matrix, const SkShader::TileMode tileModes[2]);
     94     GrBicubicEffect(GrTexture*, const SkScalar coefficients[16],
     95                     const SkMatrix &matrix, const SkRect& domain);
     96     virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
     97 
     98     float           fCoefficients[16];
     99     GrTextureDomain fDomain;
    100 
    101     GR_DECLARE_EFFECT_TEST;
    102 
    103     static const SkScalar gMitchellCoefficients[16];
    104 
    105     typedef GrSingleTextureEffect INHERITED;
    106 };
    107 
    108 #endif
    109