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