1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2014 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#include "src/gpu/GrDefaultGeoProcFactory.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkRefCnt.h"
11cb93a386Sopenharmony_ci#include "src/core/SkArenaAlloc.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h"
13cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h"
14cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
15cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLUniformHandler.h"
16cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h"
17cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h"
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci/*
20cb93a386Sopenharmony_ci * The default Geometry Processor simply takes position and multiplies it by the uniform view
21cb93a386Sopenharmony_ci * matrix. It also leaves coverage untouched.  Behind the scenes, we may add per vertex color or
22cb93a386Sopenharmony_ci * local coords.
23cb93a386Sopenharmony_ci */
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_cienum GPFlag {
26cb93a386Sopenharmony_ci    kColorAttribute_GPFlag              = 0x1,
27cb93a386Sopenharmony_ci    kColorAttributeIsWide_GPFlag        = 0x2,
28cb93a386Sopenharmony_ci    kLocalCoordAttribute_GPFlag         = 0x4,
29cb93a386Sopenharmony_ci    kCoverageAttribute_GPFlag           = 0x8,
30cb93a386Sopenharmony_ci    kCoverageAttributeTweak_GPFlag      = 0x10,
31cb93a386Sopenharmony_ci    kCoverageAttributeUnclamped_GPFlag  = 0x20,
32cb93a386Sopenharmony_ci};
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ciclass DefaultGeoProc : public GrGeometryProcessor {
35cb93a386Sopenharmony_cipublic:
36cb93a386Sopenharmony_ci    static GrGeometryProcessor* Make(SkArenaAlloc* arena,
37cb93a386Sopenharmony_ci                                     uint32_t gpTypeFlags,
38cb93a386Sopenharmony_ci                                     const SkPMColor4f& color,
39cb93a386Sopenharmony_ci                                     const SkMatrix& viewMatrix,
40cb93a386Sopenharmony_ci                                     const SkMatrix& localMatrix,
41cb93a386Sopenharmony_ci                                     bool localCoordsWillBeRead,
42cb93a386Sopenharmony_ci                                     uint8_t coverage) {
43cb93a386Sopenharmony_ci        return arena->make([&](void* ptr) {
44cb93a386Sopenharmony_ci            return new (ptr) DefaultGeoProc(gpTypeFlags, color, viewMatrix, localMatrix, coverage,
45cb93a386Sopenharmony_ci                                            localCoordsWillBeRead);
46cb93a386Sopenharmony_ci        });
47cb93a386Sopenharmony_ci    }
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ci    const char* name() const override { return "DefaultGeometryProcessor"; }
50cb93a386Sopenharmony_ci
51cb93a386Sopenharmony_ci    SkString getShaderDfxInfo() const override {
52cb93a386Sopenharmony_ci        SkString format;
53cb93a386Sopenharmony_ci        format.printf("ShaderDfx_DefaultGeoProc_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d",
54cb93a386Sopenharmony_ci            fFlags, fCoverage, fLocalCoordsWillBeRead, fInLocalCoords.isInitialized(),
55cb93a386Sopenharmony_ci            fViewMatrix.isIdentity(), fViewMatrix.isScaleTranslate(), fViewMatrix.hasPerspective(),
56cb93a386Sopenharmony_ci            fLocalMatrix.isIdentity(), fLocalMatrix.isScaleTranslate(), fLocalMatrix.hasPerspective());
57cb93a386Sopenharmony_ci        return format;
58cb93a386Sopenharmony_ci    }
59cb93a386Sopenharmony_ci
60cb93a386Sopenharmony_ci    void addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override {
61cb93a386Sopenharmony_ci        uint32_t key = fFlags;
62cb93a386Sopenharmony_ci        key |= fCoverage == 0xff      ?  0x80 : 0;
63cb93a386Sopenharmony_ci        key |= fLocalCoordsWillBeRead ? 0x100 : 0;
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci        bool usesLocalMatrix = fLocalCoordsWillBeRead && !fInLocalCoords.isInitialized();
66cb93a386Sopenharmony_ci        key = ProgramImpl::AddMatrixKeys(caps,
67cb93a386Sopenharmony_ci                                         key,
68cb93a386Sopenharmony_ci                                         fViewMatrix,
69cb93a386Sopenharmony_ci                                         usesLocalMatrix ? fLocalMatrix : SkMatrix::I());
70cb93a386Sopenharmony_ci        b->add32(key);
71cb93a386Sopenharmony_ci    }
72cb93a386Sopenharmony_ci
73cb93a386Sopenharmony_ci    std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override {
74cb93a386Sopenharmony_ci        return std::make_unique<Impl>();
75cb93a386Sopenharmony_ci    }
76cb93a386Sopenharmony_ci
77cb93a386Sopenharmony_ciprivate:
78cb93a386Sopenharmony_ci    class Impl : public ProgramImpl {
79cb93a386Sopenharmony_ci    public:
80cb93a386Sopenharmony_ci        void setData(const GrGLSLProgramDataManager& pdman,
81cb93a386Sopenharmony_ci                     const GrShaderCaps& shaderCaps,
82cb93a386Sopenharmony_ci                     const GrGeometryProcessor& geomProc) override {
83cb93a386Sopenharmony_ci            const DefaultGeoProc& dgp = geomProc.cast<DefaultGeoProc>();
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci            SetTransform(pdman, shaderCaps, fViewMatrixUniform, dgp.fViewMatrix, &fViewMatrixPrev);
86cb93a386Sopenharmony_ci            SetTransform(pdman,
87cb93a386Sopenharmony_ci                         shaderCaps,
88cb93a386Sopenharmony_ci                         fLocalMatrixUniform,
89cb93a386Sopenharmony_ci                         dgp.fLocalMatrix,
90cb93a386Sopenharmony_ci                         &fLocalMatrixPrev);
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci            if (!dgp.hasVertexColor() && dgp.fColor != fColor) {
93cb93a386Sopenharmony_ci                pdman.set4fv(fColorUniform, 1, dgp.fColor.vec());
94cb93a386Sopenharmony_ci                fColor = dgp.fColor;
95cb93a386Sopenharmony_ci            }
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci            if (dgp.fCoverage != fCoverage && !dgp.hasVertexCoverage()) {
98cb93a386Sopenharmony_ci                pdman.set1f(fCoverageUniform, GrNormalizeByteToFloat(dgp.fCoverage));
99cb93a386Sopenharmony_ci                fCoverage = dgp.fCoverage;
100cb93a386Sopenharmony_ci            }
101cb93a386Sopenharmony_ci        }
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci    private:
104cb93a386Sopenharmony_ci        void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
105cb93a386Sopenharmony_ci            const DefaultGeoProc& gp = args.fGeomProc.cast<DefaultGeoProc>();
106cb93a386Sopenharmony_ci            GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder;
107cb93a386Sopenharmony_ci            GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
108cb93a386Sopenharmony_ci            GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler;
109cb93a386Sopenharmony_ci            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
110cb93a386Sopenharmony_ci
111cb93a386Sopenharmony_ci            // emit attributes
112cb93a386Sopenharmony_ci            varyingHandler->emitAttributes(gp);
113cb93a386Sopenharmony_ci
114cb93a386Sopenharmony_ci            bool tweakAlpha = SkToBool(gp.fFlags & kCoverageAttributeTweak_GPFlag);
115cb93a386Sopenharmony_ci            bool coverageNeedsSaturate = SkToBool(gp.fFlags & kCoverageAttributeUnclamped_GPFlag);
116cb93a386Sopenharmony_ci            SkASSERT(!tweakAlpha || gp.hasVertexCoverage());
117cb93a386Sopenharmony_ci            SkASSERT(!tweakAlpha || !coverageNeedsSaturate);
118cb93a386Sopenharmony_ci
119cb93a386Sopenharmony_ci            // Setup pass through color
120cb93a386Sopenharmony_ci            fragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
121cb93a386Sopenharmony_ci            if (gp.hasVertexColor() || tweakAlpha) {
122cb93a386Sopenharmony_ci                GrGLSLVarying varying(kHalf4_GrSLType);
123cb93a386Sopenharmony_ci                varyingHandler->addVarying("color", &varying);
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_ci                // Start with the attribute or with uniform color
126cb93a386Sopenharmony_ci                if (gp.hasVertexColor()) {
127cb93a386Sopenharmony_ci                    vertBuilder->codeAppendf("half4 color = %s;", gp.fInColor.name());
128cb93a386Sopenharmony_ci                } else {
129cb93a386Sopenharmony_ci                    const char* colorUniformName;
130cb93a386Sopenharmony_ci                    fColorUniform = uniformHandler->addUniform(nullptr,
131cb93a386Sopenharmony_ci                                                               kVertex_GrShaderFlag,
132cb93a386Sopenharmony_ci                                                               kHalf4_GrSLType,
133cb93a386Sopenharmony_ci                                                               "Color",
134cb93a386Sopenharmony_ci                                                               &colorUniformName);
135cb93a386Sopenharmony_ci                    vertBuilder->codeAppendf("half4 color = %s;", colorUniformName);
136cb93a386Sopenharmony_ci                }
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_ci                // Optionally fold coverage into alpha (color).
139cb93a386Sopenharmony_ci                if (tweakAlpha) {
140cb93a386Sopenharmony_ci                    vertBuilder->codeAppendf("color = color * %s;", gp.fInCoverage.name());
141cb93a386Sopenharmony_ci                }
142cb93a386Sopenharmony_ci                vertBuilder->codeAppendf("%s = color;\n", varying.vsOut());
143cb93a386Sopenharmony_ci                fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn());
144cb93a386Sopenharmony_ci            } else {
145cb93a386Sopenharmony_ci                this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor,
146cb93a386Sopenharmony_ci                                        &fColorUniform);
147cb93a386Sopenharmony_ci            }
148cb93a386Sopenharmony_ci
149cb93a386Sopenharmony_ci            // Setup position
150cb93a386Sopenharmony_ci            WriteOutputPosition(vertBuilder,
151cb93a386Sopenharmony_ci                                uniformHandler,
152cb93a386Sopenharmony_ci                                *args.fShaderCaps,
153cb93a386Sopenharmony_ci                                gpArgs,
154cb93a386Sopenharmony_ci                                gp.fInPosition.name(),
155cb93a386Sopenharmony_ci                                gp.fViewMatrix,
156cb93a386Sopenharmony_ci                                &fViewMatrixUniform);
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci            // emit transforms using either explicit local coords or positions
159cb93a386Sopenharmony_ci            if (gp.fInLocalCoords.isInitialized()) {
160cb93a386Sopenharmony_ci                SkASSERT(gp.fLocalMatrix.isIdentity());
161cb93a386Sopenharmony_ci                gpArgs->fLocalCoordVar = gp.fInLocalCoords.asShaderVar();
162cb93a386Sopenharmony_ci            } else if (gp.fLocalCoordsWillBeRead) {
163cb93a386Sopenharmony_ci                WriteLocalCoord(vertBuilder,
164cb93a386Sopenharmony_ci                                uniformHandler,
165cb93a386Sopenharmony_ci                                *args.fShaderCaps,
166cb93a386Sopenharmony_ci                                gpArgs,
167cb93a386Sopenharmony_ci                                gp.fInPosition.asShaderVar(),
168cb93a386Sopenharmony_ci                                gp.fLocalMatrix,
169cb93a386Sopenharmony_ci                                &fLocalMatrixUniform);
170cb93a386Sopenharmony_ci            }
171cb93a386Sopenharmony_ci
172cb93a386Sopenharmony_ci            // Setup coverage as pass through
173cb93a386Sopenharmony_ci            if (gp.hasVertexCoverage() && !tweakAlpha) {
174cb93a386Sopenharmony_ci                fragBuilder->codeAppendf("half alpha = 1.0;");
175cb93a386Sopenharmony_ci                varyingHandler->addPassThroughAttribute(gp.fInCoverage.asShaderVar(), "alpha");
176cb93a386Sopenharmony_ci                if (coverageNeedsSaturate) {
177cb93a386Sopenharmony_ci                    fragBuilder->codeAppendf("half4 %s = half4(saturate(alpha));",
178cb93a386Sopenharmony_ci                                             args.fOutputCoverage);
179cb93a386Sopenharmony_ci                } else {
180cb93a386Sopenharmony_ci                    fragBuilder->codeAppendf("half4 %s = half4(alpha);", args.fOutputCoverage);
181cb93a386Sopenharmony_ci                }
182cb93a386Sopenharmony_ci            } else if (gp.fCoverage == 0xff) {
183cb93a386Sopenharmony_ci                fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage);
184cb93a386Sopenharmony_ci            } else {
185cb93a386Sopenharmony_ci                const char* fragCoverage;
186cb93a386Sopenharmony_ci                fCoverageUniform = uniformHandler->addUniform(nullptr,
187cb93a386Sopenharmony_ci                                                              kFragment_GrShaderFlag,
188cb93a386Sopenharmony_ci                                                              kHalf_GrSLType,
189cb93a386Sopenharmony_ci                                                              "Coverage",
190cb93a386Sopenharmony_ci                                                              &fragCoverage);
191cb93a386Sopenharmony_ci                fragBuilder->codeAppendf("half4 %s = half4(%s);",
192cb93a386Sopenharmony_ci                                         args.fOutputCoverage, fragCoverage);
193cb93a386Sopenharmony_ci            }
194cb93a386Sopenharmony_ci        }
195cb93a386Sopenharmony_ci
196cb93a386Sopenharmony_ci        SkMatrix    fViewMatrixPrev  = SkMatrix::InvalidMatrix();
197cb93a386Sopenharmony_ci        SkMatrix    fLocalMatrixPrev = SkMatrix::InvalidMatrix();
198cb93a386Sopenharmony_ci        SkPMColor4f fColor           = SK_PMColor4fILLEGAL;
199cb93a386Sopenharmony_ci        uint8_t     fCoverage        = 0xFF;
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci        UniformHandle fViewMatrixUniform;
202cb93a386Sopenharmony_ci        UniformHandle fLocalMatrixUniform;
203cb93a386Sopenharmony_ci        UniformHandle fColorUniform;
204cb93a386Sopenharmony_ci        UniformHandle fCoverageUniform;
205cb93a386Sopenharmony_ci    };
206cb93a386Sopenharmony_ci
207cb93a386Sopenharmony_ci    bool hasVertexColor() const { return fInColor.isInitialized(); }
208cb93a386Sopenharmony_ci    bool hasVertexCoverage() const { return fInCoverage.isInitialized(); }
209cb93a386Sopenharmony_ci
210cb93a386Sopenharmony_ci    DefaultGeoProc(uint32_t gpTypeFlags,
211cb93a386Sopenharmony_ci                   const SkPMColor4f& color,
212cb93a386Sopenharmony_ci                   const SkMatrix& viewMatrix,
213cb93a386Sopenharmony_ci                   const SkMatrix& localMatrix,
214cb93a386Sopenharmony_ci                   uint8_t coverage,
215cb93a386Sopenharmony_ci                   bool localCoordsWillBeRead)
216cb93a386Sopenharmony_ci            : INHERITED(kDefaultGeoProc_ClassID)
217cb93a386Sopenharmony_ci            , fColor(color)
218cb93a386Sopenharmony_ci            , fViewMatrix(viewMatrix)
219cb93a386Sopenharmony_ci            , fLocalMatrix(localMatrix)
220cb93a386Sopenharmony_ci            , fCoverage(coverage)
221cb93a386Sopenharmony_ci            , fFlags(gpTypeFlags)
222cb93a386Sopenharmony_ci            , fLocalCoordsWillBeRead(localCoordsWillBeRead) {
223cb93a386Sopenharmony_ci        fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
224cb93a386Sopenharmony_ci        if (fFlags & kColorAttribute_GPFlag) {
225cb93a386Sopenharmony_ci            fInColor = MakeColorAttribute("inColor",
226cb93a386Sopenharmony_ci                                          SkToBool(fFlags & kColorAttributeIsWide_GPFlag));
227cb93a386Sopenharmony_ci        }
228cb93a386Sopenharmony_ci        if (fFlags & kLocalCoordAttribute_GPFlag) {
229cb93a386Sopenharmony_ci            fInLocalCoords = {"inLocalCoord", kFloat2_GrVertexAttribType,
230cb93a386Sopenharmony_ci                                              kFloat2_GrSLType};
231cb93a386Sopenharmony_ci        }
232cb93a386Sopenharmony_ci        if (fFlags & kCoverageAttribute_GPFlag) {
233cb93a386Sopenharmony_ci            fInCoverage = {"inCoverage", kFloat_GrVertexAttribType, kHalf_GrSLType};
234cb93a386Sopenharmony_ci        }
235cb93a386Sopenharmony_ci        this->setVertexAttributes(&fInPosition, 4);
236cb93a386Sopenharmony_ci    }
237cb93a386Sopenharmony_ci
238cb93a386Sopenharmony_ci    Attribute fInPosition;
239cb93a386Sopenharmony_ci    Attribute fInColor;
240cb93a386Sopenharmony_ci    Attribute fInLocalCoords;
241cb93a386Sopenharmony_ci    Attribute fInCoverage;
242cb93a386Sopenharmony_ci    SkPMColor4f fColor;
243cb93a386Sopenharmony_ci    SkMatrix fViewMatrix;
244cb93a386Sopenharmony_ci    SkMatrix fLocalMatrix;
245cb93a386Sopenharmony_ci    uint8_t fCoverage;
246cb93a386Sopenharmony_ci    uint32_t fFlags;
247cb93a386Sopenharmony_ci    bool fLocalCoordsWillBeRead;
248cb93a386Sopenharmony_ci
249cb93a386Sopenharmony_ci    GR_DECLARE_GEOMETRY_PROCESSOR_TEST
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci    using INHERITED = GrGeometryProcessor;
252cb93a386Sopenharmony_ci};
253cb93a386Sopenharmony_ci
254cb93a386Sopenharmony_ciGR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc);
255cb93a386Sopenharmony_ci
256cb93a386Sopenharmony_ci#if GR_TEST_UTILS
257cb93a386Sopenharmony_ciGrGeometryProcessor* DefaultGeoProc::TestCreate(GrProcessorTestData* d) {
258cb93a386Sopenharmony_ci    uint32_t flags = 0;
259cb93a386Sopenharmony_ci    if (d->fRandom->nextBool()) {
260cb93a386Sopenharmony_ci        flags |= kColorAttribute_GPFlag;
261cb93a386Sopenharmony_ci    }
262cb93a386Sopenharmony_ci    if (d->fRandom->nextBool()) {
263cb93a386Sopenharmony_ci        flags |= kColorAttributeIsWide_GPFlag;
264cb93a386Sopenharmony_ci    }
265cb93a386Sopenharmony_ci    if (d->fRandom->nextBool()) {
266cb93a386Sopenharmony_ci        flags |= kCoverageAttribute_GPFlag;
267cb93a386Sopenharmony_ci        if (d->fRandom->nextBool()) {
268cb93a386Sopenharmony_ci            flags |= (d->fRandom->nextBool()) ? kCoverageAttributeTweak_GPFlag
269cb93a386Sopenharmony_ci                                              : kCoverageAttributeUnclamped_GPFlag;
270cb93a386Sopenharmony_ci        }
271cb93a386Sopenharmony_ci    }
272cb93a386Sopenharmony_ci    if (d->fRandom->nextBool()) {
273cb93a386Sopenharmony_ci        flags |= kLocalCoordAttribute_GPFlag;
274cb93a386Sopenharmony_ci    }
275cb93a386Sopenharmony_ci
276cb93a386Sopenharmony_ci    GrColor color = GrTest::RandomColor(d->fRandom);
277cb93a386Sopenharmony_ci    SkMatrix viewMtx = GrTest::TestMatrix(d->fRandom);
278cb93a386Sopenharmony_ci    SkMatrix localMtx = GrTest::TestMatrix(d->fRandom);
279cb93a386Sopenharmony_ci    bool readsLocalCoords = d->fRandom->nextBool();
280cb93a386Sopenharmony_ci    uint8_t coverage = GrTest::RandomCoverage(d->fRandom);
281cb93a386Sopenharmony_ci    return DefaultGeoProc::Make(d->allocator(),
282cb93a386Sopenharmony_ci                                flags,
283cb93a386Sopenharmony_ci                                SkPMColor4f::FromBytes_RGBA(color),
284cb93a386Sopenharmony_ci                                viewMtx,
285cb93a386Sopenharmony_ci                                localMtx,
286cb93a386Sopenharmony_ci                                readsLocalCoords,
287cb93a386Sopenharmony_ci                                coverage);
288cb93a386Sopenharmony_ci}
289cb93a386Sopenharmony_ci#endif
290cb93a386Sopenharmony_ci
291cb93a386Sopenharmony_ciGrGeometryProcessor* GrDefaultGeoProcFactory::Make(SkArenaAlloc* arena,
292cb93a386Sopenharmony_ci                                                   const Color& color,
293cb93a386Sopenharmony_ci                                                   const Coverage& coverage,
294cb93a386Sopenharmony_ci                                                   const LocalCoords& localCoords,
295cb93a386Sopenharmony_ci                                                   const SkMatrix& viewMatrix) {
296cb93a386Sopenharmony_ci    uint32_t flags = 0;
297cb93a386Sopenharmony_ci    if (Color::kPremulGrColorAttribute_Type == color.fType) {
298cb93a386Sopenharmony_ci        flags |= kColorAttribute_GPFlag;
299cb93a386Sopenharmony_ci    } else if (Color::kPremulWideColorAttribute_Type == color.fType) {
300cb93a386Sopenharmony_ci        flags |= kColorAttribute_GPFlag | kColorAttributeIsWide_GPFlag;
301cb93a386Sopenharmony_ci    }
302cb93a386Sopenharmony_ci    if (Coverage::kAttribute_Type == coverage.fType) {
303cb93a386Sopenharmony_ci        flags |= kCoverageAttribute_GPFlag;
304cb93a386Sopenharmony_ci    } else if (Coverage::kAttributeTweakAlpha_Type == coverage.fType) {
305cb93a386Sopenharmony_ci        flags |= kCoverageAttribute_GPFlag | kCoverageAttributeTweak_GPFlag;
306cb93a386Sopenharmony_ci    } else if (Coverage::kAttributeUnclamped_Type == coverage.fType) {
307cb93a386Sopenharmony_ci        flags |= kCoverageAttribute_GPFlag | kCoverageAttributeUnclamped_GPFlag;
308cb93a386Sopenharmony_ci    }
309cb93a386Sopenharmony_ci    flags |= localCoords.fType == LocalCoords::kHasExplicit_Type ? kLocalCoordAttribute_GPFlag : 0;
310cb93a386Sopenharmony_ci
311cb93a386Sopenharmony_ci    uint8_t inCoverage = coverage.fCoverage;
312cb93a386Sopenharmony_ci    bool localCoordsWillBeRead = localCoords.fType != LocalCoords::kUnused_Type;
313cb93a386Sopenharmony_ci
314cb93a386Sopenharmony_ci    return DefaultGeoProc::Make(arena,
315cb93a386Sopenharmony_ci                                flags,
316cb93a386Sopenharmony_ci                                color.fColor,
317cb93a386Sopenharmony_ci                                viewMatrix,
318cb93a386Sopenharmony_ci                                localCoords.fMatrix ? *localCoords.fMatrix : SkMatrix::I(),
319cb93a386Sopenharmony_ci                                localCoordsWillBeRead,
320cb93a386Sopenharmony_ci                                inCoverage);
321cb93a386Sopenharmony_ci}
322cb93a386Sopenharmony_ci
323cb93a386Sopenharmony_ciGrGeometryProcessor* GrDefaultGeoProcFactory::MakeForDeviceSpace(SkArenaAlloc* arena,
324cb93a386Sopenharmony_ci                                                                 const Color& color,
325cb93a386Sopenharmony_ci                                                                 const Coverage& coverage,
326cb93a386Sopenharmony_ci                                                                 const LocalCoords& localCoords,
327cb93a386Sopenharmony_ci                                                                 const SkMatrix& viewMatrix) {
328cb93a386Sopenharmony_ci    SkMatrix invert = SkMatrix::I();
329cb93a386Sopenharmony_ci    if (LocalCoords::kUnused_Type != localCoords.fType) {
330cb93a386Sopenharmony_ci        SkASSERT(LocalCoords::kUsePosition_Type == localCoords.fType);
331cb93a386Sopenharmony_ci        if (!viewMatrix.isIdentity() && !viewMatrix.invert(&invert)) {
332cb93a386Sopenharmony_ci            return nullptr;
333cb93a386Sopenharmony_ci        }
334cb93a386Sopenharmony_ci
335cb93a386Sopenharmony_ci        if (localCoords.hasLocalMatrix()) {
336cb93a386Sopenharmony_ci            invert.postConcat(*localCoords.fMatrix);
337cb93a386Sopenharmony_ci        }
338cb93a386Sopenharmony_ci    }
339cb93a386Sopenharmony_ci
340cb93a386Sopenharmony_ci    LocalCoords inverted(LocalCoords::kUsePosition_Type, &invert);
341cb93a386Sopenharmony_ci    return Make(arena, color, coverage, inverted, SkMatrix::I());
342cb93a386Sopenharmony_ci}
343