• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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