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 "glsl/GrGLSLFragmentProcessor.h"
     14 
     15 class GrGLBicubicEffect;
     16 class GrInvariantOutput;
     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     const float* coefficients() const { return fCoefficients; }
     27 
     28     const char* name() const override { return "Bicubic"; }
     29 
     30     const GrTextureDomain& domain() const { return fDomain; }
     31 
     32     /**
     33      * Create a simple filter effect with custom bicubic coefficients and optional domain.
     34      */
     35     static const GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
     36                                              const SkRect* domain = nullptr) {
     37         if (nullptr == domain) {
     38             static const SkShader::TileMode kTileModes[] = { SkShader::kClamp_TileMode,
     39                                                              SkShader::kClamp_TileMode };
     40             return Create(tex, coefficients, GrCoordTransform::MakeDivByTextureWHMatrix(tex),
     41                           kTileModes);
     42         } else {
     43             return new GrBicubicEffect(tex, coefficients,
     44                                        GrCoordTransform::MakeDivByTextureWHMatrix(tex), *domain);
     45         }
     46     }
     47 
     48     /**
     49      * Create a Mitchell filter effect with specified texture matrix and x/y tile modes.
     50      */
     51     static const GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
     52                                              const SkShader::TileMode tileModes[2]) {
     53         return Create(tex, gMitchellCoefficients, matrix, tileModes);
     54     }
     55 
     56     /**
     57      * Create a filter effect with custom bicubic coefficients, the texture matrix, and the x/y
     58      * tilemodes.
     59      */
     60     static const GrFragmentProcessor* Create(GrTexture* tex, const SkScalar coefficients[16],
     61                                              const SkMatrix& matrix,
     62                                              const SkShader::TileMode tileModes[2]) {
     63         return new GrBicubicEffect(tex, coefficients, matrix, tileModes);
     64     }
     65 
     66     /**
     67      * Create a Mitchell filter effect with a texture matrix and a domain.
     68      */
     69     static const GrFragmentProcessor* Create(GrTexture* tex, const SkMatrix& matrix,
     70                                              const SkRect& domain) {
     71         return new GrBicubicEffect(tex, gMitchellCoefficients, matrix, domain);
     72     }
     73 
     74     /**
     75      * Determines whether the bicubic effect should be used based on the transformation from the
     76      * local coords to the device. Returns true if the bicubic effect should be used. filterMode
     77      * is set to appropriate filtering mode to use regardless of the return result (e.g. when this
     78      * returns false it may indicate that the best fallback is to use kMipMap, kBilerp, or
     79      * kNearest).
     80      */
     81     static bool ShouldUseBicubic(const SkMatrix& localCoordsToDevice,
     82                                  GrTextureParams::FilterMode* filterMode);
     83 
     84 private:
     85     GrBicubicEffect(GrTexture*, const SkScalar coefficients[16], const SkMatrix &matrix,
     86                     const SkShader::TileMode tileModes[2]);
     87     GrBicubicEffect(GrTexture*, const SkScalar coefficients[16], const SkMatrix &matrix,
     88                     const SkRect& domain);
     89 
     90     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
     91 
     92     void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
     93 
     94     bool onIsEqual(const GrFragmentProcessor&) const override;
     95 
     96     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
     97 
     98     float           fCoefficients[16];
     99     GrTextureDomain fDomain;
    100 
    101     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
    102 
    103     static const SkScalar gMitchellCoefficients[16];
    104 
    105     typedef GrSingleTextureEffect INHERITED;
    106 };
    107 
    108 #endif
    109