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
14class GrGLDistanceFieldA8TextGeoProc;
15class GrGLDistanceFieldPathGeoProc;
16class GrGLDistanceFieldLCDTextGeoProc;
17class GrInvariantOutput;
18
19enum GrDistanceFieldEffectFlags {
20    kSimilarity_DistanceFieldEffectFlag = 0x01,   // ctm is similarity matrix
21    kRectToRect_DistanceFieldEffectFlag = 0x02,   // ctm maps rects to rects
22    kUseLCD_DistanceFieldEffectFlag     = 0x04,   // use lcd text
23    kBGR_DistanceFieldEffectFlag        = 0x08,   // lcd display has bgr order
24    kPortrait_DistanceFieldEffectFlag   = 0x10,   // lcd display is in portrait mode (not used yet)
25    kColorAttr_DistanceFieldEffectFlag  = 0x20,   // color vertex attribute
26
27    kInvalid_DistanceFieldEffectFlag    = 0x80,   // invalid state (for initialization)
28
29    kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
30                                            kRectToRect_DistanceFieldEffectFlag,
31    // The subset of the flags relevant to GrDistanceFieldA8TextGeoProc
32    kNonLCD_DistanceFieldEffectMask       = kSimilarity_DistanceFieldEffectFlag |
33                                            kColorAttr_DistanceFieldEffectFlag,
34    // The subset of the flags relevant to GrDistanceFieldLCDTextGeoProc
35    kLCD_DistanceFieldEffectMask          = kSimilarity_DistanceFieldEffectFlag |
36                                            kRectToRect_DistanceFieldEffectFlag |
37                                            kUseLCD_DistanceFieldEffectFlag |
38                                            kBGR_DistanceFieldEffectFlag,
39};
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 (GrTextureParams). The input
45 * coords are a custom attribute. Gamma correction is handled via a texture LUT.
46 */
47class GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor {
48public:
49#ifdef SK_GAMMA_APPLY_TO_A8
50    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix,
51                                       GrTexture* tex, const GrTextureParams& params,
52                                       float lum, uint32_t flags) {
53        return SkNEW_ARGS(GrDistanceFieldA8TextGeoProc, (color, viewMatrix, tex, params, lum,
54                                                         flags));
55    }
56#else
57    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix,
58                                       GrTexture* tex, const GrTextureParams& params,
59                                       uint32_t flags) {
60        return SkNEW_ARGS(GrDistanceFieldA8TextGeoProc, (color, viewMatrix, tex,  params, flags));
61    }
62#endif
63
64    virtual ~GrDistanceFieldA8TextGeoProc() {}
65
66    const char* name() const override { return "DistanceFieldTexture"; }
67
68    const Attribute* inPosition() const { return fInPosition; }
69    const Attribute* inColor() const { return fInColor; }
70    const Attribute* inTextureCoords() const { return fInTextureCoords; }
71    GrColor color() const { return fColor; }
72    const SkMatrix& viewMatrix() const { return fViewMatrix; }
73#ifdef SK_GAMMA_APPLY_TO_A8
74    float getDistanceAdjust() const { return fDistanceAdjust; }
75#endif
76    uint32_t getFlags() const { return fFlags; }
77
78    virtual void getGLProcessorKey(const GrBatchTracker& bt,
79                                   const GrGLSLCaps& caps,
80                                   GrProcessorKeyBuilder* b) const override;
81
82    virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
83                                                     const GrGLSLCaps&) const override;
84
85    void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override;
86
87private:
88    GrDistanceFieldA8TextGeoProc(GrColor, const SkMatrix& viewMatrix,
89                                 GrTexture* texture, const GrTextureParams& params,
90#ifdef SK_GAMMA_APPLY_TO_A8
91                                 float distanceAdjust,
92#endif
93                                 uint32_t flags);
94
95    GrColor          fColor;
96    SkMatrix         fViewMatrix;
97    GrTextureAccess  fTextureAccess;
98#ifdef SK_GAMMA_APPLY_TO_A8
99    float            fDistanceAdjust;
100#endif
101    uint32_t         fFlags;
102    const Attribute* fInPosition;
103    const Attribute* fInColor;
104    const Attribute* fInTextureCoords;
105
106    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
107
108    typedef GrGeometryProcessor INHERITED;
109};
110
111
112/**
113* The output color of this effect is a modulation of the input color and a sample from a
114* distance field texture (using a smoothed step function near 0.5).
115* It allows explicit specification of the filtering and wrap modes (GrTextureParams). The input
116* coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
117*/
118class GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
119public:
120    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, GrTexture* tex,
121                                       const GrTextureParams& params,
122                                       uint32_t flags) {
123        return SkNEW_ARGS(GrDistanceFieldPathGeoProc, (color, viewMatrix, tex, params, flags));
124    }
125
126    virtual ~GrDistanceFieldPathGeoProc() {}
127
128    const char* name() const override { return "DistanceFieldTexture"; }
129
130    const Attribute* inPosition() const { return fInPosition; }
131    const Attribute* inColor() const { return fInColor; }
132    const Attribute* inTextureCoords() const { return fInTextureCoords; }
133    GrColor color() const { return fColor; }
134    const SkMatrix& viewMatrix() const { return fViewMatrix; }
135    uint32_t getFlags() const { return fFlags; }
136
137    virtual void getGLProcessorKey(const GrBatchTracker& bt,
138                                   const GrGLSLCaps& caps,
139                                   GrProcessorKeyBuilder* b) const override;
140
141    virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
142                                                     const GrGLSLCaps&) const override;
143
144    void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override;
145
146private:
147    GrDistanceFieldPathGeoProc(GrColor, const SkMatrix& viewMatrix, GrTexture* texture,
148                               const GrTextureParams& params, uint32_t flags);
149
150    GrColor          fColor;
151    SkMatrix         fViewMatrix;
152    GrTextureAccess  fTextureAccess;
153    uint32_t         fFlags;
154    const Attribute* fInPosition;
155    const Attribute* fInColor;
156    const Attribute* fInTextureCoords;
157
158    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
159
160    typedef GrGeometryProcessor INHERITED;
161};
162
163/**
164 * The output color of this effect is a modulation of the input color and samples from a
165 * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
166 * It allows explicit specification of the filtering and wrap modes (GrTextureParams). The input
167 * coords are a custom attribute. Gamma correction is handled via a texture LUT.
168 */
169class GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
170public:
171    struct DistanceAdjust {
172        SkScalar fR, fG, fB;
173        static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
174            DistanceAdjust result;
175            result.fR = r; result.fG = g; result.fB = b;
176            return result;
177        }
178        bool operator==(const DistanceAdjust& wa) const {
179            return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
180        }
181        bool operator!=(const DistanceAdjust& wa) const {
182            return !(*this == wa);
183        }
184    };
185
186    static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix,
187                                       GrTexture* tex, const GrTextureParams& params,
188                                       DistanceAdjust distanceAdjust, uint32_t flags) {
189        return SkNEW_ARGS(GrDistanceFieldLCDTextGeoProc,
190                          (color, viewMatrix, tex, params, distanceAdjust, flags));
191    }
192
193    virtual ~GrDistanceFieldLCDTextGeoProc() {}
194
195    const char* name() const override { return "DistanceFieldLCDTexture"; }
196
197    const Attribute* inPosition() const { return fInPosition; }
198    const Attribute* inTextureCoords() const { return fInTextureCoords; }
199    DistanceAdjust getDistanceAdjust() const { return fDistanceAdjust; }
200    GrColor color() const { return fColor; }
201    const SkMatrix& viewMatrix() const { return fViewMatrix; }
202    uint32_t getFlags() const { return fFlags; }
203
204    virtual void getGLProcessorKey(const GrBatchTracker& bt,
205                                   const GrGLSLCaps& caps,
206                                   GrProcessorKeyBuilder* b) const override;
207
208    virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt,
209                                                     const GrGLSLCaps&) const override;
210
211    void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override;
212
213private:
214    GrDistanceFieldLCDTextGeoProc(GrColor, const SkMatrix& viewMatrix,
215                                  GrTexture* texture, const GrTextureParams& params,
216                                  DistanceAdjust wa, uint32_t flags);
217
218    GrColor          fColor;
219    SkMatrix         fViewMatrix;
220    GrTextureAccess  fTextureAccess;
221    DistanceAdjust   fDistanceAdjust;
222    uint32_t         fFlags;
223    const Attribute* fInPosition;
224    const Attribute* fInTextureCoords;
225
226    GR_DECLARE_GEOMETRY_PROCESSOR_TEST;
227
228    typedef GrGeometryProcessor INHERITED;
229};
230
231#endif
232