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