1 /* 2 * Copyright 2017 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 GrTextureEffect_DEFINED 9 #define GrTextureEffect_DEFINED 10 11 #include "include/core/SkImageInfo.h" 12 #include "include/core/SkMatrix.h" 13 #include "src/gpu/GrCoordTransform.h" 14 #include "src/gpu/GrFragmentProcessor.h" 15 16 class GrTextureEffect : public GrFragmentProcessor { 17 public: 18 /** Make from a filter. The sampler will be configured with clamp mode. */ 19 static std::unique_ptr<GrFragmentProcessor> Make( 20 GrSurfaceProxyView, 21 SkAlphaType, 22 const SkMatrix& = SkMatrix::I(), 23 GrSamplerState::Filter = GrSamplerState::Filter::kNearest); 24 25 /** 26 * Make from a full GrSamplerState. Caps are required to determine support for kClampToBorder. 27 * This will be emulated in the shader if there is no hardware support. 28 */ 29 static std::unique_ptr<GrFragmentProcessor> Make( 30 GrSurfaceProxyView, SkAlphaType, const SkMatrix&, GrSamplerState, const GrCaps& caps); 31 32 /** 33 * Makes a texture effect that samples a subset of a texture. The wrap modes of the 34 * GrSampleState are applied to the subset in the shader rather than using HW samplers. 35 * The 'subset' parameter specifies the texels in the base level. The shader code will 36 * avoid allowing bilerp filtering to read outside the texel window. However, if MIP 37 * filtering is used and a shader invocation reads from a level other than the base 38 * then it may read texel values that were computed from in part from base level texels 39 * outside the window. More specifically, we treat the MIP map case exactly like the 40 * bilerp case in terms of how the final texture coords are computed. 41 */ 42 static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView, 43 SkAlphaType, 44 const SkMatrix&, 45 GrSamplerState, 46 const SkRect& subset, 47 const GrCaps& caps); 48 49 /** 50 * The same as above but also takes a 'domain' that specifies any known limit on the post- 51 * matrix texture coords that will be used to sample the texture. Specifying this requires 52 * knowledge of how this effect will be nested into a paint, the local coords used with the 53 * draw, etc. It is only used to attempt to optimize away the shader subset calculations. 54 */ 55 static std::unique_ptr<GrFragmentProcessor> MakeSubset(GrSurfaceProxyView, 56 SkAlphaType, 57 const SkMatrix&, 58 GrSamplerState, 59 const SkRect& subset, 60 const SkRect& domain, 61 const GrCaps& caps); 62 63 std::unique_ptr<GrFragmentProcessor> clone() const override; 64 name()65 const char* name() const override { return "TextureEffect"; } 66 67 private: 68 enum class ShaderMode : uint16_t { 69 kClamp = static_cast<int>(GrSamplerState::WrapMode::kClamp), 70 kRepeat = static_cast<int>(GrSamplerState::WrapMode::kRepeat), 71 kMirrorRepeat = static_cast<int>(GrSamplerState::WrapMode::kMirrorRepeat), 72 kDecal = static_cast<int>(GrSamplerState::WrapMode::kClampToBorder), 73 kNone, 74 }; 75 76 struct Sampling { 77 GrSamplerState fHWSampler; 78 ShaderMode fShaderModes[2] = {ShaderMode::kNone, ShaderMode::kNone}; 79 SkRect fShaderSubset = {0, 0, 0, 0}; 80 SkRect fShaderClamp = {0, 0, 0, 0}; SamplingSampling81 Sampling(GrSamplerState::Filter filter) : fHWSampler(filter) {} 82 Sampling(const GrSurfaceProxy& proxy, 83 GrSamplerState sampler, 84 const SkRect&, 85 const SkRect*, 86 const GrCaps&); 87 inline bool usesDecal() const; 88 }; 89 90 /** 91 * Sometimes the implementation of a ShaderMode depends on which GrSamplerState::Filter is 92 * used. 93 */ 94 enum class FilterLogic { 95 kNone, // The shader isn't specialized for the filter. 96 kRepeatBilerp, // Filter across the subset boundary for kRepeat mode 97 kRepeatMipMap, // Logic for LOD selection with kRepeat mode. 98 kDecalFilter, // Logic for fading to transparent black when filtering with kDecal. 99 kDecalNearest, // Logic for hard transition to transparent black when not filtering. 100 }; 101 static FilterLogic GetFilterLogic(ShaderMode mode, GrSamplerState::Filter filter); 102 103 GrCoordTransform fCoordTransform; 104 TextureSampler fSampler; 105 SkRect fSubset; 106 SkRect fClamp; 107 ShaderMode fShaderModes[2]; 108 109 inline GrTextureEffect(GrSurfaceProxyView, SkAlphaType, const SkMatrix&, const Sampling&); 110 111 GrTextureEffect(const GrTextureEffect& src); 112 113 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; 114 115 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 116 117 bool onIsEqual(const GrFragmentProcessor&) const override; 118 119 const TextureSampler& onTextureSampler(int) const override; 120 121 GR_DECLARE_FRAGMENT_PROCESSOR_TEST 122 123 typedef GrFragmentProcessor INHERITED; 124 }; 125 #endif 126