1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2013 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#ifndef GrDistanceFieldGeoProc_DEFINED
9cb93a386Sopenharmony_ci#define GrDistanceFieldGeoProc_DEFINED
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci#include "src/core/SkArenaAlloc.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrProcessor.h"
14cb93a386Sopenharmony_ci
15cb93a386Sopenharmony_ciclass GrGLDistanceFieldA8TextGeoProc;
16cb93a386Sopenharmony_ciclass GrGLDistanceFieldPathGeoProc;
17cb93a386Sopenharmony_ciclass GrGLDistanceFieldLCDTextGeoProc;
18cb93a386Sopenharmony_ciclass GrInvariantOutput;
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_cienum GrDistanceFieldEffectFlags {
21cb93a386Sopenharmony_ci    kSimilarity_DistanceFieldEffectFlag   = 0x01, // ctm is similarity matrix
22cb93a386Sopenharmony_ci    kScaleOnly_DistanceFieldEffectFlag    = 0x02, // ctm has only scale and translate
23cb93a386Sopenharmony_ci    kPerspective_DistanceFieldEffectFlag  = 0x04, // ctm has perspective (and positions are x,y,w)
24cb93a386Sopenharmony_ci    kUseLCD_DistanceFieldEffectFlag       = 0x08, // use lcd text
25cb93a386Sopenharmony_ci    kBGR_DistanceFieldEffectFlag          = 0x10, // lcd display has bgr order
26cb93a386Sopenharmony_ci    kPortrait_DistanceFieldEffectFlag     = 0x20, // lcd display is in portrait mode (not used yet)
27cb93a386Sopenharmony_ci    kGammaCorrect_DistanceFieldEffectFlag = 0x40, // assume gamma-correct output (linear blending)
28cb93a386Sopenharmony_ci    kAliased_DistanceFieldEffectFlag      = 0x80, // monochrome output
29cb93a386Sopenharmony_ci
30cb93a386Sopenharmony_ci    kInvalid_DistanceFieldEffectFlag      = 0x100,   // invalid state (for initialization)
31cb93a386Sopenharmony_ci
32cb93a386Sopenharmony_ci    kUniformScale_DistanceFieldEffectMask = kSimilarity_DistanceFieldEffectFlag |
33cb93a386Sopenharmony_ci                                            kScaleOnly_DistanceFieldEffectFlag,
34cb93a386Sopenharmony_ci    // The subset of the flags relevant to GrDistanceFieldA8TextGeoProc
35cb93a386Sopenharmony_ci    kNonLCD_DistanceFieldEffectMask       = kSimilarity_DistanceFieldEffectFlag |
36cb93a386Sopenharmony_ci                                            kScaleOnly_DistanceFieldEffectFlag |
37cb93a386Sopenharmony_ci                                            kPerspective_DistanceFieldEffectFlag |
38cb93a386Sopenharmony_ci                                            kGammaCorrect_DistanceFieldEffectFlag |
39cb93a386Sopenharmony_ci                                            kAliased_DistanceFieldEffectFlag,
40cb93a386Sopenharmony_ci    // The subset of the flags relevant to GrDistanceFieldLCDTextGeoProc
41cb93a386Sopenharmony_ci    kLCD_DistanceFieldEffectMask          = kSimilarity_DistanceFieldEffectFlag |
42cb93a386Sopenharmony_ci                                            kScaleOnly_DistanceFieldEffectFlag |
43cb93a386Sopenharmony_ci                                            kPerspective_DistanceFieldEffectFlag |
44cb93a386Sopenharmony_ci                                            kUseLCD_DistanceFieldEffectFlag |
45cb93a386Sopenharmony_ci                                            kBGR_DistanceFieldEffectFlag |
46cb93a386Sopenharmony_ci                                            kGammaCorrect_DistanceFieldEffectFlag,
47cb93a386Sopenharmony_ci};
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ci/**
50cb93a386Sopenharmony_ci * The output color of this effect is a modulation of the input color and a sample from a
51cb93a386Sopenharmony_ci * distance field texture (using a smoothed step function near 0.5).
52cb93a386Sopenharmony_ci * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
53cb93a386Sopenharmony_ci * coords are a custom attribute. Gamma correction is handled via a texture LUT.
54cb93a386Sopenharmony_ci */
55cb93a386Sopenharmony_ciclass GrDistanceFieldA8TextGeoProc : public GrGeometryProcessor {
56cb93a386Sopenharmony_cipublic:
57cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
58cb93a386Sopenharmony_ci    inline static constexpr int kMaxTextures = 16;
59cb93a386Sopenharmony_ci#else
60cb93a386Sopenharmony_ci    inline static constexpr int kMaxTextures = 4;
61cb93a386Sopenharmony_ci#endif
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_ci    /** The local matrix should be identity if local coords are not required by the GrPipeline. */
64cb93a386Sopenharmony_ci#ifdef SK_GAMMA_APPLY_TO_A8
65cb93a386Sopenharmony_ci    static GrGeometryProcessor* Make(SkArenaAlloc* arena,
66cb93a386Sopenharmony_ci                                     const GrShaderCaps& caps,
67cb93a386Sopenharmony_ci                                     const GrSurfaceProxyView* views,
68cb93a386Sopenharmony_ci                                     int numActiveViews,
69cb93a386Sopenharmony_ci                                     GrSamplerState params,
70cb93a386Sopenharmony_ci                                     float lum,
71cb93a386Sopenharmony_ci                                     uint32_t flags,
72cb93a386Sopenharmony_ci                                     const SkMatrix& localMatrixIfUsesLocalCoords) {
73cb93a386Sopenharmony_ci        return arena->make([&](void* ptr) {
74cb93a386Sopenharmony_ci            return new (ptr) GrDistanceFieldA8TextGeoProc(
75cb93a386Sopenharmony_ci                    caps, views, numActiveViews, params, lum, flags, localMatrixIfUsesLocalCoords);
76cb93a386Sopenharmony_ci        });
77cb93a386Sopenharmony_ci    }
78cb93a386Sopenharmony_ci#else
79cb93a386Sopenharmony_ci    static GrGeometryProcessor* Make(SkArenaAlloc* arena,
80cb93a386Sopenharmony_ci                                     const GrShaderCaps& caps,
81cb93a386Sopenharmony_ci                                     const GrSurfaceProxyView* views,
82cb93a386Sopenharmony_ci                                     int numActiveViews,
83cb93a386Sopenharmony_ci                                     GrSamplerState params,
84cb93a386Sopenharmony_ci                                     uint32_t flags,
85cb93a386Sopenharmony_ci                                     const SkMatrix& localMatrixIfUsesLocalCoords) {
86cb93a386Sopenharmony_ci        return arena->make([&](void* ptr) {
87cb93a386Sopenharmony_ci            return new (ptr) GrDistanceFieldA8TextGeoProc(
88cb93a386Sopenharmony_ci                    caps, views, numActiveViews, params, flags, localMatrixIfUsesLocalCoords);
89cb93a386Sopenharmony_ci        });
90cb93a386Sopenharmony_ci    }
91cb93a386Sopenharmony_ci#endif
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci    ~GrDistanceFieldA8TextGeoProc() override {}
94cb93a386Sopenharmony_ci
95cb93a386Sopenharmony_ci    const char* name() const override { return "DistanceFieldA8Text"; }
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    SkString getShaderDfxInfo() const override;
98cb93a386Sopenharmony_ci
99cb93a386Sopenharmony_ci    void addNewViews(const GrSurfaceProxyView* views, int numViews, GrSamplerState);
100cb93a386Sopenharmony_ci
101cb93a386Sopenharmony_ci    void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci    std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ciprivate:
106cb93a386Sopenharmony_ci    class Impl;
107cb93a386Sopenharmony_ci
108cb93a386Sopenharmony_ci    GrDistanceFieldA8TextGeoProc(const GrShaderCaps& caps,
109cb93a386Sopenharmony_ci                                 const GrSurfaceProxyView* views,
110cb93a386Sopenharmony_ci                                 int numActiveViews,
111cb93a386Sopenharmony_ci                                 GrSamplerState params,
112cb93a386Sopenharmony_ci#ifdef SK_GAMMA_APPLY_TO_A8
113cb93a386Sopenharmony_ci                                 float distanceAdjust,
114cb93a386Sopenharmony_ci#endif
115cb93a386Sopenharmony_ci                                 uint32_t flags,
116cb93a386Sopenharmony_ci                                 const SkMatrix& localMatrix);
117cb93a386Sopenharmony_ci
118cb93a386Sopenharmony_ci    const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_ci    TextureSampler   fTextureSamplers[kMaxTextures];
121cb93a386Sopenharmony_ci    SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
122cb93a386Sopenharmony_ci    SkMatrix         fLocalMatrix;
123cb93a386Sopenharmony_ci    Attribute        fInPosition;
124cb93a386Sopenharmony_ci    Attribute        fInColor;
125cb93a386Sopenharmony_ci    Attribute        fInTextureCoords;
126cb93a386Sopenharmony_ci    uint32_t         fFlags;
127cb93a386Sopenharmony_ci#ifdef SK_GAMMA_APPLY_TO_A8
128cb93a386Sopenharmony_ci    float            fDistanceAdjust;
129cb93a386Sopenharmony_ci#endif
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci    GR_DECLARE_GEOMETRY_PROCESSOR_TEST
132cb93a386Sopenharmony_ci
133cb93a386Sopenharmony_ci    using INHERITED = GrGeometryProcessor;
134cb93a386Sopenharmony_ci};
135cb93a386Sopenharmony_ci
136cb93a386Sopenharmony_ci/**
137cb93a386Sopenharmony_ci * The output color of this effect is a modulation of the input color and a sample from a
138cb93a386Sopenharmony_ci * distance field texture (using a smoothed step function near 0.5).
139cb93a386Sopenharmony_ci * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
140cb93a386Sopenharmony_ci * coords are a custom attribute. No gamma correct blending is applied. Used for paths only.
141cb93a386Sopenharmony_ci */
142cb93a386Sopenharmony_ciclass GrDistanceFieldPathGeoProc : public GrGeometryProcessor {
143cb93a386Sopenharmony_cipublic:
144cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
145cb93a386Sopenharmony_ci    inline static constexpr int kMaxTextures = 16;
146cb93a386Sopenharmony_ci#else
147cb93a386Sopenharmony_ci    inline static constexpr int kMaxTextures = 4;
148cb93a386Sopenharmony_ci#endif
149cb93a386Sopenharmony_ci
150cb93a386Sopenharmony_ci    /** The local matrix should be identity if local coords are not required by the GrPipeline. */
151cb93a386Sopenharmony_ci    static GrGeometryProcessor* Make(SkArenaAlloc* arena, const GrShaderCaps& caps,
152cb93a386Sopenharmony_ci                                     const SkMatrix& matrix, bool wideColor,
153cb93a386Sopenharmony_ci                                     const GrSurfaceProxyView* views, int numActiveViews,
154cb93a386Sopenharmony_ci                                     GrSamplerState params, uint32_t flags) {
155cb93a386Sopenharmony_ci        return arena->make([&](void* ptr) {
156cb93a386Sopenharmony_ci            return new (ptr) GrDistanceFieldPathGeoProc(caps, matrix, wideColor, views,
157cb93a386Sopenharmony_ci                                                        numActiveViews, params, flags);
158cb93a386Sopenharmony_ci        });
159cb93a386Sopenharmony_ci    }
160cb93a386Sopenharmony_ci
161cb93a386Sopenharmony_ci    ~GrDistanceFieldPathGeoProc() override {}
162cb93a386Sopenharmony_ci
163cb93a386Sopenharmony_ci    const char* name() const override { return "DistanceFieldPath"; }
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ci    SkString getShaderDfxInfo() const override;
166cb93a386Sopenharmony_ci
167cb93a386Sopenharmony_ci    void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
168cb93a386Sopenharmony_ci
169cb93a386Sopenharmony_ci    void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
170cb93a386Sopenharmony_ci
171cb93a386Sopenharmony_ci    std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
172cb93a386Sopenharmony_ci
173cb93a386Sopenharmony_ciprivate:
174cb93a386Sopenharmony_ci    class Impl;
175cb93a386Sopenharmony_ci
176cb93a386Sopenharmony_ci    GrDistanceFieldPathGeoProc(const GrShaderCaps& caps,
177cb93a386Sopenharmony_ci                               const SkMatrix& matrix,
178cb93a386Sopenharmony_ci                               bool wideColor,
179cb93a386Sopenharmony_ci                               const GrSurfaceProxyView* views,
180cb93a386Sopenharmony_ci                               int numActiveViews,
181cb93a386Sopenharmony_ci                               GrSamplerState,
182cb93a386Sopenharmony_ci                               uint32_t flags);
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci    const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
185cb93a386Sopenharmony_ci
186cb93a386Sopenharmony_ci    SkMatrix         fMatrix;     // view matrix if perspective, local matrix otherwise
187cb93a386Sopenharmony_ci    TextureSampler   fTextureSamplers[kMaxTextures];
188cb93a386Sopenharmony_ci    SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
189cb93a386Sopenharmony_ci    Attribute        fInPosition;
190cb93a386Sopenharmony_ci    Attribute        fInColor;
191cb93a386Sopenharmony_ci    Attribute        fInTextureCoords;
192cb93a386Sopenharmony_ci    uint32_t         fFlags;
193cb93a386Sopenharmony_ci
194cb93a386Sopenharmony_ci    GR_DECLARE_GEOMETRY_PROCESSOR_TEST
195cb93a386Sopenharmony_ci
196cb93a386Sopenharmony_ci    using INHERITED = GrGeometryProcessor;
197cb93a386Sopenharmony_ci};
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci/**
200cb93a386Sopenharmony_ci * The output color of this effect is a modulation of the input color and samples from a
201cb93a386Sopenharmony_ci * distance field texture (using a smoothed step function near 0.5), adjusted for LCD displays.
202cb93a386Sopenharmony_ci * It allows explicit specification of the filtering and wrap modes (GrSamplerState). The input
203cb93a386Sopenharmony_ci * coords are a custom attribute. Gamma correction is handled via a texture LUT.
204cb93a386Sopenharmony_ci */
205cb93a386Sopenharmony_ciclass GrDistanceFieldLCDTextGeoProc : public GrGeometryProcessor {
206cb93a386Sopenharmony_cipublic:
207cb93a386Sopenharmony_ci#ifdef SK_ENABLE_SMALL_PAGE
208cb93a386Sopenharmony_ci    inline static constexpr int kMaxTextures = 16;
209cb93a386Sopenharmony_ci#else
210cb93a386Sopenharmony_ci    inline static constexpr int kMaxTextures = 4;
211cb93a386Sopenharmony_ci#endif
212cb93a386Sopenharmony_ci
213cb93a386Sopenharmony_ci    struct DistanceAdjust {
214cb93a386Sopenharmony_ci        SkScalar fR, fG, fB;
215cb93a386Sopenharmony_ci        static DistanceAdjust Make(SkScalar r, SkScalar g, SkScalar b) {
216cb93a386Sopenharmony_ci            DistanceAdjust result;
217cb93a386Sopenharmony_ci            result.fR = r; result.fG = g; result.fB = b;
218cb93a386Sopenharmony_ci            return result;
219cb93a386Sopenharmony_ci        }
220cb93a386Sopenharmony_ci        bool operator==(const DistanceAdjust& wa) const {
221cb93a386Sopenharmony_ci            return (fR == wa.fR && fG == wa.fG && fB == wa.fB);
222cb93a386Sopenharmony_ci        }
223cb93a386Sopenharmony_ci        bool operator!=(const DistanceAdjust& wa) const {
224cb93a386Sopenharmony_ci            return !(*this == wa);
225cb93a386Sopenharmony_ci        }
226cb93a386Sopenharmony_ci    };
227cb93a386Sopenharmony_ci
228cb93a386Sopenharmony_ci    static GrGeometryProcessor* Make(SkArenaAlloc* arena,
229cb93a386Sopenharmony_ci                                     const GrShaderCaps& caps,
230cb93a386Sopenharmony_ci                                     const GrSurfaceProxyView* views,
231cb93a386Sopenharmony_ci                                     int numActiveViews,
232cb93a386Sopenharmony_ci                                     GrSamplerState params,
233cb93a386Sopenharmony_ci                                     DistanceAdjust distanceAdjust,
234cb93a386Sopenharmony_ci                                     uint32_t flags,
235cb93a386Sopenharmony_ci                                     const SkMatrix& localMatrixIfUsesLocalCoords) {
236cb93a386Sopenharmony_ci        return arena->make([&](void* ptr) {
237cb93a386Sopenharmony_ci            return new (ptr) GrDistanceFieldLCDTextGeoProc(caps, views, numActiveViews, params,
238cb93a386Sopenharmony_ci                                                           distanceAdjust, flags,
239cb93a386Sopenharmony_ci                                                           localMatrixIfUsesLocalCoords);
240cb93a386Sopenharmony_ci        });
241cb93a386Sopenharmony_ci    }
242cb93a386Sopenharmony_ci
243cb93a386Sopenharmony_ci    ~GrDistanceFieldLCDTextGeoProc() override {}
244cb93a386Sopenharmony_ci
245cb93a386Sopenharmony_ci    const char* name() const override { return "DistanceFieldLCDText"; }
246cb93a386Sopenharmony_ci
247cb93a386Sopenharmony_ci    SkString getShaderDfxInfo() const override;
248cb93a386Sopenharmony_ci
249cb93a386Sopenharmony_ci    void addNewViews(const GrSurfaceProxyView*, int numActiveViews, GrSamplerState);
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci    void addToKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_ci    std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
254cb93a386Sopenharmony_ci
255cb93a386Sopenharmony_ciprivate:
256cb93a386Sopenharmony_ci    class Impl;
257cb93a386Sopenharmony_ci
258cb93a386Sopenharmony_ci    GrDistanceFieldLCDTextGeoProc(const GrShaderCaps& caps, const GrSurfaceProxyView* views,
259cb93a386Sopenharmony_ci                                  int numActiveViews, GrSamplerState params, DistanceAdjust wa,
260cb93a386Sopenharmony_ci                                  uint32_t flags, const SkMatrix& localMatrix);
261cb93a386Sopenharmony_ci
262cb93a386Sopenharmony_ci    const TextureSampler& onTextureSampler(int i) const override { return fTextureSamplers[i]; }
263cb93a386Sopenharmony_ci
264cb93a386Sopenharmony_ci    TextureSampler   fTextureSamplers[kMaxTextures];
265cb93a386Sopenharmony_ci    SkISize          fAtlasDimensions;  // dimensions for all textures used with fTextureSamplers[].
266cb93a386Sopenharmony_ci    const SkMatrix   fLocalMatrix;
267cb93a386Sopenharmony_ci    DistanceAdjust   fDistanceAdjust;
268cb93a386Sopenharmony_ci    Attribute        fInPosition;
269cb93a386Sopenharmony_ci    Attribute        fInColor;
270cb93a386Sopenharmony_ci    Attribute        fInTextureCoords;
271cb93a386Sopenharmony_ci    uint32_t         fFlags;
272cb93a386Sopenharmony_ci
273cb93a386Sopenharmony_ci    GR_DECLARE_GEOMETRY_PROCESSOR_TEST
274cb93a386Sopenharmony_ci
275cb93a386Sopenharmony_ci    using INHERITED = GrGeometryProcessor;
276cb93a386Sopenharmony_ci};
277cb93a386Sopenharmony_ci
278cb93a386Sopenharmony_ci#endif
279