GrMesh.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  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. #ifndef GrMesh_DEFINED
  8. #define GrMesh_DEFINED
  9. #include "src/gpu/GrBuffer.h"
  10. #include "src/gpu/GrGpuBuffer.h"
  11. #include "src/gpu/GrPendingIOResource.h"
  12. class GrPrimitiveProcessor;
  13. /**
  14. * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrOp to
  15. * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
  16. * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
  17. * already (stride, attribute mappings).
  18. */
  19. class GrMesh {
  20. public:
  21. GrMesh(GrPrimitiveType primitiveType = GrPrimitiveType::kTriangles)
  22. : fPrimitiveType(primitiveType), fBaseVertex(0) {
  23. SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;)
  24. }
  25. void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
  26. GrPrimitiveType primitiveType() const { return fPrimitiveType; }
  27. bool isIndexed() const { return SkToBool(fIndexBuffer.get()); }
  28. GrPrimitiveRestart primitiveRestart() const {
  29. return GrPrimitiveRestart(fFlags & Flags::kUsePrimitiveRestart);
  30. }
  31. bool isInstanced() const { return fFlags & Flags::kIsInstanced; }
  32. bool hasInstanceData() const { return SkToBool(fInstanceBuffer.get()); }
  33. bool hasVertexData() const { return SkToBool(fVertexBuffer.get()); }
  34. void setNonIndexedNonInstanced(int vertexCount);
  35. void setIndexed(sk_sp<const GrBuffer> indexBuffer, int indexCount, int baseIndex,
  36. uint16_t minIndexValue, uint16_t maxIndexValue, GrPrimitiveRestart);
  37. void setIndexedPatterned(sk_sp<const GrBuffer> indexBuffer, int indexCount, int vertexCount,
  38. int patternRepeatCount, int maxPatternRepetitionsInIndexBuffer);
  39. void setInstanced(sk_sp<const GrBuffer> instanceBuffer, int instanceCount, int baseInstance,
  40. int vertexCount);
  41. void setIndexedInstanced(sk_sp<const GrBuffer> indexBuffer, int indexCount,
  42. sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
  43. int baseInstance, GrPrimitiveRestart);
  44. void setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVertex = 0);
  45. class SendToGpuImpl {
  46. public:
  47. virtual void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
  48. int baseVertex) = 0;
  49. virtual void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer,
  50. int indexCount, int baseIndex, uint16_t minIndexValue,
  51. uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
  52. int baseVertex, GrPrimitiveRestart) = 0;
  53. virtual void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer,
  54. int vertexCount, int baseVertex,
  55. const GrBuffer* instanceBuffer, int instanceCount,
  56. int baseInstance) = 0;
  57. virtual void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer,
  58. int indexCount, int baseIndex,
  59. const GrBuffer* vertexBuffer, int baseVertex,
  60. const GrBuffer* instanceBuffer,
  61. int instanceCount, int baseInstance,
  62. GrPrimitiveRestart) = 0;
  63. virtual ~SendToGpuImpl() {}
  64. };
  65. void sendToGpu(SendToGpuImpl*) const;
  66. private:
  67. enum class Flags {
  68. kNone = 0,
  69. kUsePrimitiveRestart = 1 << 0,
  70. kIsInstanced = 1 << 1,
  71. };
  72. GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
  73. GR_STATIC_ASSERT(Flags(GrPrimitiveRestart::kNo) == Flags::kNone);
  74. GR_STATIC_ASSERT(Flags(GrPrimitiveRestart::kYes) == Flags::kUsePrimitiveRestart);
  75. GrPrimitiveType fPrimitiveType;
  76. sk_sp<const GrBuffer> fIndexBuffer;
  77. sk_sp<const GrBuffer> fInstanceBuffer;
  78. sk_sp<const GrBuffer> fVertexBuffer;
  79. int fBaseVertex;
  80. Flags fFlags;
  81. union {
  82. struct { // When fIndexBuffer == nullptr and isInstanced() == false.
  83. int fVertexCount;
  84. } fNonIndexNonInstanceData;
  85. struct { // When fIndexBuffer != nullptr and isInstanced() == false.
  86. struct {
  87. int fIndexCount;
  88. int fPatternRepeatCount;
  89. } fIndexData;
  90. union {
  91. struct { // When fPatternRepeatCount == 0.
  92. int fBaseIndex;
  93. uint16_t fMinIndexValue;
  94. uint16_t fMaxIndexValue;
  95. } fNonPatternIndexData;
  96. struct { // When fPatternRepeatCount != 0.
  97. int fVertexCount;
  98. int fMaxPatternRepetitionsInIndexBuffer;
  99. } fPatternData;
  100. };
  101. };
  102. struct { // When isInstanced() != false.
  103. struct {
  104. int fInstanceCount;
  105. int fBaseInstance;
  106. } fInstanceData;
  107. union { // When fIndexBuffer == nullptr.
  108. struct {
  109. int fVertexCount;
  110. } fInstanceNonIndexData;
  111. struct { // When fIndexBuffer != nullptr.
  112. int fIndexCount;
  113. } fInstanceIndexData;
  114. };
  115. };
  116. };
  117. };
  118. GR_MAKE_BITFIELD_CLASS_OPS(GrMesh::Flags);
  119. inline void GrMesh::setNonIndexedNonInstanced(int vertexCount) {
  120. fIndexBuffer.reset();
  121. fInstanceBuffer.reset();
  122. fNonIndexNonInstanceData.fVertexCount = vertexCount;
  123. fFlags = Flags::kNone;
  124. }
  125. inline void GrMesh::setIndexed(sk_sp<const GrBuffer> indexBuffer, int indexCount, int baseIndex,
  126. uint16_t minIndexValue, uint16_t maxIndexValue,
  127. GrPrimitiveRestart primitiveRestart) {
  128. SkASSERT(indexBuffer);
  129. SkASSERT(indexCount >= 1);
  130. SkASSERT(baseIndex >= 0);
  131. SkASSERT(maxIndexValue >= minIndexValue);
  132. fIndexBuffer = std::move(indexBuffer);
  133. fInstanceBuffer.reset();
  134. fIndexData.fIndexCount = indexCount;
  135. fIndexData.fPatternRepeatCount = 0;
  136. fNonPatternIndexData.fBaseIndex = baseIndex;
  137. fNonPatternIndexData.fMinIndexValue = minIndexValue;
  138. fNonPatternIndexData.fMaxIndexValue = maxIndexValue;
  139. fFlags = Flags(primitiveRestart);
  140. }
  141. inline void GrMesh::setIndexedPatterned(sk_sp<const GrBuffer> indexBuffer, int indexCount,
  142. int vertexCount, int patternRepeatCount,
  143. int maxPatternRepetitionsInIndexBuffer) {
  144. SkASSERT(indexBuffer);
  145. SkASSERT(indexCount >= 1);
  146. SkASSERT(vertexCount >= 1);
  147. SkASSERT(patternRepeatCount >= 1);
  148. SkASSERT(maxPatternRepetitionsInIndexBuffer >= 1);
  149. fIndexBuffer = std::move(indexBuffer);
  150. fInstanceBuffer.reset();
  151. fIndexData.fIndexCount = indexCount;
  152. fIndexData.fPatternRepeatCount = patternRepeatCount;
  153. fPatternData.fVertexCount = vertexCount;
  154. fPatternData.fMaxPatternRepetitionsInIndexBuffer = maxPatternRepetitionsInIndexBuffer;
  155. fFlags = Flags::kNone;
  156. }
  157. inline void GrMesh::setInstanced(sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
  158. int baseInstance, int vertexCount) {
  159. SkASSERT(instanceCount >= 1);
  160. SkASSERT(baseInstance >= 0);
  161. fIndexBuffer.reset();
  162. fInstanceBuffer = std::move(instanceBuffer);
  163. fInstanceData.fInstanceCount = instanceCount;
  164. fInstanceData.fBaseInstance = baseInstance;
  165. fInstanceNonIndexData.fVertexCount = vertexCount;
  166. fFlags = Flags::kIsInstanced;
  167. }
  168. inline void GrMesh::setIndexedInstanced(sk_sp<const GrBuffer> indexBuffer, int indexCount,
  169. sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
  170. int baseInstance, GrPrimitiveRestart primitiveRestart) {
  171. SkASSERT(indexBuffer);
  172. SkASSERT(indexCount >= 1);
  173. SkASSERT(instanceCount >= 1);
  174. SkASSERT(baseInstance >= 0);
  175. fIndexBuffer = std::move(indexBuffer);
  176. fInstanceBuffer = std::move(instanceBuffer);
  177. fInstanceData.fInstanceCount = instanceCount;
  178. fInstanceData.fBaseInstance = baseInstance;
  179. fInstanceIndexData.fIndexCount = indexCount;
  180. fFlags = Flags::kIsInstanced | Flags(primitiveRestart);
  181. }
  182. inline void GrMesh::setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVertex) {
  183. SkASSERT(baseVertex >= 0);
  184. fVertexBuffer = std::move(vertexBuffer);
  185. fBaseVertex = baseVertex;
  186. }
  187. inline void GrMesh::sendToGpu(SendToGpuImpl* impl) const {
  188. if (this->isInstanced()) {
  189. if (!this->isIndexed()) {
  190. impl->sendInstancedMeshToGpu(fPrimitiveType, fVertexBuffer.get(),
  191. fInstanceNonIndexData.fVertexCount, fBaseVertex,
  192. fInstanceBuffer.get(), fInstanceData.fInstanceCount,
  193. fInstanceData.fBaseInstance);
  194. } else {
  195. impl->sendIndexedInstancedMeshToGpu(
  196. fPrimitiveType, fIndexBuffer.get(), fInstanceIndexData.fIndexCount, 0,
  197. fVertexBuffer.get(), fBaseVertex, fInstanceBuffer.get(),
  198. fInstanceData.fInstanceCount, fInstanceData.fBaseInstance,
  199. this->primitiveRestart());
  200. }
  201. return;
  202. }
  203. if (!this->isIndexed()) {
  204. SkASSERT(fNonIndexNonInstanceData.fVertexCount > 0);
  205. impl->sendMeshToGpu(fPrimitiveType, fVertexBuffer.get(),
  206. fNonIndexNonInstanceData.fVertexCount, fBaseVertex);
  207. return;
  208. }
  209. if (0 == fIndexData.fPatternRepeatCount) {
  210. impl->sendIndexedMeshToGpu(
  211. fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount,
  212. fNonPatternIndexData.fBaseIndex, fNonPatternIndexData.fMinIndexValue,
  213. fNonPatternIndexData.fMaxIndexValue, fVertexBuffer.get(), fBaseVertex,
  214. this->primitiveRestart());
  215. return;
  216. }
  217. SkASSERT(fIndexData.fPatternRepeatCount > 0);
  218. int baseRepetition = 0;
  219. do {
  220. int repeatCount = SkTMin(fPatternData.fMaxPatternRepetitionsInIndexBuffer,
  221. fIndexData.fPatternRepeatCount - baseRepetition);
  222. // A patterned index buffer must contain indices in the range [0..vertexCount].
  223. int minIndexValue = 0;
  224. int maxIndexValue = fPatternData.fVertexCount * repeatCount - 1;
  225. SkASSERT(!(fFlags & Flags::kUsePrimitiveRestart));
  226. impl->sendIndexedMeshToGpu(
  227. fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount * repeatCount, 0,
  228. minIndexValue, maxIndexValue, fVertexBuffer.get(),
  229. fBaseVertex + fPatternData.fVertexCount * baseRepetition, GrPrimitiveRestart::kNo);
  230. baseRepetition += repeatCount;
  231. } while (baseRepetition < fIndexData.fPatternRepeatCount);
  232. }
  233. #endif