Home | History | Annotate | Download | only in effects
      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
     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
     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 
     79     ~GrDistanceFieldA8TextGeoProc() override {}
     80 
     81     const char* name() const override { return "DistanceFieldA8Text"; }
     82 
     83     const Attribute& inPosition() const { return fInPosition; }
     84     const Attribute& inColor() const { return fInColor; }
     85     const Attribute& inTextureCoords() const { return fInTextureCoords; }
     86     const SkMatrix& localMatrix() const { return fLocalMatrix; }
     87 #ifdef SK_GAMMA_APPLY_TO_A8
     88     float getDistanceAdjust() const { return fDistanceAdjust; }
     89 #endif
     90     uint32_t getFlags() const { return fFlags; }
     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 
    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. */
    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 
    149     ~GrDistanceFieldPathGeoProc() override {}
    150 
    151     const char* name() const override { return "DistanceFieldPath"; }
    152 
    153     const Attribute& inPosition() const { return fInPosition; }
    154     const Attribute& inColor() const { return fInColor; }
    155     const Attribute& inTextureCoords() const { return fInTextureCoords; }
    156     const SkMatrix& matrix() const { return fMatrix; }
    157     uint32_t getFlags() const { return fFlags; }
    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 
    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;
    201         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 
    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 
    226     ~GrDistanceFieldLCDTextGeoProc() override {}
    227 
    228     const char* name() const override { return "DistanceFieldLCDText"; }
    229 
    230     const Attribute& inPosition() const { return fInPosition; }
    231     const Attribute& inColor() const { return fInColor; }
    232     const Attribute& inTextureCoords() const { return fInTextureCoords; }
    233     DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
    234     uint32_t getFlags() const { return fFlags; }
    235     const SkMatrix& localMatrix() const { return fLocalMatrix; }
    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 
    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