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 "src/core/SkArenaAlloc.h" 12 #include "src/gpu/GrAppliedClip.h" 13 #include "src/gpu/GrGeometryProcessor.h" 14 #include "src/gpu/GrSimpleMesh.h" 15 #include "src/gpu/ops/GrDrawOp.h" 16 #include <type_traits> 17 18 class GrAtlasManager; 19 class GrCaps; 20 class GrStrikeCache; 21 class GrOpFlushState; 22 class GrSmallPathAtlasMgr; 23 24 /** 25 * Base class for mesh-drawing GrDrawOps. 26 */ 27 class GrMeshDrawOp : public GrDrawOp { 28 public: 29 /** Abstract interface that represents a destination for a GrMeshDrawOp. */ 30 class Target; 31 CanUpgradeAAOnMerge(GrAAType aa1,GrAAType aa2)32 static bool CanUpgradeAAOnMerge(GrAAType aa1, GrAAType aa2) { 33 return (aa1 == GrAAType::kNone && aa2 == GrAAType::kCoverage) || 34 (aa1 == GrAAType::kCoverage && aa2 == GrAAType::kNone); 35 } 36 37 protected: 38 GrMeshDrawOp(uint32_t classID); 39 createProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView * writeView,GrAppliedClip && appliedClip,const GrXferProcessor::DstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers)40 void createProgramInfo(const GrCaps* caps, 41 SkArenaAlloc* arena, 42 const GrSurfaceProxyView* writeView, 43 GrAppliedClip&& appliedClip, 44 const GrXferProcessor::DstProxyView& dstProxyView, 45 GrXferBarrierFlags renderPassXferBarriers) { 46 this->onCreateProgramInfo(caps, arena, writeView, std::move(appliedClip), dstProxyView, 47 renderPassXferBarriers); 48 } 49 50 void createProgramInfo(Target* target); 51 52 /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the 53 space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */ 54 class PatternHelper { 55 public: 56 PatternHelper(Target*, GrPrimitiveType, size_t vertexStride, 57 sk_sp<const GrBuffer> indexBuffer, int verticesPerRepetition, 58 int indicesPerRepetition, int repeatCount, int maxRepetitions); 59 60 /** Called to issue draws to the GrMeshDrawOp::Target.*/ 61 void recordDraw(Target*, const GrGeometryProcessor*) const; 62 void recordDraw(Target*, const GrGeometryProcessor*, 63 const GrSurfaceProxy* const primProcProxies[]) const; 64 vertices()65 void* vertices() const { return fVertices; } mesh()66 GrSimpleMesh* mesh() { return fMesh; } 67 68 protected: 69 PatternHelper() = default; 70 void init(Target*, GrPrimitiveType, size_t vertexStride, sk_sp<const GrBuffer> indexBuffer, 71 int verticesPerRepetition, int indicesPerRepetition, int repeatCount, 72 int maxRepetitions); 73 74 private: 75 void* fVertices = nullptr; 76 GrSimpleMesh* fMesh = nullptr; 77 GrPrimitiveType fPrimitiveType; 78 }; 79 80 /** A specialization of InstanceHelper for quad rendering. 81 * It only draws non-antialiased indexed quads. 82 */ 83 class QuadHelper : private PatternHelper { 84 public: 85 QuadHelper() = delete; 86 QuadHelper(Target* target, size_t vertexStride, int quadsToDraw); 87 88 using PatternHelper::mesh; 89 using PatternHelper::recordDraw; 90 using PatternHelper::vertices; 91 92 private: 93 using INHERITED = PatternHelper; 94 }; 95 CombinedQuadCountWillOverflow(GrAAType aaType,bool willBeUpgradedToAA,int combinedQuadCount)96 static bool CombinedQuadCountWillOverflow(GrAAType aaType, 97 bool willBeUpgradedToAA, 98 int combinedQuadCount) { 99 bool willBeAA = (aaType == GrAAType::kCoverage) || willBeUpgradedToAA; 100 101 return combinedQuadCount > (willBeAA ? GrResourceProvider::MaxNumAAQuads() 102 : GrResourceProvider::MaxNumNonAAQuads()); 103 } 104 105 virtual void onPrePrepareDraws(GrRecordingContext*, 106 const GrSurfaceProxyView* writeView, 107 GrAppliedClip*, 108 const GrXferProcessor::DstProxyView&, 109 GrXferBarrierFlags renderPassXferBarriers); 110 111 private: 112 virtual GrProgramInfo* programInfo() = 0; 113 // This method is responsible for creating all the programInfos required 114 // by this op. 115 virtual void onCreateProgramInfo(const GrCaps*, 116 SkArenaAlloc*, 117 const GrSurfaceProxyView* writeView, 118 GrAppliedClip&&, 119 const GrXferProcessor::DstProxyView&, 120 GrXferBarrierFlags renderPassXferBarriers) = 0; 121 onPrePrepare(GrRecordingContext * context,const GrSurfaceProxyView * writeView,GrAppliedClip * clip,const GrXferProcessor::DstProxyView & dstProxyView,GrXferBarrierFlags renderPassXferBarriers)122 void onPrePrepare(GrRecordingContext* context, 123 const GrSurfaceProxyView* writeView, 124 GrAppliedClip* clip, 125 const GrXferProcessor::DstProxyView& dstProxyView, 126 GrXferBarrierFlags renderPassXferBarriers) final { 127 this->onPrePrepareDraws(context, writeView, clip, dstProxyView, renderPassXferBarriers); 128 } 129 void onPrepare(GrOpFlushState* state) final; 130 131 virtual void onPrepareDraws(Target*) = 0; 132 using INHERITED = GrDrawOp; 133 }; 134 135 class GrMeshDrawOp::Target { 136 public: ~Target()137 virtual ~Target() {} 138 139 /** Adds a draw of a mesh. 'primProcProxies' must have 140 * GrPrimitiveProcessor::numTextureSamplers() entries. Can be null if no samplers. 141 */ 142 virtual void recordDraw(const GrGeometryProcessor*, 143 const GrSimpleMesh[], 144 int meshCnt, 145 const GrSurfaceProxy* const primProcProxies[], 146 GrPrimitiveType) = 0; 147 148 /** 149 * Helper for drawing GrSimpleMesh(es) with zero primProc textures. 150 */ recordDraw(const GrGeometryProcessor * gp,const GrSimpleMesh meshes[],int meshCnt,GrPrimitiveType primitiveType)151 void recordDraw(const GrGeometryProcessor* gp, 152 const GrSimpleMesh meshes[], 153 int meshCnt, 154 GrPrimitiveType primitiveType) { 155 this->recordDraw(gp, meshes, meshCnt, nullptr, primitiveType); 156 } 157 158 /** 159 * Makes space for vertex data. The returned pointer is the location where vertex data 160 * should be written. On return the buffer that will hold the data as well as an offset into 161 * the buffer (in 'vertexSize' units) where the data will be placed. 162 */ 163 virtual void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*, 164 int* startVertex) = 0; 165 166 /** 167 * Makes space for index data. The returned pointer is the location where index data 168 * should be written. On return the buffer that will hold the data as well as an offset into 169 * the buffer (in uint16_t units) where the data will be placed. 170 */ 171 virtual uint16_t* makeIndexSpace(int indexCount, sk_sp<const GrBuffer>*, int* startIndex) = 0; 172 173 /** 174 * This is similar to makeVertexSpace. It allows the caller to use up to 'actualVertexCount' 175 * vertices in the returned pointer, which may exceed 'minVertexCount'. 176 * 'fallbackVertexCount' is the maximum number of vertices that should be allocated if a new 177 * buffer is allocated on behalf of this request. 178 */ 179 virtual void* makeVertexSpaceAtLeast(size_t vertexSize, int minVertexCount, 180 int fallbackVertexCount, sk_sp<const GrBuffer>*, 181 int* startVertex, int* actualVertexCount) = 0; 182 183 /** 184 * This is similar to makeIndexSpace. It allows the caller to use up to 'actualIndexCount' 185 * indices in the returned pointer, which may exceed 'minIndexCount'. 186 * 'fallbackIndexCount' is the maximum number of indices that should be allocated if a new 187 * buffer is allocated on behalf of this request. 188 */ 189 virtual uint16_t* makeIndexSpaceAtLeast(int minIndexCount, int fallbackIndexCount, 190 sk_sp<const GrBuffer>*, int* startIndex, 191 int* actualIndexCount) = 0; 192 193 /** 194 * Makes space for elements in a draw-indirect buffer. Upon success, the returned pointer is a 195 * CPU mapping where the data should be written. 196 */ 197 virtual GrDrawIndirectCommand* makeDrawIndirectSpace(int drawCount, 198 sk_sp<const GrBuffer>* buffer, 199 size_t* offsetInBytes) = 0; 200 201 /** 202 * Makes space for elements in a draw-indexed-indirect buffer. Upon success, the returned 203 * pointer is a CPU mapping where the data should be written. 204 */ 205 virtual GrDrawIndexedIndirectCommand* makeDrawIndexedIndirectSpace( 206 int drawCount, sk_sp<const GrBuffer>* buffer, size_t* offsetInBytes) = 0; 207 208 /** Helpers for ops which over-allocate and then return excess data to the pool. */ 209 virtual void putBackIndices(int indices) = 0; 210 virtual void putBackVertices(int vertices, size_t vertexStride) = 0; 211 allocMesh()212 GrSimpleMesh* allocMesh() { return this->allocator()->make<GrSimpleMesh>(); } allocMeshes(int n)213 GrSimpleMesh* allocMeshes(int n) { return this->allocator()->makeArray<GrSimpleMesh>(n); } allocPrimProcProxyPtrs(int n)214 const GrSurfaceProxy** allocPrimProcProxyPtrs(int n) { 215 return this->allocator()->makeArray<const GrSurfaceProxy*>(n); 216 } 217 218 virtual GrRenderTargetProxy* proxy() const = 0; 219 virtual const GrSurfaceProxyView* writeView() const = 0; 220 221 virtual const GrAppliedClip* appliedClip() const = 0; 222 virtual GrAppliedClip detachAppliedClip() = 0; 223 224 virtual const GrXferProcessor::DstProxyView& dstProxyView() const = 0; 225 226 virtual GrXferBarrierFlags renderPassBarriers() const = 0; 227 228 virtual GrThreadSafeCache* threadSafeCache() const = 0; 229 virtual GrResourceProvider* resourceProvider() const = 0; contextUniqueID()230 uint32_t contextUniqueID() const { return this->resourceProvider()->contextUniqueID(); } 231 232 virtual GrStrikeCache* strikeCache() const = 0; 233 virtual GrAtlasManager* atlasManager() const = 0; 234 virtual GrSmallPathAtlasMgr* smallPathAtlasManager() const = 0; 235 236 // This should be called during onPrepare of a GrOp. The caller should add any proxies to the 237 // array it will use that it did not access during a call to visitProxies. This is usually the 238 // case for atlases. 239 virtual SkTArray<GrSurfaceProxy*, true>* sampledProxyArray() = 0; 240 241 virtual const GrCaps& caps() const = 0; 242 243 virtual GrDeferredUploadTarget* deferredUploadTarget() = 0; 244 245 virtual SkArenaAlloc* allocator() = 0; 246 }; 247 248 #endif 249