123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef GrMesh_DEFINED
- #define GrMesh_DEFINED
- #include "src/gpu/GrBuffer.h"
- #include "src/gpu/GrGpuBuffer.h"
- #include "src/gpu/GrPendingIOResource.h"
- class GrPrimitiveProcessor;
- /**
- * Used to communicate index and vertex buffers, counts, and offsets for a draw from GrOp to
- * GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
- * and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
- * already (stride, attribute mappings).
- */
- class GrMesh {
- public:
- GrMesh(GrPrimitiveType primitiveType = GrPrimitiveType::kTriangles)
- : fPrimitiveType(primitiveType), fBaseVertex(0) {
- SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;)
- }
- void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
- GrPrimitiveType primitiveType() const { return fPrimitiveType; }
- bool isIndexed() const { return SkToBool(fIndexBuffer.get()); }
- GrPrimitiveRestart primitiveRestart() const {
- return GrPrimitiveRestart(fFlags & Flags::kUsePrimitiveRestart);
- }
- bool isInstanced() const { return fFlags & Flags::kIsInstanced; }
- bool hasInstanceData() const { return SkToBool(fInstanceBuffer.get()); }
- bool hasVertexData() const { return SkToBool(fVertexBuffer.get()); }
- void setNonIndexedNonInstanced(int vertexCount);
- void setIndexed(sk_sp<const GrBuffer> indexBuffer, int indexCount, int baseIndex,
- uint16_t minIndexValue, uint16_t maxIndexValue, GrPrimitiveRestart);
- void setIndexedPatterned(sk_sp<const GrBuffer> indexBuffer, int indexCount, int vertexCount,
- int patternRepeatCount, int maxPatternRepetitionsInIndexBuffer);
- void setInstanced(sk_sp<const GrBuffer> instanceBuffer, int instanceCount, int baseInstance,
- int vertexCount);
- void setIndexedInstanced(sk_sp<const GrBuffer> indexBuffer, int indexCount,
- sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
- int baseInstance, GrPrimitiveRestart);
- void setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVertex = 0);
- class SendToGpuImpl {
- public:
- virtual void sendMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer, int vertexCount,
- int baseVertex) = 0;
- virtual void sendIndexedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer,
- int indexCount, int baseIndex, uint16_t minIndexValue,
- uint16_t maxIndexValue, const GrBuffer* vertexBuffer,
- int baseVertex, GrPrimitiveRestart) = 0;
- virtual void sendInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* vertexBuffer,
- int vertexCount, int baseVertex,
- const GrBuffer* instanceBuffer, int instanceCount,
- int baseInstance) = 0;
- virtual void sendIndexedInstancedMeshToGpu(GrPrimitiveType, const GrBuffer* indexBuffer,
- int indexCount, int baseIndex,
- const GrBuffer* vertexBuffer, int baseVertex,
- const GrBuffer* instanceBuffer,
- int instanceCount, int baseInstance,
- GrPrimitiveRestart) = 0;
- virtual ~SendToGpuImpl() {}
- };
- void sendToGpu(SendToGpuImpl*) const;
- private:
- enum class Flags {
- kNone = 0,
- kUsePrimitiveRestart = 1 << 0,
- kIsInstanced = 1 << 1,
- };
- GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Flags);
- GR_STATIC_ASSERT(Flags(GrPrimitiveRestart::kNo) == Flags::kNone);
- GR_STATIC_ASSERT(Flags(GrPrimitiveRestart::kYes) == Flags::kUsePrimitiveRestart);
- GrPrimitiveType fPrimitiveType;
- sk_sp<const GrBuffer> fIndexBuffer;
- sk_sp<const GrBuffer> fInstanceBuffer;
- sk_sp<const GrBuffer> fVertexBuffer;
- int fBaseVertex;
- Flags fFlags;
- union {
- struct { // When fIndexBuffer == nullptr and isInstanced() == false.
- int fVertexCount;
- } fNonIndexNonInstanceData;
- struct { // When fIndexBuffer != nullptr and isInstanced() == false.
- struct {
- int fIndexCount;
- int fPatternRepeatCount;
- } fIndexData;
- union {
- struct { // When fPatternRepeatCount == 0.
- int fBaseIndex;
- uint16_t fMinIndexValue;
- uint16_t fMaxIndexValue;
- } fNonPatternIndexData;
- struct { // When fPatternRepeatCount != 0.
- int fVertexCount;
- int fMaxPatternRepetitionsInIndexBuffer;
- } fPatternData;
- };
- };
- struct { // When isInstanced() != false.
- struct {
- int fInstanceCount;
- int fBaseInstance;
- } fInstanceData;
- union { // When fIndexBuffer == nullptr.
- struct {
- int fVertexCount;
- } fInstanceNonIndexData;
- struct { // When fIndexBuffer != nullptr.
- int fIndexCount;
- } fInstanceIndexData;
- };
- };
- };
- };
- GR_MAKE_BITFIELD_CLASS_OPS(GrMesh::Flags);
- inline void GrMesh::setNonIndexedNonInstanced(int vertexCount) {
- fIndexBuffer.reset();
- fInstanceBuffer.reset();
- fNonIndexNonInstanceData.fVertexCount = vertexCount;
- fFlags = Flags::kNone;
- }
- inline void GrMesh::setIndexed(sk_sp<const GrBuffer> indexBuffer, int indexCount, int baseIndex,
- uint16_t minIndexValue, uint16_t maxIndexValue,
- GrPrimitiveRestart primitiveRestart) {
- SkASSERT(indexBuffer);
- SkASSERT(indexCount >= 1);
- SkASSERT(baseIndex >= 0);
- SkASSERT(maxIndexValue >= minIndexValue);
- fIndexBuffer = std::move(indexBuffer);
- fInstanceBuffer.reset();
- fIndexData.fIndexCount = indexCount;
- fIndexData.fPatternRepeatCount = 0;
- fNonPatternIndexData.fBaseIndex = baseIndex;
- fNonPatternIndexData.fMinIndexValue = minIndexValue;
- fNonPatternIndexData.fMaxIndexValue = maxIndexValue;
- fFlags = Flags(primitiveRestart);
- }
- inline void GrMesh::setIndexedPatterned(sk_sp<const GrBuffer> indexBuffer, int indexCount,
- int vertexCount, int patternRepeatCount,
- int maxPatternRepetitionsInIndexBuffer) {
- SkASSERT(indexBuffer);
- SkASSERT(indexCount >= 1);
- SkASSERT(vertexCount >= 1);
- SkASSERT(patternRepeatCount >= 1);
- SkASSERT(maxPatternRepetitionsInIndexBuffer >= 1);
- fIndexBuffer = std::move(indexBuffer);
- fInstanceBuffer.reset();
- fIndexData.fIndexCount = indexCount;
- fIndexData.fPatternRepeatCount = patternRepeatCount;
- fPatternData.fVertexCount = vertexCount;
- fPatternData.fMaxPatternRepetitionsInIndexBuffer = maxPatternRepetitionsInIndexBuffer;
- fFlags = Flags::kNone;
- }
- inline void GrMesh::setInstanced(sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
- int baseInstance, int vertexCount) {
- SkASSERT(instanceCount >= 1);
- SkASSERT(baseInstance >= 0);
- fIndexBuffer.reset();
- fInstanceBuffer = std::move(instanceBuffer);
- fInstanceData.fInstanceCount = instanceCount;
- fInstanceData.fBaseInstance = baseInstance;
- fInstanceNonIndexData.fVertexCount = vertexCount;
- fFlags = Flags::kIsInstanced;
- }
- inline void GrMesh::setIndexedInstanced(sk_sp<const GrBuffer> indexBuffer, int indexCount,
- sk_sp<const GrBuffer> instanceBuffer, int instanceCount,
- int baseInstance, GrPrimitiveRestart primitiveRestart) {
- SkASSERT(indexBuffer);
- SkASSERT(indexCount >= 1);
- SkASSERT(instanceCount >= 1);
- SkASSERT(baseInstance >= 0);
- fIndexBuffer = std::move(indexBuffer);
- fInstanceBuffer = std::move(instanceBuffer);
- fInstanceData.fInstanceCount = instanceCount;
- fInstanceData.fBaseInstance = baseInstance;
- fInstanceIndexData.fIndexCount = indexCount;
- fFlags = Flags::kIsInstanced | Flags(primitiveRestart);
- }
- inline void GrMesh::setVertexData(sk_sp<const GrBuffer> vertexBuffer, int baseVertex) {
- SkASSERT(baseVertex >= 0);
- fVertexBuffer = std::move(vertexBuffer);
- fBaseVertex = baseVertex;
- }
- inline void GrMesh::sendToGpu(SendToGpuImpl* impl) const {
- if (this->isInstanced()) {
- if (!this->isIndexed()) {
- impl->sendInstancedMeshToGpu(fPrimitiveType, fVertexBuffer.get(),
- fInstanceNonIndexData.fVertexCount, fBaseVertex,
- fInstanceBuffer.get(), fInstanceData.fInstanceCount,
- fInstanceData.fBaseInstance);
- } else {
- impl->sendIndexedInstancedMeshToGpu(
- fPrimitiveType, fIndexBuffer.get(), fInstanceIndexData.fIndexCount, 0,
- fVertexBuffer.get(), fBaseVertex, fInstanceBuffer.get(),
- fInstanceData.fInstanceCount, fInstanceData.fBaseInstance,
- this->primitiveRestart());
- }
- return;
- }
- if (!this->isIndexed()) {
- SkASSERT(fNonIndexNonInstanceData.fVertexCount > 0);
- impl->sendMeshToGpu(fPrimitiveType, fVertexBuffer.get(),
- fNonIndexNonInstanceData.fVertexCount, fBaseVertex);
- return;
- }
- if (0 == fIndexData.fPatternRepeatCount) {
- impl->sendIndexedMeshToGpu(
- fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount,
- fNonPatternIndexData.fBaseIndex, fNonPatternIndexData.fMinIndexValue,
- fNonPatternIndexData.fMaxIndexValue, fVertexBuffer.get(), fBaseVertex,
- this->primitiveRestart());
- return;
- }
- SkASSERT(fIndexData.fPatternRepeatCount > 0);
- int baseRepetition = 0;
- do {
- int repeatCount = SkTMin(fPatternData.fMaxPatternRepetitionsInIndexBuffer,
- fIndexData.fPatternRepeatCount - baseRepetition);
- // A patterned index buffer must contain indices in the range [0..vertexCount].
- int minIndexValue = 0;
- int maxIndexValue = fPatternData.fVertexCount * repeatCount - 1;
- SkASSERT(!(fFlags & Flags::kUsePrimitiveRestart));
- impl->sendIndexedMeshToGpu(
- fPrimitiveType, fIndexBuffer.get(), fIndexData.fIndexCount * repeatCount, 0,
- minIndexValue, maxIndexValue, fVertexBuffer.get(),
- fBaseVertex + fPatternData.fVertexCount * baseRepetition, GrPrimitiveRestart::kNo);
- baseRepetition += repeatCount;
- } while (baseRepetition < fIndexData.fPatternRepeatCount);
- }
- #endif
|