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 #ifndef GrMeshDrawOp_DEFINED 9 #define GrMeshDrawOp_DEFINED 10 11 #include "GrDrawOp.h" 12 #include "GrGeometryProcessor.h" 13 #include "GrMesh.h" 14 #include "GrPendingProgramElement.h" 15 16 #include "SkTLList.h" 17 18 class GrCaps; 19 class GrOpFlushState; 20 21 /** 22 * Base class for mesh-drawing GrDrawOps. 23 */ 24 class GrMeshDrawOp : public GrDrawOp { 25 public: 26 class Target; 27 28 protected: 29 GrMeshDrawOp(uint32_t classID); 30 31 /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the 32 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */ 33 class PatternHelper { 34 public: PatternHelper(GrPrimitiveType primitiveType)35 PatternHelper(GrPrimitiveType primitiveType) : fMesh(primitiveType) {} 36 /** Returns the allocated storage for the vertices. The caller should populate the vertices 37 before calling recordDraws(). */ 38 void* init(Target*, size_t vertexStride, const GrBuffer*, int verticesPerRepetition, 39 int indicesPerRepetition, int repeatCount); 40 41 /** Call after init() to issue draws to the GrMeshDrawOp::Target.*/ 42 void recordDraw(Target*, const GrGeometryProcessor*, const GrPipeline*); 43 44 private: 45 GrMesh fMesh; 46 }; 47 48 static const int kVerticesPerQuad = 4; 49 static const int kIndicesPerQuad = 6; 50 51 /** A specialization of InstanceHelper for quad rendering. */ 52 class QuadHelper : private PatternHelper { 53 public: QuadHelper()54 QuadHelper() : INHERITED(GrPrimitiveType::kTriangles) {} 55 /** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure 56 and on success a pointer to the vertex data that the caller should populate before 57 calling recordDraws(). */ 58 void* init(Target*, size_t vertexStride, int quadsToDraw); 59 60 using PatternHelper::recordDraw; 61 62 private: 63 typedef PatternHelper INHERITED; 64 }; 65 66 private: 67 void onPrepare(GrOpFlushState* state) final; 68 void onExecute(GrOpFlushState* state) final; 69 70 virtual void onPrepareDraws(Target*) const = 0; 71 72 // A set of contiguous draws that share a draw token and primitive processor. The draws all use 73 // the op's pipeline. The meshes for the draw are stored in the fMeshes array and each 74 // Queued draw uses fMeshCnt meshes from the fMeshes array. The reason for coallescing meshes 75 // that share a primitive processor into a QueuedDraw is that it allows the Gpu object to setup 76 // the shared state once and then issue draws for each mesh. 77 struct QueuedDraw { 78 int fMeshCnt = 0; 79 GrPendingProgramElement<const GrGeometryProcessor> fGeometryProcessor; 80 const GrPipeline* fPipeline; 81 }; 82 83 // All draws in all the GrMeshDrawOps have implicit tokens based on the order they are enqueued 84 // globally across all ops. This is the offset of the first entry in fQueuedDraws. 85 // fQueuedDraws[i]'s token is fBaseDrawToken + i. 86 GrDrawOpUploadToken fBaseDrawToken; 87 SkSTArray<4, GrMesh> fMeshes; 88 SkSTArray<4, QueuedDraw, true> fQueuedDraws; 89 90 typedef GrDrawOp INHERITED; 91 }; 92 93 #endif 94