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 #ifdef SK_ENABLE_SMALL_PAGE 58 inline static constexpr int kMaxTextures = 16; 59 #else 60 inline static constexpr int kMaxTextures = 4; 61 #endif 62 63 /** The local matrix should be identity if local coords are not required by the GrPipeline. */ 64 #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)65 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 66 const GrShaderCaps& caps, 67 const GrSurfaceProxyView* views, 68 int numActiveViews, 69 GrSamplerState params, 70 float lum, 71 uint32_t flags, 72 const SkMatrix& localMatrixIfUsesLocalCoords) { 73 return arena->make([&](void* ptr) { 74 return new (ptr) GrDistanceFieldA8TextGeoProc( 75 caps, views, numActiveViews, params, lum, flags, localMatrixIfUsesLocalCoords); 76 }); 77 } 78 #else Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)79 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 80 const GrShaderCaps& caps, 81 const GrSurfaceProxyView* views, 82 int numActiveViews, 83 GrSamplerState params, 84 uint32_t flags, 85 const SkMatrix& localMatrixIfUsesLocalCoords) { 86 return arena->make([&](void* ptr) { 87 return new (ptr) GrDistanceFieldA8TextGeoProc( 88 caps, views, numActiveViews, params, flags, localMatrixIfUsesLocalCoords); 89 }); 90 } 91 #endif 92 ~GrDistanceFieldA8TextGeoProc()93 ~GrDistanceFieldA8TextGeoProc() override {} 94 name()95 const char* name() const override { return "DistanceFieldA8Text"; } 96 97 void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState); 98 99 void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 100 101 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 102 103 private: 104 class Impl; 105 106 GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps, 107 const GrSurfaceProxyView* views, 108 int numActiveViews, 109 GrSamplerState params, 110 #ifdef SK_GAMMA_APPLY_TO_A8 111 float distanceAdjust, 112 #endif 113 uint32_t flags, 114 const SkMatrix& localMatrix); 115 onTextureSampler(int i)116 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 117 118 TextureSampler fTextureSamplers[kMaxTextures]; 119 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 120 SkMatrix fLocalMatrix; 121 Attribute fInPosition; 122 Attribute fInColor; 123 Attribute fInTextureCoords; 124 uint32_t fFlags; 125 #ifdef SK_GAMMA_APPLY_TO_A8 126 float fDistanceAdjust; 127 #endif 128 129 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 130 131 using INHERITED = GrGeometryProcessor; 132 }; 133 134 /** 135 * The output color of this effect is a modulation of the input color and a sample from a 136 * distance field texture (using a smoothed step function near 0.5). 137 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 138 * coords are a custom attribute. No gamma correct blending is applied. Used for paths only. 139 */ 140 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor { 141 public: 142 #ifdef SK_ENABLE_SMALL_PAGE 143 inline static constexpr int kMaxTextures = 16; 144 #else 145 inline static constexpr int kMaxTextures = 4; 146 #endif 147 148 /** 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)149 static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps, 150 const SkMatrix& matrix, bool wideColor, 151 const GrSurfaceProxyView* views, int numActiveViews, 152 GrSamplerState params, uint32_t flags) { 153 return arena->make([&](void* ptr) { 154 return new (ptr) GrDistanceFieldPathGeoProc(caps, matrix, wideColor, views, 155 numActiveViews, params, flags); 156 }); 157 } 158 ~GrDistanceFieldPathGeoProc()159 ~GrDistanceFieldPathGeoProc() override {} 160 name()161 const char* name() const override { return "DistanceFieldPath"; } 162 163 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 164 165 void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 166 167 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 168 169 private: 170 class Impl; 171 172 GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, 173 const SkMatrix& matrix, 174 bool wideColor, 175 const GrSurfaceProxyView* views, 176 int numActiveViews, 177 GrSamplerState, 178 uint32_t flags); 179 onTextureSampler(int i)180 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 181 182 SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise 183 TextureSampler fTextureSamplers[kMaxTextures]; 184 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 185 Attribute fInPosition; 186 Attribute fInColor; 187 Attribute fInTextureCoords; 188 uint32_t fFlags; 189 190 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 191 192 using INHERITED = GrGeometryProcessor; 193 }; 194 195 /** 196 * The output color of this effect is a modulation of the input color and samples from a 197 * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays. 198 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 199 * coords are a custom attribute. Gamma correction is handled via a texture LUT. 200 */ 201 class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor { 202 public: 203 #ifdef SK_ENABLE_SMALL_PAGE 204 inline static constexpr int kMaxTextures = 16; 205 #else 206 inline static constexpr int kMaxTextures = 4; 207 #endif 208 209 struct DistanceAdjust { 210 SkScalar fR, fG, fB; MakeDistanceAdjust211 static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) { 212 DistanceAdjust result; 213 result.fR = r; result.fG = g; result.fB = b; 214 return result; 215 } 216 bool operator==(const DistanceAdjust& wa) const { 217 return (fR == wa.fR && fG == wa.fG && fB == wa.fB); 218 } 219 bool operator!=(const DistanceAdjust& wa) const { 220 return !(*this == wa); 221 } 222 }; 223 Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,DistanceAdjust distanceAdjust,uint32_t flags,const SkMatrix & localMatrixIfUsesLocalCoords)224 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 225 const GrShaderCaps& caps, 226 const GrSurfaceProxyView* views, 227 int numActiveViews, 228 GrSamplerState params, 229 DistanceAdjust distanceAdjust, 230 uint32_t flags, 231 const SkMatrix& localMatrixIfUsesLocalCoords) { 232 return arena->make([&](void* ptr) { 233 return new (ptr) GrDistanceFieldLCDTextGeoProc(caps, views, numActiveViews, params, 234 distanceAdjust, flags, 235 localMatrixIfUsesLocalCoords); 236 }); 237 } 238 ~GrDistanceFieldLCDTextGeoProc()239 ~GrDistanceFieldLCDTextGeoProc() override {} 240 name()241 const char* name() const override { return "DistanceFieldLCDText"; } 242 243 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 244 245 void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 246 247 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 248 249 private: 250 class Impl; 251 252 GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views, 253 int numActiveViews, GrSamplerState params, DistanceAdjust wa, 254 uint32_t flags, const SkMatrix& localMatrix); 255 onTextureSampler(int i)256 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 257 258 TextureSampler fTextureSamplers[kMaxTextures]; 259 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 260 const SkMatrix fLocalMatrix; 261 DistanceAdjust fDistanceAdjust; 262 Attribute fInPosition; 263 Attribute fInColor; 264 Attribute fInTextureCoords; 265 uint32_t fFlags; 266 267 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 268 269 using INHERITED = GrGeometryProcessor; 270 }; 271 272 #endif 273