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