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