xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/DrawAtlasPathOp.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2020 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/ops/DrawAtlasPathOp.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAlignedStorage.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkOnce.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkPoint_impl.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkSLTypeShared.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/BufferWriter.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/KeyBuilder.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ResourceKey.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrAppliedClip.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBuffer.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDstProxyView.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGeometryProcessor.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpuBuffer.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrOpFlushState.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPipeline.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProcessorAnalysis.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProgramInfo.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTargetProxy.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderCaps.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrShaderVar.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrUserStencilSettings.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLUniformHandler.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/glsl/GrGLSLVertexGeoBuilder.h"
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
46*c8dee2aaSAndroid Build Coastguard Worker 
47*c8dee2aaSAndroid Build Coastguard Worker class GrGLSLProgramDataManager;
48*c8dee2aaSAndroid Build Coastguard Worker enum class GrXferBarrierFlags;
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker namespace {
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker class DrawAtlasPathShader : public GrGeometryProcessor {
55*c8dee2aaSAndroid Build Coastguard Worker public:
DrawAtlasPathShader(bool usesLocalCoords,const skgpu::ganesh::AtlasInstancedHelper * atlasHelper,const GrShaderCaps & shaderCaps)56*c8dee2aaSAndroid Build Coastguard Worker     DrawAtlasPathShader(bool usesLocalCoords,
57*c8dee2aaSAndroid Build Coastguard Worker                         const skgpu::ganesh::AtlasInstancedHelper* atlasHelper,
58*c8dee2aaSAndroid Build Coastguard Worker                         const GrShaderCaps& shaderCaps)
59*c8dee2aaSAndroid Build Coastguard Worker             : GrGeometryProcessor(kDrawAtlasPathShader_ClassID)
60*c8dee2aaSAndroid Build Coastguard Worker             , fUsesLocalCoords(usesLocalCoords)
61*c8dee2aaSAndroid Build Coastguard Worker             , fAtlasHelper(atlasHelper)
62*c8dee2aaSAndroid Build Coastguard Worker             , fAtlasAccess(GrSamplerState::Filter::kNearest,
63*c8dee2aaSAndroid Build Coastguard Worker                            fAtlasHelper->proxy()->backendFormat(),
64*c8dee2aaSAndroid Build Coastguard Worker                            fAtlasHelper->atlasSwizzle()) {
65*c8dee2aaSAndroid Build Coastguard Worker         if (!shaderCaps.fVertexIDSupport) {
66*c8dee2aaSAndroid Build Coastguard Worker             constexpr static Attribute kUnitCoordAttrib(
67*c8dee2aaSAndroid Build Coastguard Worker                     "unitCoord", kFloat2_GrVertexAttribType, SkSLType::kFloat2);
68*c8dee2aaSAndroid Build Coastguard Worker             this->setVertexAttributesWithImplicitOffsets(&kUnitCoordAttrib, 1);
69*c8dee2aaSAndroid Build Coastguard Worker         }
70*c8dee2aaSAndroid Build Coastguard Worker         fAttribs.emplace_back("fillBounds", kFloat4_GrVertexAttribType, SkSLType::kFloat4);
71*c8dee2aaSAndroid Build Coastguard Worker         if (fUsesLocalCoords) {
72*c8dee2aaSAndroid Build Coastguard Worker             fAttribs.emplace_back("affineMatrix", kFloat4_GrVertexAttribType, SkSLType::kFloat4);
73*c8dee2aaSAndroid Build Coastguard Worker             fAttribs.emplace_back("translate", kFloat2_GrVertexAttribType, SkSLType::kFloat2);
74*c8dee2aaSAndroid Build Coastguard Worker         }
75*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fAttribs.size() == this->colorAttribIdx());
76*c8dee2aaSAndroid Build Coastguard Worker         fAttribs.emplace_back("color", kFloat4_GrVertexAttribType, SkSLType::kHalf4);
77*c8dee2aaSAndroid Build Coastguard Worker         fAtlasHelper->appendInstanceAttribs(&fAttribs);
78*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fAttribs.size() <= kMaxInstanceAttribs);
79*c8dee2aaSAndroid Build Coastguard Worker         this->setInstanceAttributesWithImplicitOffsets(fAttribs.data(), fAttribs.size());
80*c8dee2aaSAndroid Build Coastguard Worker         this->setTextureSamplerCnt(1);
81*c8dee2aaSAndroid Build Coastguard Worker     }
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker private:
84*c8dee2aaSAndroid Build Coastguard Worker     class Impl;
85*c8dee2aaSAndroid Build Coastguard Worker 
colorAttribIdx() const86*c8dee2aaSAndroid Build Coastguard Worker     int colorAttribIdx() const { return fUsesLocalCoords ? 3 : 1; }
name() const87*c8dee2aaSAndroid Build Coastguard Worker     const char* name() const override { return "DrawAtlasPathShader"; }
addToKey(const GrShaderCaps &,skgpu::KeyBuilder * b) const88*c8dee2aaSAndroid Build Coastguard Worker     void addToKey(const GrShaderCaps&, skgpu::KeyBuilder* b) const override {
89*c8dee2aaSAndroid Build Coastguard Worker         b->addBits(1, fUsesLocalCoords, "localCoords");
90*c8dee2aaSAndroid Build Coastguard Worker         fAtlasHelper->getKeyBits(b);
91*c8dee2aaSAndroid Build Coastguard Worker     }
onTextureSampler(int) const92*c8dee2aaSAndroid Build Coastguard Worker     const TextureSampler& onTextureSampler(int) const override { return fAtlasAccess; }
93*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override;
94*c8dee2aaSAndroid Build Coastguard Worker 
95*c8dee2aaSAndroid Build Coastguard Worker     const bool fUsesLocalCoords;
96*c8dee2aaSAndroid Build Coastguard Worker     const skgpu::ganesh::AtlasInstancedHelper* const fAtlasHelper;
97*c8dee2aaSAndroid Build Coastguard Worker     TextureSampler fAtlasAccess;
98*c8dee2aaSAndroid Build Coastguard Worker     constexpr static int kMaxInstanceAttribs = 6;
99*c8dee2aaSAndroid Build Coastguard Worker     STArray<kMaxInstanceAttribs, GrGeometryProcessor::Attribute> fAttribs;
100*c8dee2aaSAndroid Build Coastguard Worker };
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker class DrawAtlasPathShader::Impl : public ProgramImpl {
103*c8dee2aaSAndroid Build Coastguard Worker public:
setData(const GrGLSLProgramDataManager & pdman,const GrShaderCaps &,const GrGeometryProcessor & geomProc)104*c8dee2aaSAndroid Build Coastguard Worker     void setData(const GrGLSLProgramDataManager& pdman,
105*c8dee2aaSAndroid Build Coastguard Worker                  const GrShaderCaps&,
106*c8dee2aaSAndroid Build Coastguard Worker                  const GrGeometryProcessor& geomProc) override {
107*c8dee2aaSAndroid Build Coastguard Worker         auto* atlasHelper = geomProc.cast<DrawAtlasPathShader>().fAtlasHelper;
108*c8dee2aaSAndroid Build Coastguard Worker         atlasHelper->setUniformData(pdman, fAtlasAdjustUniform);
109*c8dee2aaSAndroid Build Coastguard Worker     }
110*c8dee2aaSAndroid Build Coastguard Worker 
111*c8dee2aaSAndroid Build Coastguard Worker private:
onEmitCode(EmitArgs & args,GrGPArgs * gpArgs)112*c8dee2aaSAndroid Build Coastguard Worker     void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
113*c8dee2aaSAndroid Build Coastguard Worker         const auto& shader = args.fGeomProc.cast<DrawAtlasPathShader>();
114*c8dee2aaSAndroid Build Coastguard Worker         args.fVaryingHandler->emitAttributes(shader);
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker         if (args.fShaderCaps->fVertexIDSupport) {
117*c8dee2aaSAndroid Build Coastguard Worker             // If we don't have sk_VertexID support then "unitCoord" already came in as a vertex
118*c8dee2aaSAndroid Build Coastguard Worker             // attrib.
119*c8dee2aaSAndroid Build Coastguard Worker             args.fVertBuilder->codeAppendf(R"(
120*c8dee2aaSAndroid Build Coastguard Worker             float2 unitCoord = float2(sk_VertexID & 1, sk_VertexID >> 1);)");
121*c8dee2aaSAndroid Build Coastguard Worker         }
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker         args.fVertBuilder->codeAppendf(R"(
124*c8dee2aaSAndroid Build Coastguard Worker         float2 devCoord = mix(fillBounds.xy, fillBounds.zw, unitCoord);)");
125*c8dee2aaSAndroid Build Coastguard Worker         gpArgs->fPositionVar.set(SkSLType::kFloat2, "devCoord");
126*c8dee2aaSAndroid Build Coastguard Worker 
127*c8dee2aaSAndroid Build Coastguard Worker         if (shader.fUsesLocalCoords) {
128*c8dee2aaSAndroid Build Coastguard Worker             args.fVertBuilder->codeAppendf(R"(
129*c8dee2aaSAndroid Build Coastguard Worker             float2x2 M = float2x2(affineMatrix.xy, affineMatrix.zw);
130*c8dee2aaSAndroid Build Coastguard Worker             float2 localCoord = inverse(M) * (devCoord - translate);)");
131*c8dee2aaSAndroid Build Coastguard Worker             gpArgs->fLocalCoordVar.set(SkSLType::kFloat2, "localCoord");
132*c8dee2aaSAndroid Build Coastguard Worker         }
133*c8dee2aaSAndroid Build Coastguard Worker 
134*c8dee2aaSAndroid Build Coastguard Worker         args.fFragBuilder->codeAppendf("half4 %s = half4(1);", args.fOutputCoverage);
135*c8dee2aaSAndroid Build Coastguard Worker         shader.fAtlasHelper->injectShaderCode(args, gpArgs->fPositionVar, &fAtlasAdjustUniform);
136*c8dee2aaSAndroid Build Coastguard Worker 
137*c8dee2aaSAndroid Build Coastguard Worker         args.fFragBuilder->codeAppendf("half4 %s;", args.fOutputColor);
138*c8dee2aaSAndroid Build Coastguard Worker         args.fVaryingHandler->addPassThroughAttribute(
139*c8dee2aaSAndroid Build Coastguard Worker                 shader.fAttribs[shader.colorAttribIdx()].asShaderVar(),
140*c8dee2aaSAndroid Build Coastguard Worker                 args.fOutputColor,
141*c8dee2aaSAndroid Build Coastguard Worker                 GrGLSLVaryingHandler::Interpolation::kCanBeFlat);
142*c8dee2aaSAndroid Build Coastguard Worker     }
143*c8dee2aaSAndroid Build Coastguard Worker 
144*c8dee2aaSAndroid Build Coastguard Worker     GrGLSLUniformHandler::UniformHandle fAtlasAdjustUniform;
145*c8dee2aaSAndroid Build Coastguard Worker };
146*c8dee2aaSAndroid Build Coastguard Worker 
makeProgramImpl(const GrShaderCaps &) const147*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<GrGeometryProcessor::ProgramImpl> DrawAtlasPathShader::makeProgramImpl(
148*c8dee2aaSAndroid Build Coastguard Worker         const GrShaderCaps&) const {
149*c8dee2aaSAndroid Build Coastguard Worker     return std::make_unique<Impl>();
150*c8dee2aaSAndroid Build Coastguard Worker }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker }  // anonymous namespace
153*c8dee2aaSAndroid Build Coastguard Worker 
154*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::ganesh {
155*c8dee2aaSAndroid Build Coastguard Worker 
finalize(const GrCaps & caps,const GrAppliedClip * clip,GrClampType clampType)156*c8dee2aaSAndroid Build Coastguard Worker GrProcessorSet::Analysis DrawAtlasPathOp::finalize(const GrCaps& caps, const GrAppliedClip* clip,
157*c8dee2aaSAndroid Build Coastguard Worker                                                    GrClampType clampType) {
158*c8dee2aaSAndroid Build Coastguard Worker     const GrProcessorSet::Analysis& analysis = fProcessors.finalize(
159*c8dee2aaSAndroid Build Coastguard Worker             fHeadInstance->fColor, GrProcessorAnalysisCoverage::kSingleChannel, clip,
160*c8dee2aaSAndroid Build Coastguard Worker             &GrUserStencilSettings::kUnused, caps, clampType, &fHeadInstance->fColor);
161*c8dee2aaSAndroid Build Coastguard Worker     fUsesLocalCoords = analysis.usesLocalCoords();
162*c8dee2aaSAndroid Build Coastguard Worker     return analysis;
163*c8dee2aaSAndroid Build Coastguard Worker }
164*c8dee2aaSAndroid Build Coastguard Worker 
onCombineIfPossible(GrOp * op,SkArenaAlloc *,const GrCaps &)165*c8dee2aaSAndroid Build Coastguard Worker GrOp::CombineResult DrawAtlasPathOp::onCombineIfPossible(GrOp* op, SkArenaAlloc*, const GrCaps&) {
166*c8dee2aaSAndroid Build Coastguard Worker     auto that = op->cast<DrawAtlasPathOp>();
167*c8dee2aaSAndroid Build Coastguard Worker 
168*c8dee2aaSAndroid Build Coastguard Worker     if (!fAtlasHelper.isCompatible(that->fAtlasHelper) ||
169*c8dee2aaSAndroid Build Coastguard Worker         fProcessors != that->fProcessors) {
170*c8dee2aaSAndroid Build Coastguard Worker         return CombineResult::kCannotCombine;
171*c8dee2aaSAndroid Build Coastguard Worker     }
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fUsesLocalCoords == that->fUsesLocalCoords);
174*c8dee2aaSAndroid Build Coastguard Worker     *fTailInstance = that->fHeadInstance;
175*c8dee2aaSAndroid Build Coastguard Worker     fTailInstance = that->fTailInstance;
176*c8dee2aaSAndroid Build Coastguard Worker     fInstanceCount += that->fInstanceCount;
177*c8dee2aaSAndroid Build Coastguard Worker     return CombineResult::kMerged;
178*c8dee2aaSAndroid Build Coastguard Worker }
179*c8dee2aaSAndroid Build Coastguard Worker 
prepareProgram(const GrCaps & caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,bool usesMSAASurface,GrAppliedClip && appliedClip,const GrDstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)180*c8dee2aaSAndroid Build Coastguard Worker void DrawAtlasPathOp::prepareProgram(const GrCaps& caps, SkArenaAlloc* arena,
181*c8dee2aaSAndroid Build Coastguard Worker                                      const GrSurfaceProxyView& writeView, bool usesMSAASurface,
182*c8dee2aaSAndroid Build Coastguard Worker                                      GrAppliedClip&& appliedClip,
183*c8dee2aaSAndroid Build Coastguard Worker                                      const GrDstProxyView& dstProxyView,
184*c8dee2aaSAndroid Build Coastguard Worker                                      GrXferBarrierFlags renderPassXferBarriers,
185*c8dee2aaSAndroid Build Coastguard Worker                                      GrLoadOp colorLoadOp) {
186*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!fProgram);
187*c8dee2aaSAndroid Build Coastguard Worker     GrPipeline::InitArgs initArgs;
188*c8dee2aaSAndroid Build Coastguard Worker     initArgs.fCaps = &caps;
189*c8dee2aaSAndroid Build Coastguard Worker     initArgs.fDstProxyView = dstProxyView;
190*c8dee2aaSAndroid Build Coastguard Worker     initArgs.fWriteSwizzle = writeView.swizzle();
191*c8dee2aaSAndroid Build Coastguard Worker     auto pipeline = arena->make<GrPipeline>(initArgs, std::move(fProcessors),
192*c8dee2aaSAndroid Build Coastguard Worker                                             std::move(appliedClip));
193*c8dee2aaSAndroid Build Coastguard Worker     auto shader = arena->make<DrawAtlasPathShader>(fUsesLocalCoords, &fAtlasHelper,
194*c8dee2aaSAndroid Build Coastguard Worker                                                    *caps.shaderCaps());
195*c8dee2aaSAndroid Build Coastguard Worker     fProgram = arena->make<GrProgramInfo>(caps, writeView, usesMSAASurface, pipeline,
196*c8dee2aaSAndroid Build Coastguard Worker                                           &GrUserStencilSettings::kUnused, shader,
197*c8dee2aaSAndroid Build Coastguard Worker                                           GrPrimitiveType::kTriangleStrip,
198*c8dee2aaSAndroid Build Coastguard Worker                                           renderPassXferBarriers, colorLoadOp);
199*c8dee2aaSAndroid Build Coastguard Worker }
200*c8dee2aaSAndroid Build Coastguard Worker 
onPrePrepare(GrRecordingContext * rContext,const GrSurfaceProxyView & writeView,GrAppliedClip * appliedClip,const GrDstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)201*c8dee2aaSAndroid Build Coastguard Worker void DrawAtlasPathOp::onPrePrepare(GrRecordingContext* rContext,
202*c8dee2aaSAndroid Build Coastguard Worker                                    const GrSurfaceProxyView& writeView,
203*c8dee2aaSAndroid Build Coastguard Worker                                    GrAppliedClip* appliedClip, const GrDstProxyView& dstProxyView,
204*c8dee2aaSAndroid Build Coastguard Worker                                    GrXferBarrierFlags renderPassXferBarriers,
205*c8dee2aaSAndroid Build Coastguard Worker                                    GrLoadOp colorLoadOp) {
206*c8dee2aaSAndroid Build Coastguard Worker     // DMSAA is not supported on DDL.
207*c8dee2aaSAndroid Build Coastguard Worker     bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
208*c8dee2aaSAndroid Build Coastguard Worker     this->prepareProgram(*rContext->priv().caps(), rContext->priv().recordTimeAllocator(),
209*c8dee2aaSAndroid Build Coastguard Worker                          writeView, usesMSAASurface, std::move(*appliedClip), dstProxyView,
210*c8dee2aaSAndroid Build Coastguard Worker                          renderPassXferBarriers, colorLoadOp);
211*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(fProgram);
212*c8dee2aaSAndroid Build Coastguard Worker     rContext->priv().recordProgramInfo(fProgram);
213*c8dee2aaSAndroid Build Coastguard Worker }
214*c8dee2aaSAndroid Build Coastguard Worker 
215*c8dee2aaSAndroid Build Coastguard Worker SKGPU_DECLARE_STATIC_UNIQUE_KEY(gUnitQuadBufferKey);
216*c8dee2aaSAndroid Build Coastguard Worker 
onPrepare(GrOpFlushState * flushState)217*c8dee2aaSAndroid Build Coastguard Worker void DrawAtlasPathOp::onPrepare(GrOpFlushState* flushState) {
218*c8dee2aaSAndroid Build Coastguard Worker     if (!fProgram) {
219*c8dee2aaSAndroid Build Coastguard Worker         this->prepareProgram(flushState->caps(), flushState->allocator(), flushState->writeView(),
220*c8dee2aaSAndroid Build Coastguard Worker                              flushState->usesMSAASurface(), flushState->detachAppliedClip(),
221*c8dee2aaSAndroid Build Coastguard Worker                              flushState->dstProxyView(), flushState->renderPassBarriers(),
222*c8dee2aaSAndroid Build Coastguard Worker                              flushState->colorLoadOp());
223*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fProgram);
224*c8dee2aaSAndroid Build Coastguard Worker     }
225*c8dee2aaSAndroid Build Coastguard Worker 
226*c8dee2aaSAndroid Build Coastguard Worker     if (VertexWriter instanceWriter = flushState->makeVertexWriter(
227*c8dee2aaSAndroid Build Coastguard Worker                 fProgram->geomProc().instanceStride(), fInstanceCount, &fInstanceBuffer,
228*c8dee2aaSAndroid Build Coastguard Worker                 &fBaseInstance)) {
229*c8dee2aaSAndroid Build Coastguard Worker         for (const Instance* i = fHeadInstance; i; i = i->fNext) {
230*c8dee2aaSAndroid Build Coastguard Worker             instanceWriter << SkRect::Make(i->fFillBounds)
231*c8dee2aaSAndroid Build Coastguard Worker                            << VertexWriter::If(fUsesLocalCoords,
232*c8dee2aaSAndroid Build Coastguard Worker                                                i->fLocalToDeviceIfUsingLocalCoords)
233*c8dee2aaSAndroid Build Coastguard Worker                            << i->fColor;
234*c8dee2aaSAndroid Build Coastguard Worker             fAtlasHelper.writeInstanceData(&instanceWriter, &i->fAtlasInstance);
235*c8dee2aaSAndroid Build Coastguard Worker         }
236*c8dee2aaSAndroid Build Coastguard Worker     }
237*c8dee2aaSAndroid Build Coastguard Worker 
238*c8dee2aaSAndroid Build Coastguard Worker     if (!flushState->caps().shaderCaps()->fVertexIDSupport) {
239*c8dee2aaSAndroid Build Coastguard Worker         constexpr static SkPoint kUnitQuad[4] = {{0,0}, {0,1}, {1,0}, {1,1}};
240*c8dee2aaSAndroid Build Coastguard Worker 
241*c8dee2aaSAndroid Build Coastguard Worker         SKGPU_DEFINE_STATIC_UNIQUE_KEY(gUnitQuadBufferKey);
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker         fVertexBufferIfNoIDSupport = flushState->resourceProvider()->findOrMakeStaticBuffer(
244*c8dee2aaSAndroid Build Coastguard Worker                 GrGpuBufferType::kVertex, sizeof(kUnitQuad), kUnitQuad, gUnitQuadBufferKey);
245*c8dee2aaSAndroid Build Coastguard Worker     }
246*c8dee2aaSAndroid Build Coastguard Worker }
247*c8dee2aaSAndroid Build Coastguard Worker 
onExecute(GrOpFlushState * flushState,const SkRect & chainBounds)248*c8dee2aaSAndroid Build Coastguard Worker void DrawAtlasPathOp::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) {
249*c8dee2aaSAndroid Build Coastguard Worker     if (fProgram->geomProc().hasVertexAttributes() && !fVertexBufferIfNoIDSupport) {
250*c8dee2aaSAndroid Build Coastguard Worker         return;
251*c8dee2aaSAndroid Build Coastguard Worker     }
252*c8dee2aaSAndroid Build Coastguard Worker     flushState->bindPipelineAndScissorClip(*fProgram, this->bounds());
253*c8dee2aaSAndroid Build Coastguard Worker     flushState->bindTextures(fProgram->geomProc(), *fAtlasHelper.proxy(), fProgram->pipeline());
254*c8dee2aaSAndroid Build Coastguard Worker     flushState->bindBuffers(nullptr, std::move(fInstanceBuffer), fVertexBufferIfNoIDSupport);
255*c8dee2aaSAndroid Build Coastguard Worker     flushState->drawInstanced(fInstanceCount, fBaseInstance, 4, 0);
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker 
258*c8dee2aaSAndroid Build Coastguard Worker }  // namespace skgpu::ganesh
259