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/GrFragmentProcessor.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 inline static constexpr SkImage::CubicResampler gMitchell = { 1.0f/3, 1.0f/3 }; 23 inline 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 36 SkString getShaderDfxInfo() const override; 37 clone()38 std::unique_ptr<GrFragmentProcessor> clone() const override { 39 return std::unique_ptr<GrFragmentProcessor>(new GrBicubicEffect(*this)); 40 } 41 42 /** 43 * Create a bicubic filter effect with specified texture matrix with clamp wrap mode. 44 */ 45 static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view, 46 SkAlphaType, 47 const SkMatrix&, 48 SkImage::CubicResampler, 49 Direction); 50 51 /** 52 * Create a bicubic filter effect for a texture with arbitrary wrap modes. 53 */ 54 static std::unique_ptr<GrFragmentProcessor> Make(GrSurfaceProxyView view, 55 SkAlphaType, 56 const SkMatrix&, 57 const GrSamplerState::WrapMode wrapX, 58 const GrSamplerState::WrapMode wrapY, 59 SkImage::CubicResampler, 60 Direction, 61 const GrCaps&); 62 63 /** 64 * Create a bicubic filter effect for a subset of a texture, specified by a texture coordinate 65 * rectangle subset. The WrapModes apply to the subset. 66 */ 67 static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView view, 68 SkAlphaType, 69 const SkMatrix&, 70 const GrSamplerState::WrapMode wrapX, 71 const GrSamplerState::WrapMode wrapY, 72 const SkRect& subset, 73 SkImage::CubicResampler, 74 Direction, 75 const GrCaps&); 76 77 /** 78 * Same as above but provides a known 'domain' that bounds the coords at which bicubic sampling 79 * occurs. Note that this is a bound on the coords after transformed by the matrix parameter. 80 */ 81 static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView view, 82 SkAlphaType, 83 const SkMatrix&, 84 const GrSamplerState::WrapMode wrapX, 85 const GrSamplerState::WrapMode wrapY, 86 const SkRect& subset, 87 const SkRect& domain, 88 SkImage::CubicResampler, 89 Direction, 90 const GrCaps&); 91 92 /** 93 * Make a bicubic filter of a another fragment processor. The bicubic filter assumes that the 94 * discrete samples of the provided processor are at half-integer coords. 95 */ 96 static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor>, 97 SkAlphaType, 98 const SkMatrix&, 99 SkImage::CubicResampler, 100 Direction); 101 102 private: 103 class Impl; 104 105 enum class Clamp { 106 kUnpremul, // clamps rgba to 0..1 107 kPremul, // clamps a to 0..1 and rgb to 0..a 108 }; 109 110 GrBicubicEffect(std::unique_ptr<GrFragmentProcessor>, 111 SkImage::CubicResampler, 112 Direction, 113 Clamp); 114 115 explicit GrBicubicEffect(const GrBicubicEffect&); 116 117 std::unique_ptr<ProgramImpl> onMakeProgramImpl() const override; 118 119 void onAddToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 120 121 bool onIsEqual(const GrFragmentProcessor&) const override; 122 123 SkPMColor4f constantOutputForConstantInput(const SkPMColor4f&) const override; 124 125 SkImage::CubicResampler fKernel; 126 Direction fDirection; 127 Clamp fClamp; 128 129 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 130 131 using INHERITED = GrFragmentProcessor; 132 }; 133 134 #endif 135