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 "GrTextureDomain.h" 12 #include "glsl/GrGLSLFragmentProcessor.h" 13 14 class GrInvariantOutput; 15 16 class GrBicubicEffect : public GrFragmentProcessor { 17 public: 18 enum { 19 kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of 20 // surrounding texels are needed by the kernel in x and y. 21 }; 22 23 const char* name() const override { return "Bicubic"; } 24 25 std::unique_ptr<GrFragmentProcessor> clone() const override { 26 return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(*this)); 27 } 28 29 const GrTextureDomain& domain() const { return fDomain; } 30 31 /** 32 * Create a Mitchell filter effect with specified texture matrix and x/y tile modes. 33 */ 34 static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy, 35 const SkMatrix& matrix, 36 const GrSamplerState::WrapMode wrapModes[2]) { 37 // Ignore the domain on x and y, since this factory relies solely on the wrap mode of the 38 // sampler to constrain texture coordinates 39 return Make(std::move(proxy), matrix, wrapModes, GrTextureDomain::kIgnore_Mode, 40 GrTextureDomain::kIgnore_Mode); 41 } 42 43 /** 44 * Create a Mitchell filter effect with specified texture matrix and x/y tile modes. This 45 * supports providing modes for the texture domain explicitly, in the event that it should 46 * override the behavior of the sampler's tile mode (e.g. clamp to border unsupported). 47 */ 48 static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy, 49 const SkMatrix& matrix, 50 const GrSamplerState::WrapMode wrapModes[2], 51 GrTextureDomain::Mode modeX, 52 GrTextureDomain::Mode modeY) { 53 return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(std::move(proxy), matrix, 54 wrapModes, modeX, modeY)); 55 } 56 57 /** 58 * Create a Mitchell filter effect with a texture matrix and a domain. 59 */ 60 static std::unique_ptr<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy, 61 const SkMatrix& matrix, 62 const SkRect& domain) { 63 return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(std::move(proxy), matrix, 64 domain)); 65 } 66 67 /** 68 * Determines whether the bicubic effect should be used based on the transformation from the 69 * local coords to the device. Returns true if the bicubic effect should be used. filterMode 70 * is set to appropriate filtering mode to use regardless of the return result (e.g. when this 71 * returns false it may indicate that the best fallback is to use kMipMap, kBilerp, or 72 * kNearest). 73 */ 74 static bool ShouldUseBicubic(const SkMatrix& localCoordsToDevice, 75 GrSamplerState::Filter* filterMode); 76 77 private: 78 GrBicubicEffect(sk_sp<GrTextureProxy>, const SkMatrix& matrix, 79 const GrSamplerState::WrapMode wrapModes[2], 80 GrTextureDomain::Mode modeX, GrTextureDomain::Mode modeY); 81 GrBicubicEffect(sk_sp<GrTextureProxy>, const SkMatrix &matrix, const SkRect& domain); 82 explicit GrBicubicEffect(const GrBicubicEffect&); 83 84 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 85 86 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 87 88 bool onIsEqual(const GrFragmentProcessor&) const override; 89 90 const TextureSampler& onTextureSampler(int) const override { return fTextureSampler; } 91 92 GrCoordTransform fCoordTransform; 93 GrTextureDomain fDomain; 94 TextureSampler fTextureSampler; 95 96 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 97 98 typedef GrFragmentProcessor INHERITED; 99 }; 100 101 #endif 102