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 GrDistanceFieldGeoProc_DEFINED 9 #define GrDistanceFieldGeoProc_DEFINED 10 11 #if !defined(SK_DISABLE_SDF_TEXT) 12 13 #include "include/core/SkMatrix.h" 14 #include "include/core/SkScalar.h" 15 #include "include/core/SkSize.h" 16 #include "src/base/SkArenaAlloc.h" 17 #include "src/gpu/ganesh/GrGeometryProcessor.h" 18 #include "src/gpu/ganesh/GrProcessorUnitTest.h" 19 #include "src/gpu/ganesh/GrSamplerState.h" 20 21 #include <cstdint> 22 #include <memory> 23 24 class GrSurfaceProxyView; 25 namespace skgpu { class KeyBuilder; } 26 struct GrShaderCaps; 27 28 enum GrDistanceFieldEffectFlags { 29 kSimilarity_DistanceFieldEffectFlag = 0x001, // ctm is similarity matrix 30 kScaleOnly_DistanceFieldEffectFlag = 0x002, // ctm has only scale and translate 31 kPerspective_DistanceFieldEffectFlag = 0x004, // ctm has perspective (and positions are x,y,w) 32 kUseLCD_DistanceFieldEffectFlag = 0x008, // use lcd text 33 kBGR_DistanceFieldEffectFlag = 0x010, // lcd display has bgr order 34 kPortrait_DistanceFieldEffectFlag = 0x020, // lcd display is in portrait mode 35 kGammaCorrect_DistanceFieldEffectFlag = 0x040, // assume gamma-correct output (linear blending) 36 kAliased_DistanceFieldEffectFlag = 0x080, // monochrome output 37 kWideColor_DistanceFieldEffectFlag = 0x100, // use wide color (only for path) 38 39 kInvalid_DistanceFieldEffectFlag = 0x200, // invalid state (for initialization) 40 41 kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag | 42 kScaleOnly_DistanceFieldEffectFlag, 43 // The subset of the flags relevant to GrDistanceFieldA8TextGeoProc 44 kNonLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag | 45 kScaleOnly_DistanceFieldEffectFlag | 46 kPerspective_DistanceFieldEffectFlag | 47 kGammaCorrect_DistanceFieldEffectFlag | 48 kAliased_DistanceFieldEffectFlag, 49 // The subset of the flags relevant to GrDistanceFieldPathGeoProc 50 kPath_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag | 51 kScaleOnly_DistanceFieldEffectFlag | 52 kPerspective_DistanceFieldEffectFlag | 53 kGammaCorrect_DistanceFieldEffectFlag | 54 kAliased_DistanceFieldEffectFlag | 55 kWideColor_DistanceFieldEffectFlag, 56 // The subset of the flags relevant to GrDistanceFieldLCDTextGeoProc 57 kLCD_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag | 58 kScaleOnly_DistanceFieldEffectFlag | 59 kPerspective_DistanceFieldEffectFlag | 60 kUseLCD_DistanceFieldEffectFlag | 61 kBGR_DistanceFieldEffectFlag | 62 kPortrait_DistanceFieldEffectFlag | 63 kGammaCorrect_DistanceFieldEffectFlag, 64 }; 65 66 /** 67 * The output color of this effect is a modulation of the input color and a sample from a 68 * distance field texture (using a smoothed step function near 0.5). 69 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 70 * coords are a custom attribute. Gamma correction is handled via a texture LUT. 71 */ 72 class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor { 73 public: 74 inline static constexpr int kMaxTextures = 4; 75 76 /** The local matrix should be identity if local coords are not required by the GrPipeline. */ 77 #ifdef SK_GAMMA_APPLY_TO_A8 Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,float lum,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)78 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 79 const GrShaderCaps& caps, 80 const GrSurfaceProxyView* views, 81 int numActiveViews, 82 GrSamplerState params, 83 float lum, 84 uint32_t flags, 85 const SkMatrix& localMatrixIfUsesLocalCoords) { 86 return arena->make([&](void* ptr) { 87 return new (ptr) GrDistanceFieldA8TextGeoProc( 88 caps, views, numActiveViews, params, lum, flags, localMatrixIfUsesLocalCoords); 89 }); 90 } 91 #else Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)92 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 93 const GrShaderCaps& caps, 94 const GrSurfaceProxyView* views, 95 int numActiveViews, 96 GrSamplerState params, 97 uint32_t flags, 98 const SkMatrix& localMatrixIfUsesLocalCoords) { 99 return arena->make([&](void* ptr) { 100 return new (ptr) GrDistanceFieldA8TextGeoProc( 101 caps, views, numActiveViews, params, flags, localMatrixIfUsesLocalCoords); 102 }); 103 } 104 #endif 105 ~GrDistanceFieldA8TextGeoProc()106 ~GrDistanceFieldA8TextGeoProc() override {} 107 name()108 const char* name() const override { return "DistanceFieldA8Text"; } 109 110 void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState); 111 112 void addToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override; 113 114 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 115 116 private: 117 class Impl; 118 119 GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps, 120 const GrSurfaceProxyView* views, 121 int numActiveViews, 122 GrSamplerState params, 123 #ifdef SK_GAMMA_APPLY_TO_A8 124 float distanceAdjust, 125 #endif 126 uint32_t flags, 127 const SkMatrix& localMatrix); 128 onTextureSampler(int i)129 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 130 131 TextureSampler fTextureSamplers[kMaxTextures]; 132 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 133 SkMatrix fLocalMatrix; 134 Attribute fInPosition; 135 Attribute fInColor; 136 Attribute fInTextureCoords; 137 uint32_t fFlags; 138 #ifdef SK_GAMMA_APPLY_TO_A8 139 float fDistanceAdjust; 140 #endif 141 142 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 143 144 using INHERITED = GrGeometryProcessor; 145 }; 146 147 /** 148 * The output color of this effect is a modulation of the input color and a sample from a 149 * distance field texture (using a smoothed step function near 0.5). 150 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 151 * coords are a custom attribute. No gamma correct blending is applied. Used for paths only. 152 */ 153 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor { 154 public: 155 inline static constexpr int kMaxTextures = 4; 156 157 /** The local matrix should be identity if local coords are not required by the GrPipeline. */ Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,const SkMatrix & localMatrix,uint32_t flags)158 static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps, 159 const GrSurfaceProxyView* views, int numActiveViews, 160 GrSamplerState params, const SkMatrix& localMatrix, 161 uint32_t flags) { 162 return arena->make([&](void* ptr) { 163 return new (ptr) GrDistanceFieldPathGeoProc(caps, views, numActiveViews, 164 params, localMatrix, flags); 165 }); 166 } 167 ~GrDistanceFieldPathGeoProc()168 ~GrDistanceFieldPathGeoProc() override {} 169 name()170 const char* name() const override { return "DistanceFieldPath"; } 171 172 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 173 174 void addToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override; 175 176 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 177 178 private: 179 class Impl; 180 181 GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, 182 const GrSurfaceProxyView* views, 183 int numActiveViews, 184 GrSamplerState, 185 const SkMatrix& localMatrix, 186 uint32_t flags); 187 onTextureSampler(int i)188 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 189 190 SkMatrix fLocalMatrix; 191 TextureSampler fTextureSamplers[kMaxTextures]; 192 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 193 Attribute fInPosition; 194 Attribute fInColor; 195 Attribute fInTextureCoords; 196 uint32_t fFlags; 197 198 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 199 200 using INHERITED = GrGeometryProcessor; 201 }; 202 203 /** 204 * The output color of this effect is a modulation of the input color and samples from a 205 * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays. 206 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 207 * coords are a custom attribute. Gamma correction is handled via a texture LUT. 208 */ 209 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor { 210 public: 211 inline static constexpr int kMaxTextures = 4; 212 213 struct DistanceAdjust { 214 SkScalar fR, fG, fB; MakeDistanceAdjust215 static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) { 216 DistanceAdjust result; 217 result.fR = r; result.fG = g; result.fB = b; 218 return result; 219 } 220 bool operator==(const DistanceAdjust& wa) const { 221 return (fR == wa.fR && fG == wa.fG && fB == wa.fB); 222 } 223 bool operator!=(const DistanceAdjust& wa) const { 224 return !(*this == wa); 225 } 226 }; 227 Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,DistanceAdjust distanceAdjust,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)228 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 229 const GrShaderCaps& caps, 230 const GrSurfaceProxyView* views, 231 int numActiveViews, 232 GrSamplerState params, 233 DistanceAdjust distanceAdjust, 234 uint32_t flags, 235 const SkMatrix& localMatrixIfUsesLocalCoords) { 236 return arena->make([&](void* ptr) { 237 return new (ptr) GrDistanceFieldLCDTextGeoProc(caps, views, numActiveViews, params, 238 distanceAdjust, flags, 239 localMatrixIfUsesLocalCoords); 240 }); 241 } 242 ~GrDistanceFieldLCDTextGeoProc()243 ~GrDistanceFieldLCDTextGeoProc() override {} 244 name()245 const char* name() const override { return "DistanceFieldLCDText"; } 246 247 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 248 249 void addToKey(const GrShaderCaps&, skgpu::KeyBuilder*) const override; 250 251 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 252 253 private: 254 class Impl; 255 256 GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views, 257 int numActiveViews, GrSamplerState params, DistanceAdjust wa, 258 uint32_t flags, const SkMatrix& localMatrix); 259 onTextureSampler(int i)260 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 261 262 TextureSampler fTextureSamplers[kMaxTextures]; 263 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 264 const SkMatrix fLocalMatrix; 265 DistanceAdjust fDistanceAdjust; 266 Attribute fInPosition; 267 Attribute fInColor; 268 Attribute fInTextureCoords; 269 uint32_t fFlags; 270 271 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 272 273 using INHERITED = GrGeometryProcessor; 274 }; 275 276 #endif // !defined(SK_DISABLE_SDF_TEXT) 277 278 #endif 279