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 "src/gpu/glsl/GrGLSLFragmentProcessor.h" 12 13 class GrInvariantOutput; 14 15 class GrBicubicEffect : public GrFragmentProcessor { 16 public: 17 enum { 18 kFilterTexelPad = 2, // Given a src rect in texels to be filtered, this number of 19 // surrounding texels are needed by the kernel in x and y. 20 }; 21 22 static constexpr SkImage::CubicResampler gMitchell = { 1.0f/3, 1.0f/3 }; 23 static constexpr SkImage::CubicResampler gCatmullRom = { 0, 1.0f/2 }; 24 25 enum class Direction { 26 /** Apply bicubic kernel in local coord x, nearest neighbor in y. */ 27 kX, 28 /** Apply bicubic kernel in local coord y, nearest neighbor in x. */ 29 kY, 30 /** Apply bicubic in both x and y. */ 31 kXY 32 }; 33 name()34 const char* name() const override { return "Bicubic"; } 35 clone()36 std::unique_ptr<GrFragmentProcessor> clone() const override { 37 return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(*this)); 38 } 39 40 /** 41 * Create a bicubic filter effect with specified texture matrix with clamp wrap mode. 42 */ 43 static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view, 44 SkAlphaType, 45 const SkMatrix&, 46 SkImage::CubicResampler, 47 Direction); 48 49 /** 50 * Create a bicubic filter effect for a texture with arbitrary wrap modes. 51 */ 52 static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view, 53 SkAlphaType, 54 const SkMatrix&, 55 const GrSamplerState::WrapMode wrapX, 56 const GrSamplerState::WrapMode wrapY, 57 SkImage::CubicResampler, 58 Direction, 59 const GrCaps&); 60 61 /** 62 * Create a bicubic filter effect for a subset of a texture, specified by a texture coordinate 63 * rectangle subset. The WrapModes apply to the subset. 64 */ 65 static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView view, 66 SkAlphaType, 67 const SkMatrix&, 68 const GrSamplerState::WrapMode wrapX, 69 const GrSamplerState::WrapMode wrapY, 70 const SkRect& subset, 71 SkImage::CubicResampler, 72 Direction, 73 const GrCaps&); 74 75 /** 76 * Same as above but provides a known 'domain' that bounds the coords at which bicubic sampling 77 * occurs. Note that this is a bound on the coords after transformed by the matrix parameter. 78 */ 79 static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView view, 80 SkAlphaType, 81 const SkMatrix&, 82 const GrSamplerState::WrapMode wrapX, 83 const GrSamplerState::WrapMode wrapY, 84 const SkRect& subset, 85 const SkRect& domain, 86 SkImage::CubicResampler, 87 Direction, 88 const GrCaps&); 89 90 /** 91 * Make a bicubic filter of a another fragment processor. The bicubic filter assumes that the 92 * discrete samples of the provided processor are at half-integer coords. 93 */ 94 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>, 95 SkAlphaType, 96 const SkMatrix&, 97 SkImage::CubicResampler, 98 Direction); 99 100 private: 101 class Impl; 102 103 enum class Clamp { 104 kUnpremul, // clamps rgba to 0..1 105 kPremul, // clamps a to 0..1 and rgb to 0..a 106 }; 107 108 GrBicubicEffect(std::unique_ptr<GrFragmentProcessor>, 109 SkImage::CubicResampler, 110 Direction, 111 Clamp); 112 113 explicit GrBicubicEffect(const GrBicubicEffect&); 114 115 std::unique_ptr<GrGLSLFragmentProcessor> onMakeProgramImpl() const override; 116 117 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 118 119 bool onIsEqual(const GrFragmentProcessor&) const override; 120 121 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override; 122 123 SkImage::CubicResampler fKernel; 124 Direction fDirection; 125 Clamp fClamp; 126 127 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 128 129 using INHERITED = GrFragmentProcessor; 130 }; 131 132 #endif 133