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