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