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 "GrAppliedClip.h" 12 #include "GrDrawOp.h" 13 #include "GrGeometryProcessor.h" 14 #include "GrMesh.h" 15 #include <type_traits> 16 17 class GrAtlasManager; 18 class GrCaps; 19 class GrStrikeCache; 20 class GrOpFlushState; 21 22 /** 23 * Base class for mesh-drawing GrDrawOps. 24 */ 25 class GrMeshDrawOp : public GrDrawOp { 26 public: 27 /** Abstract interface that represents a destination for a GrMeshDrawOp. */ 28 class Target; 29 30 protected: 31 GrMeshDrawOp(uint32_t classID); 32 33 /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the 34 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */ 35 class PatternHelper { 36 public: 37 PatternHelper(Target*, GrPrimitiveType, size_t vertexStride, 38 sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition, 39 int indicesPerRepetition, int repeatCount); 40 41 /** Called to issue draws to the GrMeshDrawOp::Target.*/ 42 void recordDraw(Target*, sk_sp<const GrGeometryProcessor>) const; 43 void recordDraw(Target*, sk_sp<const GrGeometryProcessor>, 44 const GrPipeline::FixedDynamicState*) const; 45 vertices()46 void* vertices() const { return fVertices; } 47 48 protected: 49 PatternHelper() = default; 50 void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer, 51 int verticesPerRepetition, int indicesPerRepetition, int repeatCount); 52 53 private: 54 void* fVertices = nullptr; 55 GrMesh* fMesh = nullptr; 56 }; 57 58 static const int kVerticesPerQuad = 4; 59 static const int kIndicesPerQuad = 6; 60 61 /** A specialization of InstanceHelper for quad rendering. */ 62 class QuadHelper : private PatternHelper { 63 public: 64 QuadHelper() = delete; 65 QuadHelper(Target* target, size_t vertexStride, int quadsToDraw); 66 67 using PatternHelper::recordDraw; 68 using PatternHelper::vertices; 69 70 private: 71 typedef PatternHelper INHERITED; 72 }; 73 74 private: 75 void onPrepare(GrOpFlushState* state) final; 76 virtual void onPrepareDraws(Target*) = 0; 77 typedef GrDrawOp INHERITED; 78 }; 79 80 class GrMeshDrawOp::Target { 81 public: ~Target()82 virtual ~Target() {} 83 84 /** Adds a draw of a mesh. */ 85 virtual void recordDraw( 86 sk_sp<const GrGeometryProcessor>, const GrMesh[], int meshCnt, 87 const GrPipeline::FixedDynamicState*, const GrPipeline::DynamicStateArrays*) = 0; 88 89 /** 90 * Helper for drawing GrMesh(es) with zero primProc textures and no dynamic state besides the 91 * scissor clip. 92 */ 93 void recordDraw(sk_sp<const GrGeometryProcessor> gp, const GrMesh meshes[], int meshCnt = 1) { 94 static constexpr int kZeroPrimProcTextures = 0; 95 auto fixedDynamicState = this->makeFixedDynamicState(kZeroPrimProcTextures); 96 this->recordDraw(std::move(gp), meshes, meshCnt, fixedDynamicState, nullptr); 97 } 98 99 /** 100 * Makes space for vertex data. The returned pointer is the location where vertex data 101 * should be written. On return the buffer that will hold the data as well as an offset into 102 * the buffer (in 'vertexSize' units) where the data will be placed. 103 */ 104 virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*, 105 int* startVertex) = 0; 106 107 /** 108 * Makes space for index data. The returned pointer is the location where index data 109 * should be written. On return the buffer that will hold the data as well as an offset into 110 * the buffer (in uint16_t units) where the data will be placed. 111 */ 112 virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0; 113 114 /** 115 * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount' 116 * vertices in the returned pointer, which may exceed 'minVertexCount'. 117 * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new 118 * buffer is allocated on behalf of this request. 119 */ 120 virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, 121 int fallbackVertexCount, sk_sp<const GrBuffer>*, 122 int* startVertex, int* actualVertexCount) = 0; 123 124 /** 125 * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount' 126 * indices in the returned pointer, which may exceed 'minIndexCount'. 127 * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new 128 * buffer is allocated on behalf of this request. 129 */ 130 virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, 131 sk_sp<const GrBuffer>*, int* startIndex, 132 int* actualIndexCount) = 0; 133 134 /** Helpers for ops which over-allocate and then return excess data to the pool. */ 135 virtual void putBackIndices(int indices) = 0; 136 virtual void putBackVertices(int vertices, size_t vertexStride) = 0; 137 allocMesh(GrPrimitiveType primitiveType)138 GrMesh* allocMesh(GrPrimitiveType primitiveType) { 139 return this->allocator()->make<GrMesh>(primitiveType); 140 } 141 allocMeshes(int n)142 GrMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrMesh>(n); } 143 144 GrPipeline::DynamicStateArrays* allocDynamicStateArrays(int numMeshes, 145 int numPrimitiveProcessorTextures, 146 bool allocScissors); 147 148 GrPipeline::FixedDynamicState* makeFixedDynamicState(int numPrimitiveProcessorTextures); 149 150 virtual GrRenderTargetProxy* proxy() const = 0; 151 152 virtual const GrAppliedClip* appliedClip() = 0; 153 virtual GrAppliedClip detachAppliedClip() = 0; 154 155 virtual const GrXferProcessor::DstProxy& dstProxy() const = 0; 156 157 virtual GrResourceProvider* resourceProvider() const = 0; contextUniqueID()158 uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); } 159 160 virtual GrStrikeCache* glyphCache() const = 0; 161 virtual GrAtlasManager* atlasManager() const = 0; 162 163 virtual const GrCaps& caps() const = 0; 164 165 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0; 166 167 private: 168 virtual SkArenaAlloc* allocator() = 0; 169 }; 170 171 #endif 172