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