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