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 15class GrGLDistanceFieldA8TextGeoProc; 16class GrGLDistanceFieldPathGeoProc; 17class GrGLDistanceFieldLCDTextGeoProc; 18class GrInvariantOutput; 19 20enum 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 */ 55class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor { 56public: 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 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 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 93 ~GrDistanceFieldA8TextGeoProc() override {} 94 95 const char* name() const override { return "DistanceFieldA8Text"; } 96 97 SkString getShaderDfxInfo() const override; 98 99 void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState); 100 101 void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 102 103 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 104 105private: 106 class Impl; 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 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 using INHERITED = GrGeometryProcessor; 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 */ 142class GrDistanceFieldPathGeoProc : public GrGeometryProcessor { 143public: 144#ifdef SK_ENABLE_SMALL_PAGE 145 inline static constexpr int kMaxTextures = 16; 146#else 147 inline static constexpr int kMaxTextures = 4; 148#endif 149 150 /** The local matrix should be identity if local coords are not required by the GrPipeline. */ 151 static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps, 152 const SkMatrix& matrix, bool wideColor, 153 const GrSurfaceProxyView* views, int numActiveViews, 154 GrSamplerState params, uint32_t flags) { 155 return arena->make([&](void* ptr) { 156 return new (ptr) GrDistanceFieldPathGeoProc(caps, matrix, wideColor, views, 157 numActiveViews, params, flags); 158 }); 159 } 160 161 ~GrDistanceFieldPathGeoProc() override {} 162 163 const char* name() const override { return "DistanceFieldPath"; } 164 165 SkString getShaderDfxInfo() const override; 166 167 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 168 169 void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 170 171 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 172 173private: 174 class Impl; 175 176 GrDistanceFieldPathGeoProc(const GrShaderCaps& caps, 177 const SkMatrix& matrix, 178 bool wideColor, 179 const GrSurfaceProxyView* views, 180 int numActiveViews, 181 GrSamplerState, 182 uint32_t flags); 183 184 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 185 186 SkMatrix fMatrix; // view matrix if perspective, local matrix otherwise 187 TextureSampler fTextureSamplers[kMaxTextures]; 188 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 189 Attribute fInPosition; 190 Attribute fInColor; 191 Attribute fInTextureCoords; 192 uint32_t fFlags; 193 194 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 195 196 using INHERITED = GrGeometryProcessor; 197}; 198 199/** 200 * The output color of this effect is a modulation of the input color and samples from a 201 * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays. 202 * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input 203 * coords are a custom attribute. Gamma correction is handled via a texture LUT. 204 */ 205class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor { 206public: 207#ifdef SK_ENABLE_SMALL_PAGE 208 inline static constexpr int kMaxTextures = 16; 209#else 210 inline static constexpr int kMaxTextures = 4; 211#endif 212 213 struct DistanceAdjust { 214 SkScalar fR, fG, fB; 215 static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) { 216 DistanceAdjust result; 217 result.fR = r; result.fG = g; result.fB = b; 218 return result; 219 } 220 bool operator==(const DistanceAdjust& wa) const { 221 return (fR == wa.fR && fG == wa.fG && fB == wa.fB); 222 } 223 bool operator!=(const DistanceAdjust& wa) const { 224 return !(*this == wa); 225 } 226 }; 227 228 static GrGeometryProcessor* Make(SkArenaAlloc* arena, 229 const GrShaderCaps& caps, 230 const GrSurfaceProxyView* views, 231 int numActiveViews, 232 GrSamplerState params, 233 DistanceAdjust distanceAdjust, 234 uint32_t flags, 235 const SkMatrix& localMatrixIfUsesLocalCoords) { 236 return arena->make([&](void* ptr) { 237 return new (ptr) GrDistanceFieldLCDTextGeoProc(caps, views, numActiveViews, params, 238 distanceAdjust, flags, 239 localMatrixIfUsesLocalCoords); 240 }); 241 } 242 243 ~GrDistanceFieldLCDTextGeoProc() override {} 244 245 const char* name() const override { return "DistanceFieldLCDText"; } 246 247 SkString getShaderDfxInfo() const override; 248 249 void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState); 250 251 void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; 252 253 std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override; 254 255private: 256 class Impl; 257 258 GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views, 259 int numActiveViews, GrSamplerState params, DistanceAdjust wa, 260 uint32_t flags, const SkMatrix& localMatrix); 261 262 const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; } 263 264 TextureSampler fTextureSamplers[kMaxTextures]; 265 SkISize fAtlasDimensions; // dimensions for all textures used with fTextureSamplers[]. 266 const SkMatrix fLocalMatrix; 267 DistanceAdjust fDistanceAdjust; 268 Attribute fInPosition; 269 Attribute fInColor; 270 Attribute fInTextureCoords; 271 uint32_t fFlags; 272 273 GR_DECLARE_GEOMETRY_PROCESSOR_TEST 274 275 using INHERITED = GrGeometryProcessor; 276}; 277 278#endif 279