GrDistanceFieldGeoProc.h 12 KB

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