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