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 GrAtlasManager; 19 class GrCaps; 20 class GrGlyphCache; 21 class GrOpFlushState; 22 23 /** 24 * Base class for mesh-drawing GrDrawOps. 25 */ 26 class GrMeshDrawOp : public GrDrawOp { 27 public: 28 /** Abstract interface that represents a destination for a GrMeshDrawOp. */ 29 class Target; 30 31 protected: 32 GrMeshDrawOp(uint32_t classID); 33 34 /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the 35 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */ 36 class PatternHelper { 37 public: 38 PatternHelper(GrPrimitiveType primitiveType) : fMesh(primitiveType) {} 39 /** Returns the allocated storage for the vertices. The caller should populate the vertices 40 before calling recordDraws(). */ 41 void* init(Target*, size_t vertexStride, const GrBuffer*, int verticesPerRepetition, 42 int indicesPerRepetition, int repeatCount); 43 44 /** Call after init() to issue draws to the GrMeshDrawOp::Target.*/ 45 void recordDraw(Target*, const GrGeometryProcessor*, const GrPipeline*); 46 47 private: 48 GrMesh fMesh; 49 }; 50 51 static const int kVerticesPerQuad = 4; 52 static const int kIndicesPerQuad = 6; 53 54 /** A specialization of InstanceHelper for quad rendering. */ 55 class QuadHelper : private PatternHelper { 56 public: 57 QuadHelper() : INHERITED(GrPrimitiveType::kTriangles) {} 58 /** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure 59 and on success a pointer to the vertex data that the caller should populate before 60 calling recordDraws(). */ 61 void* init(Target*, size_t vertexStride, int quadsToDraw); 62 63 using PatternHelper::recordDraw; 64 65 private: 66 typedef PatternHelper INHERITED; 67 }; 68 69 private: 70 void onPrepare(GrOpFlushState* state) final; 71 void onExecute(GrOpFlushState* state) final; 72 virtual void onPrepareDraws(Target*) = 0; 73 typedef GrDrawOp INHERITED; 74 }; 75 76 class GrMeshDrawOp::Target { 77 public: 78 virtual ~Target() {} 79 80 /** Adds a draw of a mesh. */ 81 virtual void draw(const GrGeometryProcessor*, const GrPipeline*, const GrMesh&) = 0; 82 83 /** 84 * Makes space for vertex data. The returned pointer is the location where vertex data 85 * should be written. On return the buffer that will hold the data as well as an offset into 86 * the buffer (in 'vertexSize' units) where the data will be placed. 87 */ 88 virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**, 89 int* startVertex) = 0; 90 91 /** 92 * Makes space for index data. The returned pointer is the location where index data 93 * should be written. On return the buffer that will hold the data as well as an offset into 94 * the buffer (in uint16_t units) where the data will be placed. 95 */ 96 virtual uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) = 0; 97 98 /** 99 * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount' 100 * vertices in the returned pointer, which may exceed 'minVertexCount'. 101 * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new 102 * buffer is allocated on behalf of this request. 103 */ 104 virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, 105 int fallbackVertexCount, const GrBuffer**, 106 int* startVertex, int* actualVertexCount) = 0; 107 108 /** 109 * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount' 110 * indices in the returned pointer, which may exceed 'minIndexCount'. 111 * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new 112 * buffer is allocated on behalf of this request. 113 */ 114 virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, 115 const GrBuffer**, int* startIndex, 116 int* actualIndexCount) = 0; 117 118 /** Helpers for ops which over-allocate and then return excess data to the pool. */ 119 virtual void putBackIndices(int indices) = 0; 120 virtual void putBackVertices(int vertices, size_t vertexStride) = 0; 121 122 /** 123 * Allocate space for a pipeline. The target ensures this pipeline lifetime is at least 124 * as long as any deferred execution of draws added via draw(). 125 * @tparam Args 126 * @param args 127 * @return 128 */ 129 template <typename... Args> 130 GrPipeline* allocPipeline(Args&&... args) { 131 return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...); 132 } 133 134 /** 135 * Helper that makes a pipeline targeting the op's render target that incorporates the op's 136 * GrAppliedClip. 137 */ 138 GrPipeline* makePipeline(uint32_t pipelineFlags, GrProcessorSet&& processorSet, 139 GrAppliedClip&& clip) { 140 GrPipeline::InitArgs pipelineArgs; 141 pipelineArgs.fFlags = pipelineFlags; 142 pipelineArgs.fProxy = this->proxy(); 143 pipelineArgs.fDstProxy = this->dstProxy(); 144 pipelineArgs.fCaps = &this->caps(); 145 pipelineArgs.fResourceProvider = this->resourceProvider(); 146 return this->allocPipeline(pipelineArgs, std::move(processorSet), std::move(clip)); 147 } 148 149 virtual GrRenderTargetProxy* proxy() const = 0; 150 151 virtual GrAppliedClip detachAppliedClip() = 0; 152 153 virtual const GrXferProcessor::DstProxy& dstProxy() const = 0; 154 155 virtual GrResourceProvider* resourceProvider() const = 0; 156 157 virtual GrGlyphCache* glyphCache() const = 0; 158 virtual GrAtlasManager* fullAtlasManager() const = 0; 159 160 virtual const GrCaps& caps() const = 0; 161 162 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0; 163 164 private: 165 virtual SkArenaAlloc* pipelineArena() = 0; 166 }; 167 168 #endif 169