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