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 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<GrDistanceFieldA8TextGeoProc>( 70 caps, views, numActiveViews, params, lum, flags, localMatrixIfUsesLocalCoords); 71 } 72 #else Make(SkArenaAlloc * arena,const GrShaderCaps & caps,const GrSurfaceProxyView * views,int numActiveViews,GrSamplerState params,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 uint32_t flags, 79 const SkMatrix& localMatrixIfUsesLocalCoords) { 80 return arena->make<GrDistanceFieldA8TextGeoProc>( 81 caps, views, numActiveViews, params, flags, localMatrixIfUsesLocalCoords); 82 } 83 #endif 84 ~GrDistanceFieldA8TextGeoProc()85 ~GrDistanceFieldA8TextGeoProc() override {} 86 name()87 const char* name() const override { return "DistanceFieldA8Text"; } 88 inPosition()89 const Attribute& inPosition() const { return fInPosition; } inColor()90 const Attribute& inColor() const { return fInColor; } inTextureCoords()91 const Attribute& inTextureCoords() const { return fInTextureCoords; } localMatrix()92 const SkMatrix& localMatrix() const { return fLocalMatrix; } 93 #ifdef SK_GAMMA_APPLY_TO_A8 getDistanceAdjust()94 float getDistanceAdjust() const { return fDistanceAdjust; } 95 #endif getFlags()96 uint32_t getFlags() const { return fFlags; } atlasDimensions()97 const SkISize& atlasDimensions() const { return fAtlasDimensions; } 98 99 void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState); 100 101 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; 102 103 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; 104 105 private: 106 friend class ::SkArenaAlloc; // for access to ctor 107 108 GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps, 109 const GrSurfaceProxyView* views, 110 int numActiveViews, 111 GrSamplerState params, 112 #ifdef SK_GAMMA_APPLY_TO_A8 113 float distanceAdjust, 114 #endif 115 uint32_t flags, 116 const SkMatrix& localMatrix); 117 onTextureSampler(int i)118 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 119 120 TextureSampler fTextureSamplers[kMaxTextures]; 121 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 122 SkMatrix fLocalMatrix; 123 Attribute fInPosition; 124 Attribute fInColor; 125 Attribute fInTextureCoords; 126 uint32_t fFlags; 127 #ifdef SK_GAMMA_APPLY_TO_A8 128 float fDistanceAdjust; 129 #endif 130 131 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 132 133 typedef GrGeometryProcessor INHERITED; 134 }; 135 136 /** 137 * The output color of this effect is a modulation of the input color and a sample from a 138 * distance field texture (using a smoothed step function near 0.5). 139 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 140 * coords are a custom attribute. No gamma correct blending is applied. Used for paths only. 141 */ 142 class GrDistanceFieldPathGeoProc : public GrGeometryProcessor { 143 public: 144 static constexpr int kMaxTextures = 4; 145 146 /** 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)147 static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps, 148 const SkMatrix& matrix, bool wideColor, 149 const GrSurfaceProxyView* views, int numActiveViews, 150 GrSamplerState params, uint32_t flags) { 151 return arena->make<GrDistanceFieldPathGeoProc>(caps, matrix, wideColor, views, 152 numActiveViews, params, flags); 153 } 154 ~GrDistanceFieldPathGeoProc()155 ~GrDistanceFieldPathGeoProc() override {} 156 name()157 const char* name() const override { return "DistanceFieldPath"; } 158 inPosition()159 const Attribute& inPosition() const { return fInPosition; } inColor()160 const Attribute& inColor() const { return fInColor; } inTextureCoords()161 const Attribute& inTextureCoords() const { return fInTextureCoords; } matrix()162 const SkMatrix& matrix() const { return fMatrix; } getFlags()163 uint32_t getFlags() const { return fFlags; } atlasDimensions()164 const SkISize& atlasDimensions() const { return fAtlasDimensions; } 165 166 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 167 168 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; 169 170 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; 171 172 private: 173 friend class ::SkArenaAlloc; // for access to ctor 174 175 GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, 176 const SkMatrix& matrix, 177 bool wideColor, 178 const GrSurfaceProxyView* views, 179 int numActiveViews, 180 GrSamplerState, 181 uint32_t flags); 182 onTextureSampler(int i)183 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 184 185 SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise 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 typedef GrGeometryProcessor INHERITED; 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 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<GrDistanceFieldLCDTextGeoProc>(caps, views, numActiveViews, params, 232 distanceAdjust, flags, 233 localMatrixIfUsesLocalCoords); 234 } 235 ~GrDistanceFieldLCDTextGeoProc()236 ~GrDistanceFieldLCDTextGeoProc() override {} 237 name()238 const char* name() const override { return "DistanceFieldLCDText"; } 239 inPosition()240 const Attribute& inPosition() const { return fInPosition; } inColor()241 const Attribute& inColor() const { return fInColor; } inTextureCoords()242 const Attribute& inTextureCoords() const { return fInTextureCoords; } getDistanceAdjust()243 DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; } getFlags()244 uint32_t getFlags() const { return fFlags; } localMatrix()245 const SkMatrix& localMatrix() const { return fLocalMatrix; } atlasDimensions()246 const SkISize& atlasDimensions() const { return fAtlasDimensions; } 247 248 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 249 250 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override; 251 252 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override; 253 254 private: 255 friend class ::SkArenaAlloc; // for access to ctor 256 257 GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views, 258 int numActiveViews, GrSamplerState params, DistanceAdjust wa, 259 uint32_t flags, const SkMatrix& localMatrix); 260 onTextureSampler(int i)261 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 262 263 TextureSampler fTextureSamplers[kMaxTextures]; 264 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 265 const SkMatrix fLocalMatrix; 266 DistanceAdjust fDistanceAdjust; 267 Attribute fInPosition; 268 Attribute fInColor; 269 Attribute fInTextureCoords; 270 uint32_t fFlags; 271 272 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 273 274 typedef GrGeometryProcessor INHERITED; 275 }; 276 277 #endif 278