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 = ∩︀
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