xref: /aosp_15_r20/external/skia/src/gpu/ganesh/ops/GrMeshDrawOp.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2015 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/GrMeshDrawOp.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrRecordingContext.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkDebug.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMath.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrBuffer.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrMeshDrawTarget.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrOpFlushState.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRecordingContextPriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrRenderTargetProxy.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrResourceProvider.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSimpleMesh.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h"
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker class GrGpuBuffer;
24*c8dee2aaSAndroid Build Coastguard Worker 
GrMeshDrawOp(uint32_t classID)25*c8dee2aaSAndroid Build Coastguard Worker GrMeshDrawOp::GrMeshDrawOp(uint32_t classID) : INHERITED(classID) {}
26*c8dee2aaSAndroid Build Coastguard Worker 
onPrepare(GrOpFlushState * state)27*c8dee2aaSAndroid Build Coastguard Worker void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); }
28*c8dee2aaSAndroid Build Coastguard Worker 
createProgramInfo(GrMeshDrawTarget * target)29*c8dee2aaSAndroid Build Coastguard Worker void GrMeshDrawOp::createProgramInfo(GrMeshDrawTarget* target) {
30*c8dee2aaSAndroid Build Coastguard Worker     this->createProgramInfo(&target->caps(),
31*c8dee2aaSAndroid Build Coastguard Worker                             target->allocator(),
32*c8dee2aaSAndroid Build Coastguard Worker                             target->writeView(),
33*c8dee2aaSAndroid Build Coastguard Worker                             target->usesMSAASurface(),
34*c8dee2aaSAndroid Build Coastguard Worker                             target->detachAppliedClip(),
35*c8dee2aaSAndroid Build Coastguard Worker                             target->dstProxyView(),
36*c8dee2aaSAndroid Build Coastguard Worker                             target->renderPassBarriers(),
37*c8dee2aaSAndroid Build Coastguard Worker                             target->colorLoadOp());
38*c8dee2aaSAndroid Build Coastguard Worker }
39*c8dee2aaSAndroid Build Coastguard Worker 
CombinedQuadCountWillOverflow(GrAAType aaType,bool willBeUpgradedToAA,int combinedQuadCount)40*c8dee2aaSAndroid Build Coastguard Worker bool GrMeshDrawOp::CombinedQuadCountWillOverflow(GrAAType aaType,
41*c8dee2aaSAndroid Build Coastguard Worker                                                  bool willBeUpgradedToAA,
42*c8dee2aaSAndroid Build Coastguard Worker                                                  int combinedQuadCount) {
43*c8dee2aaSAndroid Build Coastguard Worker     bool willBeAA = (aaType == GrAAType::kCoverage) || willBeUpgradedToAA;
44*c8dee2aaSAndroid Build Coastguard Worker 
45*c8dee2aaSAndroid Build Coastguard Worker     return combinedQuadCount > (willBeAA ? GrResourceProvider::MaxNumAAQuads()
46*c8dee2aaSAndroid Build Coastguard Worker                                          : GrResourceProvider::MaxNumNonAAQuads());
47*c8dee2aaSAndroid Build Coastguard Worker }
48*c8dee2aaSAndroid Build Coastguard Worker 
49*c8dee2aaSAndroid Build Coastguard Worker // This onPrepareDraws implementation assumes the derived Op only has a single programInfo -
50*c8dee2aaSAndroid Build Coastguard Worker // which is the majority of the cases.
onPrePrepareDraws(GrRecordingContext * context,const GrSurfaceProxyView & writeView,GrAppliedClip * clip,const GrDstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp)51*c8dee2aaSAndroid Build Coastguard Worker void GrMeshDrawOp::onPrePrepareDraws(GrRecordingContext* context,
52*c8dee2aaSAndroid Build Coastguard Worker                                      const GrSurfaceProxyView& writeView,
53*c8dee2aaSAndroid Build Coastguard Worker                                      GrAppliedClip* clip,
54*c8dee2aaSAndroid Build Coastguard Worker                                      const GrDstProxyView& dstProxyView,
55*c8dee2aaSAndroid Build Coastguard Worker                                      GrXferBarrierFlags renderPassXferBarriers,
56*c8dee2aaSAndroid Build Coastguard Worker                                      GrLoadOp colorLoadOp) {
57*c8dee2aaSAndroid Build Coastguard Worker     SkArenaAlloc* arena = context->priv().recordTimeAllocator();
58*c8dee2aaSAndroid Build Coastguard Worker 
59*c8dee2aaSAndroid Build Coastguard Worker     // http://skbug.com/12201 -- DDL does not yet support DMSAA.
60*c8dee2aaSAndroid Build Coastguard Worker     bool usesMSAASurface = writeView.asRenderTargetProxy()->numSamples() > 1;
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker     // This is equivalent to a GrOpFlushState::detachAppliedClip
63*c8dee2aaSAndroid Build Coastguard Worker     GrAppliedClip appliedClip = clip ? std::move(*clip) : GrAppliedClip::Disabled();
64*c8dee2aaSAndroid Build Coastguard Worker 
65*c8dee2aaSAndroid Build Coastguard Worker     this->createProgramInfo(context->priv().caps(), arena, writeView, usesMSAASurface,
66*c8dee2aaSAndroid Build Coastguard Worker                             std::move(appliedClip), dstProxyView, renderPassXferBarriers,
67*c8dee2aaSAndroid Build Coastguard Worker                             colorLoadOp);
68*c8dee2aaSAndroid Build Coastguard Worker 
69*c8dee2aaSAndroid Build Coastguard Worker     // TODO: at this point we've created both the program info and desc in the recording context's
70*c8dee2aaSAndroid Build Coastguard Worker     // arena. In the DDL case, it would be cool if 'recordProgramInfo' could return the
71*c8dee2aaSAndroid Build Coastguard Worker     // pre-existing versions if the program has already been seen. We could then return the
72*c8dee2aaSAndroid Build Coastguard Worker     // memory for the current copy to the arena.
73*c8dee2aaSAndroid Build Coastguard Worker     context->priv().recordProgramInfo(this->programInfo());
74*c8dee2aaSAndroid Build Coastguard Worker }
75*c8dee2aaSAndroid Build Coastguard Worker 
76*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
77*c8dee2aaSAndroid Build Coastguard Worker 
PatternHelper(GrMeshDrawTarget * target,GrPrimitiveType primitiveType,size_t vertexStride,sk_sp<const GrBuffer> indexBuffer,int verticesPerRepetition,int indicesPerRepetition,int repeatCount,int maxRepetitions)78*c8dee2aaSAndroid Build Coastguard Worker GrMeshDrawOp::PatternHelper::PatternHelper(GrMeshDrawTarget* target, GrPrimitiveType primitiveType,
79*c8dee2aaSAndroid Build Coastguard Worker                                            size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
80*c8dee2aaSAndroid Build Coastguard Worker                                            int verticesPerRepetition, int indicesPerRepetition,
81*c8dee2aaSAndroid Build Coastguard Worker                                            int repeatCount, int maxRepetitions) {
82*c8dee2aaSAndroid Build Coastguard Worker     this->init(target, primitiveType, vertexStride, std::move(indexBuffer), verticesPerRepetition,
83*c8dee2aaSAndroid Build Coastguard Worker                indicesPerRepetition, repeatCount, maxRepetitions);
84*c8dee2aaSAndroid Build Coastguard Worker }
85*c8dee2aaSAndroid Build Coastguard Worker 
init(GrMeshDrawTarget * target,GrPrimitiveType primitiveType,size_t vertexStride,sk_sp<const GrBuffer> indexBuffer,int verticesPerRepetition,int indicesPerRepetition,int repeatCount,int maxRepetitions)86*c8dee2aaSAndroid Build Coastguard Worker void GrMeshDrawOp::PatternHelper::init(GrMeshDrawTarget* target, GrPrimitiveType primitiveType,
87*c8dee2aaSAndroid Build Coastguard Worker                                        size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
88*c8dee2aaSAndroid Build Coastguard Worker                                        int verticesPerRepetition, int indicesPerRepetition,
89*c8dee2aaSAndroid Build Coastguard Worker                                        int repeatCount, int maxRepetitions) {
90*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(target);
91*c8dee2aaSAndroid Build Coastguard Worker     if (!indexBuffer) {
92*c8dee2aaSAndroid Build Coastguard Worker         return;
93*c8dee2aaSAndroid Build Coastguard Worker     }
94*c8dee2aaSAndroid Build Coastguard Worker 
95*c8dee2aaSAndroid Build Coastguard Worker     // Bail out when we get overflow from really large draws.
96*c8dee2aaSAndroid Build Coastguard Worker     if (repeatCount < 0 || repeatCount > SK_MaxS32 / verticesPerRepetition) {
97*c8dee2aaSAndroid Build Coastguard Worker         return;
98*c8dee2aaSAndroid Build Coastguard Worker     }
99*c8dee2aaSAndroid Build Coastguard Worker 
100*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<const GrBuffer> vertexBuffer;
101*c8dee2aaSAndroid Build Coastguard Worker     int firstVertex;
102*c8dee2aaSAndroid Build Coastguard Worker     int vertexCount = verticesPerRepetition * repeatCount;
103*c8dee2aaSAndroid Build Coastguard Worker     fVertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
104*c8dee2aaSAndroid Build Coastguard Worker     if (!fVertices) {
105*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Vertices could not be allocated for patterned rendering.");
106*c8dee2aaSAndroid Build Coastguard Worker         return;
107*c8dee2aaSAndroid Build Coastguard Worker     }
108*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(vertexBuffer);
109*c8dee2aaSAndroid Build Coastguard Worker     fMesh = target->allocMesh();
110*c8dee2aaSAndroid Build Coastguard Worker     fPrimitiveType = primitiveType;
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(maxRepetitions ==
113*c8dee2aaSAndroid Build Coastguard Worker              static_cast<int>(indexBuffer->size() / (sizeof(uint16_t) * indicesPerRepetition)));
114*c8dee2aaSAndroid Build Coastguard Worker     fMesh->setIndexedPatterned(std::move(indexBuffer), indicesPerRepetition, repeatCount,
115*c8dee2aaSAndroid Build Coastguard Worker                                maxRepetitions, std::move(vertexBuffer), verticesPerRepetition,
116*c8dee2aaSAndroid Build Coastguard Worker                                firstVertex);
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker 
recordDraw(GrMeshDrawTarget * target,const GrGeometryProcessor * gp) const119*c8dee2aaSAndroid Build Coastguard Worker void GrMeshDrawOp::PatternHelper::recordDraw(GrMeshDrawTarget* target,
120*c8dee2aaSAndroid Build Coastguard Worker                                              const GrGeometryProcessor* gp) const {
121*c8dee2aaSAndroid Build Coastguard Worker     target->recordDraw(gp, fMesh, 1, fPrimitiveType);
122*c8dee2aaSAndroid Build Coastguard Worker }
123*c8dee2aaSAndroid Build Coastguard Worker 
recordDraw(GrMeshDrawTarget * target,const GrGeometryProcessor * gp,const GrSurfaceProxy * const primProcProxies[]) const124*c8dee2aaSAndroid Build Coastguard Worker void GrMeshDrawOp::PatternHelper::recordDraw(
125*c8dee2aaSAndroid Build Coastguard Worker         GrMeshDrawTarget* target,
126*c8dee2aaSAndroid Build Coastguard Worker         const GrGeometryProcessor* gp,
127*c8dee2aaSAndroid Build Coastguard Worker         const GrSurfaceProxy* const primProcProxies[]) const {
128*c8dee2aaSAndroid Build Coastguard Worker     target->recordDraw(gp, fMesh, 1, primProcProxies, fPrimitiveType);
129*c8dee2aaSAndroid Build Coastguard Worker }
130*c8dee2aaSAndroid Build Coastguard Worker 
131*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
132*c8dee2aaSAndroid Build Coastguard Worker 
QuadHelper(GrMeshDrawTarget * target,size_t vertexStride,int quadsToDraw)133*c8dee2aaSAndroid Build Coastguard Worker GrMeshDrawOp::QuadHelper::QuadHelper(GrMeshDrawTarget* target,
134*c8dee2aaSAndroid Build Coastguard Worker                                      size_t vertexStride,
135*c8dee2aaSAndroid Build Coastguard Worker                                      int quadsToDraw) {
136*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<const GrGpuBuffer> indexBuffer = target->resourceProvider()->refNonAAQuadIndexBuffer();
137*c8dee2aaSAndroid Build Coastguard Worker     if (!indexBuffer) {
138*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("Could not get quad index buffer.");
139*c8dee2aaSAndroid Build Coastguard Worker         return;
140*c8dee2aaSAndroid Build Coastguard Worker     }
141*c8dee2aaSAndroid Build Coastguard Worker     this->init(target, GrPrimitiveType::kTriangles, vertexStride, std::move(indexBuffer),
142*c8dee2aaSAndroid Build Coastguard Worker                GrResourceProvider::NumVertsPerNonAAQuad(),
143*c8dee2aaSAndroid Build Coastguard Worker                GrResourceProvider::NumIndicesPerNonAAQuad(), quadsToDraw,
144*c8dee2aaSAndroid Build Coastguard Worker                GrResourceProvider::MaxNumNonAAQuads());
145*c8dee2aaSAndroid Build Coastguard Worker }
146