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