bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 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 | |
egdaniel | 0e1853c | 2016-03-17 11:35:45 -0700 | [diff] [blame] | 8 | #ifndef GrMesh_DEFINED |
| 9 | #define GrMesh_DEFINED |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 10 | |
cdalton | 397536c | 2016-03-25 12:15:03 -0700 | [diff] [blame] | 11 | #include "GrBuffer.h" |
| 12 | #include "GrGpuResourceRef.h" |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 13 | |
| 14 | /** |
Brian Salomon | 25a8809 | 2016-12-01 09:36:50 -0500 | [diff] [blame] | 15 | * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrOp to |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 16 | * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this |
| 17 | * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there |
| 18 | * already (stride, attribute mappings). |
| 19 | */ |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 20 | class GrMesh { |
| 21 | public: |
| 22 | GrMesh(GrPrimitiveType primitiveType) |
| 23 | : fPrimitiveType(primitiveType) { |
| 24 | SkDEBUGCODE(fVertexCount = 0;) |
| 25 | SkDEBUGCODE(fBaseVertex = -1;) |
| 26 | } |
| 27 | |
| 28 | void setNonIndexed(); |
| 29 | void setIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex = 0); |
| 30 | void setIndexedPatterned(const GrBuffer* indexBuffer, int indexCount, |
| 31 | int patternRepeatCount, int maxPatternRepetitionsInIndexBuffer); |
| 32 | |
| 33 | void setVertices(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex = 0); |
| 34 | |
| 35 | GrPrimitiveType primitiveType() const { return fPrimitiveType; } |
| 36 | |
| 37 | bool isIndexed() const { return SkToBool(fIndexBuffer.get()); } |
| 38 | const GrBuffer* indexBuffer() const { return fIndexBuffer.get(); } |
| 39 | int indexCount() const { SkASSERT(this->isIndexed()); return fIndexCount; } |
| 40 | int baseIndex() const { SkASSERT(this->isIndexed()); return fBaseIndex; } |
| 41 | |
| 42 | const GrBuffer* vertexBuffer() const { return fVertexBuffer.get(); } |
| 43 | int vertexCount() const { SkASSERT(fVertexCount >= 1); return fVertexCount; } |
| 44 | int baseVertex() const { SkASSERT(fBaseVertex >= 0); return fBaseVertex; } |
| 45 | |
| 46 | struct PatternBatch; |
| 47 | |
| 48 | private: |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 49 | using PendingBuffer = GrPendingIOResource<const GrBuffer, kRead_GrIOType>; |
| 50 | |
| 51 | GrPrimitiveType fPrimitiveType; |
| 52 | |
| 53 | PendingBuffer fIndexBuffer; |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 54 | int fIndexCount; |
| 55 | int fBaseIndex; |
| 56 | int fPatternRepeatCount; |
| 57 | int fMaxPatternRepetitionsInIndexBuffer; |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 58 | |
| 59 | PendingBuffer fVertexBuffer; |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 60 | int fVertexCount; |
| 61 | int fBaseVertex; |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 62 | |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 63 | class PatternIterator; |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 64 | friend GrMesh::PatternIterator begin(const GrMesh&); |
| 65 | friend GrMesh::PatternIterator end(const GrMesh&); |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 66 | }; |
| 67 | |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 68 | inline void GrMesh::setNonIndexed() { |
| 69 | fIndexBuffer.reset(nullptr); |
| 70 | } |
| 71 | |
| 72 | inline void GrMesh::setIndexed(const GrBuffer* indexBuffer, int indexCount, int baseIndex) { |
| 73 | SkASSERT(indexBuffer); |
| 74 | SkASSERT(indexCount >= 1); |
| 75 | SkASSERT(baseIndex >= 0); |
| 76 | fIndexBuffer.reset(indexBuffer); |
| 77 | fIndexCount = indexCount; |
| 78 | fBaseIndex = baseIndex; |
| 79 | fPatternRepeatCount = fMaxPatternRepetitionsInIndexBuffer = 1; |
| 80 | } |
| 81 | |
| 82 | inline void GrMesh::setIndexedPatterned(const GrBuffer* indexBuffer, int indexCount, |
| 83 | int patternRepeatCount, |
| 84 | int maxPatternRepetitionsInIndexBuffer) { |
| 85 | SkASSERT(indexBuffer); |
| 86 | SkASSERT(indexCount >= 1); |
| 87 | SkASSERT(patternRepeatCount >= 1); |
| 88 | SkASSERT(maxPatternRepetitionsInIndexBuffer >= 1); |
| 89 | fIndexBuffer.reset(indexBuffer); |
| 90 | fIndexCount = indexCount; |
| 91 | fBaseIndex = 0; |
| 92 | fPatternRepeatCount = patternRepeatCount; |
| 93 | fMaxPatternRepetitionsInIndexBuffer = maxPatternRepetitionsInIndexBuffer; |
| 94 | } |
| 95 | |
| 96 | inline void GrMesh::setVertices(const GrBuffer* vertexBuffer, int vertexCount, int baseVertex) { |
| 97 | fVertexBuffer.reset(vertexBuffer); |
| 98 | fVertexCount = vertexCount; |
| 99 | fBaseVertex = baseVertex; |
| 100 | } |
| 101 | |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 102 | struct GrMesh::PatternBatch { |
| 103 | int fBaseVertex; |
| 104 | int fRepeatCount; |
| 105 | }; |
| 106 | |
| 107 | class GrMesh::PatternIterator { |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 108 | public: |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 109 | PatternIterator(const GrMesh& mesh, int repetitionIdx) |
| 110 | : fMesh(mesh) |
| 111 | , fRepetitionIdx(repetitionIdx) { |
Chris Dalton | bca46e2 | 2017-05-15 11:03:26 -0600 | [diff] [blame] | 112 | SkASSERT(fMesh.isIndexed()); |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 113 | } |
| 114 | |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 115 | bool operator!=(const PatternIterator& that) { |
| 116 | SkASSERT(&fMesh == &that.fMesh); |
| 117 | return fRepetitionIdx != that.fRepetitionIdx; |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 118 | } |
| 119 | |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 120 | const PatternBatch operator*() { |
| 121 | PatternBatch batch; |
| 122 | batch.fBaseVertex = fMesh.fBaseVertex + fRepetitionIdx * fMesh.fVertexCount; |
| 123 | batch.fRepeatCount = SkTMin(fMesh.fPatternRepeatCount - fRepetitionIdx, |
| 124 | fMesh.fMaxPatternRepetitionsInIndexBuffer); |
| 125 | return batch; |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 126 | } |
| 127 | |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 128 | void operator++() { |
| 129 | fRepetitionIdx = SkTMin(fRepetitionIdx + fMesh.fMaxPatternRepetitionsInIndexBuffer, |
| 130 | fMesh.fPatternRepeatCount); |
| 131 | } |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 132 | |
| 133 | private: |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 134 | const GrMesh& fMesh; |
| 135 | int fRepetitionIdx; |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 136 | }; |
| 137 | |
Chris Dalton | ff92650 | 2017-05-03 14:36:54 -0400 | [diff] [blame] | 138 | inline GrMesh::PatternIterator begin(const GrMesh& mesh) { |
| 139 | return GrMesh::PatternIterator(mesh, 0); |
| 140 | } |
| 141 | |
| 142 | inline GrMesh::PatternIterator end(const GrMesh& mesh) { |
| 143 | return GrMesh::PatternIterator(mesh, mesh.fPatternRepeatCount); |
| 144 | } |
| 145 | |
bsalomon | cb8979d | 2015-05-05 09:51:38 -0700 | [diff] [blame] | 146 | #endif |