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/GrResourceProvider.h"
13 
GrMeshDrawOp(uint32_t classID)14 GrMeshDrawOp::GrMeshDrawOp(uint32_t classID) : INHERITED(classID) {}
15 
onPrepare(GrOpFlushState * state)16 void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); }
17 
18 //////////////////////////////////////////////////////////////////////////////
19 
PatternHelper(Target * target,GrPrimitiveType primitiveType,size_t vertexStride,sk_sp<const GrBuffer> indexBuffer,int verticesPerRepetition,int indicesPerRepetition,int repeatCount)20 GrMeshDrawOp::PatternHelper::PatternHelper(Target* target, GrPrimitiveType primitiveType,
21                                            size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
22                                            int verticesPerRepetition, int indicesPerRepetition,
23                                            int repeatCount) {
24     this->init(target, primitiveType, vertexStride, std::move(indexBuffer), verticesPerRepetition,
25                indicesPerRepetition, repeatCount);
26 }
27 
init(Target * target,GrPrimitiveType primitiveType,size_t vertexStride,sk_sp<const GrBuffer> indexBuffer,int verticesPerRepetition,int indicesPerRepetition,int repeatCount)28 void GrMeshDrawOp::PatternHelper::init(Target* target, GrPrimitiveType primitiveType,
29                                        size_t vertexStride, sk_sp<const GrBuffer> indexBuffer,
30                                        int verticesPerRepetition, int indicesPerRepetition,
31                                        int repeatCount) {
32     SkASSERT(target);
33     if (!indexBuffer) {
34         return;
35     }
36     sk_sp<const GrBuffer> vertexBuffer;
37     int firstVertex;
38     int vertexCount = verticesPerRepetition * repeatCount;
39     fVertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
40     if (!fVertices) {
41         SkDebugf("Vertices could not be allocated for patterned rendering.");
42         return;
43     }
44     SkASSERT(vertexBuffer);
45     size_t ibSize = indexBuffer->size();
46     int maxRepetitions = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerRepetition));
47     fMesh = target->allocMesh(primitiveType);
48     fMesh->setIndexedPatterned(std::move(indexBuffer), indicesPerRepetition, verticesPerRepetition,
49                                repeatCount, maxRepetitions);
50     fMesh->setVertexData(std::move(vertexBuffer), firstVertex);
51 }
52 
recordDraw(Target * target,sk_sp<const GrGeometryProcessor> gp) const53 void GrMeshDrawOp::PatternHelper::recordDraw(
54         Target* target, sk_sp<const GrGeometryProcessor> gp) const {
55     target->recordDraw(std::move(gp), fMesh);
56 }
57 
recordDraw(Target * target,sk_sp<const GrGeometryProcessor> gp,const GrPipeline::FixedDynamicState * fixedDynamicState) const58 void GrMeshDrawOp::PatternHelper::recordDraw(
59         Target* target, sk_sp<const GrGeometryProcessor> gp,
60         const GrPipeline::FixedDynamicState* fixedDynamicState) const {
61     target->recordDraw(std::move(gp), fMesh, 1, fixedDynamicState, nullptr);
62 }
63 
64 //////////////////////////////////////////////////////////////////////////////
65 
QuadHelper(Target * target,size_t vertexStride,int quadsToDraw)66 GrMeshDrawOp::QuadHelper::QuadHelper(Target* target, size_t vertexStride, int quadsToDraw) {
67     sk_sp<const GrGpuBuffer> quadIndexBuffer = target->resourceProvider()->refQuadIndexBuffer();
68     if (!quadIndexBuffer) {
69         SkDebugf("Could not get quad index buffer.");
70         return;
71     }
72     this->init(target, GrPrimitiveType::kTriangles, vertexStride, std::move(quadIndexBuffer),
73                kVerticesPerQuad, kIndicesPerQuad, quadsToDraw);
74 }
75 
76 //////////////////////////////////////////////////////////////////////////////
77 
allocDynamicStateArrays(int numMeshes,int numPrimitiveProcessorTextures,bool allocScissors)78 GrPipeline::DynamicStateArrays* GrMeshDrawOp::Target::allocDynamicStateArrays(
79         int numMeshes, int numPrimitiveProcessorTextures, bool allocScissors) {
80     auto result = this->allocator()->make<GrPipeline::DynamicStateArrays>();
81     if (allocScissors) {
82         result->fScissorRects = this->allocator()->makeArray<SkIRect>(numMeshes);
83     }
84     if (numPrimitiveProcessorTextures) {
85         result->fPrimitiveProcessorTextures =
86                 this->allocator()->makeArrayDefault<GrTextureProxy*>(
87                         numPrimitiveProcessorTextures * numMeshes);
88     }
89     return result;
90 }
91 
makeFixedDynamicState(int numPrimProcTextures)92 GrPipeline::FixedDynamicState* GrMeshDrawOp::Target::makeFixedDynamicState(
93         int numPrimProcTextures) {
94     const GrAppliedClip* clip = this->appliedClip();
95     if ((clip && clip->scissorState().enabled()) || numPrimProcTextures) {
96         const SkIRect& scissor = (clip) ? clip->scissorState().rect() : SkIRect::MakeEmpty();
97         auto fixedDynamicState =
98                 this->allocator()->make<GrPipeline::FixedDynamicState>(scissor);
99         if (numPrimProcTextures) {
100             fixedDynamicState->fPrimitiveProcessorTextures =
101                     this->allocator()->makeArrayDefault<GrTextureProxy*>(numPrimProcTextures);
102         }
103         return fixedDynamicState;
104     }
105     return nullptr;
106 }
107