aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2017-05-03 14:36:54 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-03 19:08:40 +0000
commitff926502069d0ddafaecc18dc08973762e4befd2 (patch)
tree5c8c4335c6a3b71006ce2e3646987930ecb2e28e
parent85591831b2fc0f67968116d73c79ee1232a59935 (diff)
Convert GrMesh to a struct
Converts GrMesh to a struct and changes the names/semantics of its fields to be more inline with their GL counterparts. Also renames the "instancing" feature to "pattern", to avoid ambiguity with hardware instancing. Bug: skia: Change-Id: Ia0999d4f9c83b5dd31f81b9bf4f36ed9abd26286 Reviewed-on: https://skia-review.googlesource.com/15157 Commit-Queue: Chris Dalton <csmartdalton@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--include/gpu/GrGpuResourceRef.h4
-rw-r--r--src/gpu/GrGpu.cpp18
-rw-r--r--src/gpu/GrGpu.h3
-rw-r--r--src/gpu/GrGpuCommandBuffer.h2
-rw-r--r--src/gpu/GrMesh.h217
-rw-r--r--src/gpu/GrResourceProvider.cpp4
-rw-r--r--src/gpu/GrResourceProvider.h12
-rw-r--r--src/gpu/gl/GrGLGpu.cpp70
-rw-r--r--src/gpu/gl/GrGLGpu.h6
-rw-r--r--src/gpu/ops/GrAAConvexPathRenderer.cpp34
-rw-r--r--src/gpu/ops/GrAAFillRectOp.cpp4
-rw-r--r--src/gpu/ops/GrAAHairLinePathRenderer.cpp37
-rw-r--r--src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp17
-rw-r--r--src/gpu/ops/GrAAStrokeRectOp.cpp6
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp11
-rw-r--r--src/gpu/ops/GrDefaultPathRenderer.cpp11
-rw-r--r--src/gpu/ops/GrDrawVerticesOp.cpp12
-rw-r--r--src/gpu/ops/GrLatticeOp.cpp2
-rw-r--r--src/gpu/ops/GrMSAAPathRenderer.cpp30
-rw-r--r--src/gpu/ops/GrMeshDrawOp.cpp24
-rw-r--r--src/gpu/ops/GrMeshDrawOp.h16
-rw-r--r--src/gpu/ops/GrNonAAFillRectOp.cpp2
-rw-r--r--src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp2
-rw-r--r--src/gpu/ops/GrNonAAStrokeRectOp.cpp5
-rw-r--r--src/gpu/ops/GrOvalOpFactory.cpp24
-rw-r--r--src/gpu/ops/GrRegionOp.cpp2
-rw-r--r--src/gpu/ops/GrShadowRRectOp.cpp9
-rw-r--r--src/gpu/ops/GrSmallPathRenderer.cpp11
-rw-r--r--src/gpu/ops/GrTessellatingPathRenderer.cpp5
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h4
-rw-r--r--src/gpu/vk/GrVkGpu.h1
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.cpp60
-rw-r--r--src/gpu/vk/GrVkGpuCommandBuffer.h5
-rw-r--r--src/gpu/vk/GrVkPipeline.h1
-rw-r--r--tests/PreFlushCallbackTest.cpp11
35 files changed, 321 insertions, 361 deletions
diff --git a/include/gpu/GrGpuResourceRef.h b/include/gpu/GrGpuResourceRef.h
index d6ef6c13a9..3a170f44d2 100644
--- a/include/gpu/GrGpuResourceRef.h
+++ b/include/gpu/GrGpuResourceRef.h
@@ -163,6 +163,10 @@ public:
this->reset(resource);
}
+ GrPendingIOResource(const GrPendingIOResource& that)
+ : GrPendingIOResource(that.get()) {
+ }
+
void reset(T* resource) {
if (resource) {
switch (IO_TYPE) {
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 5ce8274215..f8ac850bf7 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -25,24 +25,6 @@
#include "GrTexturePriv.h"
#include "SkMathPriv.h"
-GrMesh& GrMesh::operator =(const GrMesh& di) {
- fPrimitiveType = di.fPrimitiveType;
- fStartVertex = di.fStartVertex;
- fStartIndex = di.fStartIndex;
- fVertexCount = di.fVertexCount;
- fIndexCount = di.fIndexCount;
-
- fInstanceCount = di.fInstanceCount;
- fVerticesPerInstance = di.fVerticesPerInstance;
- fIndicesPerInstance = di.fIndicesPerInstance;
- fMaxInstancesPerDraw = di.fMaxInstancesPerDraw;
-
- fVertexBuffer.reset(di.vertexBuffer());
- fIndexBuffer.reset(di.indexBuffer());
-
- return *this;
-}
-
////////////////////////////////////////////////////////////////////////////////
GrGpu::GrGpu(GrContext* context)
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 68d26191bc..b7fe048b7f 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -25,8 +25,7 @@ class GrBuffer;
class GrContext;
struct GrContextOptions;
class GrGLContext;
-class GrMesh;
-class GrNonInstancedVertices;
+struct GrMesh;
class GrPath;
class GrPathRange;
class GrPathRenderer;
diff --git a/src/gpu/GrGpuCommandBuffer.h b/src/gpu/GrGpuCommandBuffer.h
index 23a300c2f4..fb54b2e3df 100644
--- a/src/gpu/GrGpuCommandBuffer.h
+++ b/src/gpu/GrGpuCommandBuffer.h
@@ -14,7 +14,7 @@
class GrOpFlushState;
class GrFixedClip;
class GrGpu;
-class GrMesh;
+struct GrMesh;
class GrPipeline;
class GrPrimitiveProcessor;
class GrRenderTarget;
diff --git a/src/gpu/GrMesh.h b/src/gpu/GrMesh.h
index 5d1ce6f3e4..e2fd2dfda3 100644
--- a/src/gpu/GrMesh.h
+++ b/src/gpu/GrMesh.h
@@ -11,169 +11,90 @@
#include "GrBuffer.h"
#include "GrGpuResourceRef.h"
-class GrNonInstancedMesh {
-public:
- GrPrimitiveType primitiveType() const { return fPrimitiveType; }
- int startVertex() const { return fStartVertex; }
- int startIndex() const { return fStartIndex; }
- int vertexCount() const { return fVertexCount; }
- int indexCount() const { return fIndexCount; }
- bool isIndexed() const { return fIndexCount > 0; }
-
- const GrBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
- const GrBuffer* indexBuffer() const { return fIndexBuffer.get(); }
-
-protected:
- GrPrimitiveType fPrimitiveType;
- int fStartVertex;
- int fStartIndex;
- int fVertexCount;
- int fIndexCount;
- GrPendingIOResource<const GrBuffer, kRead_GrIOType> fVertexBuffer;
- GrPendingIOResource<const GrBuffer, kRead_GrIOType> fIndexBuffer;
- friend class GrMesh;
-};
-
/**
* 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 GrNonInstancedMesh {
+struct GrMesh {
+ using PendingBuffer = GrPendingIOResource<const GrBuffer, kRead_GrIOType>;
+
+ GrPrimitiveType fPrimitiveType;
+
+ PendingBuffer fIndexBuffer;
+ int fIndexCount = 0;
+ int fBaseIndex = 0;
+
+ PendingBuffer fVertexBuffer;
+ int fVertexCount = 0;
+ int fBaseVertex = 0;
+
+ int fPatternRepeatCount = 1;
+ int fMaxPatternRepetitionsInIndexBuffer = 1;
+
+ struct PatternBatch;
+ class PatternIterator;
+
+ SkDEBUGCODE(void validate() const;)
+};
+
+struct GrMesh::PatternBatch {
+ int fBaseVertex;
+ int fRepeatCount;
+};
+
+class GrMesh::PatternIterator {
public:
- GrMesh() {}
- GrMesh(const GrMesh& di) { (*this) = di; }
- GrMesh& operator =(const GrMesh& di);
-
- void init(GrPrimitiveType primType, const GrBuffer* vertexBuffer, int startVertex,
- int vertexCount) {
- SkASSERT(vertexBuffer);
- SkASSERT(vertexCount);
- SkASSERT(startVertex >= 0);
- fPrimitiveType = primType;
- fVertexBuffer.reset(vertexBuffer);
- fIndexBuffer.reset(nullptr);
- fStartVertex = startVertex;
- fStartIndex = 0;
- fVertexCount = vertexCount;
- fIndexCount = 0;
- fInstanceCount = 0;
- fVerticesPerInstance = 0;
- fIndicesPerInstance = 0;
- fMaxInstancesPerDraw = 0;
+ PatternIterator(const GrMesh& mesh, int repetitionIdx)
+ : fMesh(mesh)
+ , fRepetitionIdx(repetitionIdx) {
+ SkDEBUGCODE(mesh.validate());
}
- void initIndexed(GrPrimitiveType primType,
- const GrBuffer* vertexBuffer,
- const GrBuffer* indexBuffer,
- int startVertex,
- int startIndex,
- int vertexCount,
- int indexCount) {
- SkASSERT(indexBuffer);
- SkASSERT(vertexBuffer);
- SkASSERT(indexCount);
- SkASSERT(vertexCount);
- SkASSERT(startIndex >= 0);
- SkASSERT(startVertex >= 0);
- fPrimitiveType = primType;
- fVertexBuffer.reset(vertexBuffer);
- fIndexBuffer.reset(indexBuffer);
- fStartVertex = startVertex;
- fStartIndex = startIndex;
- fVertexCount = vertexCount;
- fIndexCount = indexCount;
- fInstanceCount = 0;
- fVerticesPerInstance = 0;
- fIndicesPerInstance = 0;
- fMaxInstancesPerDraw = 0;
+ bool operator!=(const PatternIterator& that) {
+ SkASSERT(&fMesh == &that.fMesh);
+ return fRepetitionIdx != that.fRepetitionIdx;
}
-
- /** Variation of the above that may be used when the total number of instances may exceed
- the number of instances supported by the index buffer. To be used with
- nextInstances() to draw in max-sized batches.*/
- void initInstanced(GrPrimitiveType primType,
- const GrBuffer* vertexBuffer,
- const GrBuffer* indexBuffer,
- int startVertex,
- int verticesPerInstance,
- int indicesPerInstance,
- int instanceCount,
- int maxInstancesPerDraw) {
- SkASSERT(vertexBuffer);
- SkASSERT(indexBuffer);
- SkASSERT(instanceCount);
- SkASSERT(verticesPerInstance);
- SkASSERT(indicesPerInstance);
- SkASSERT(startVertex >= 0);
- fPrimitiveType = primType;
- fVertexBuffer.reset(vertexBuffer);
- fIndexBuffer.reset(indexBuffer);
- fStartVertex = startVertex;
- fStartIndex = 0;
- fVerticesPerInstance = verticesPerInstance;
- fIndicesPerInstance = indicesPerInstance;
- fInstanceCount = instanceCount;
- fVertexCount = instanceCount * fVerticesPerInstance;
- fIndexCount = instanceCount * fIndicesPerInstance;
- fMaxInstancesPerDraw = maxInstancesPerDraw;
+ const PatternBatch operator*() {
+ PatternBatch batch;
+ batch.fBaseVertex = fMesh.fBaseVertex + fRepetitionIdx * fMesh.fVertexCount;
+ batch.fRepeatCount = SkTMin(fMesh.fPatternRepeatCount - fRepetitionIdx,
+ fMesh.fMaxPatternRepetitionsInIndexBuffer);
+ return batch;
}
-
- /** These return 0 if initInstanced was not used to initialize the GrVertices. */
- int verticesPerInstance() const { return fVerticesPerInstance; }
- int indicesPerInstance() const { return fIndicesPerInstance; }
- int instanceCount() const { return fInstanceCount; }
-
- bool isInstanced() const { return fInstanceCount > 0; }
-
- class Iterator {
- public:
- const GrNonInstancedMesh* init(const GrMesh& mesh) {
- fMesh = &mesh;
- if (mesh.fInstanceCount <= mesh.fMaxInstancesPerDraw) {
- fInstancesRemaining = 0;
- // Note, this also covers the non-instanced case!
- return &mesh;
- }
- SkASSERT(mesh.isInstanced());
- fInstanceBatch.fIndexBuffer.reset(mesh.fIndexBuffer.get());
- fInstanceBatch.fVertexBuffer.reset(mesh.fVertexBuffer.get());
- fInstanceBatch.fIndexCount = mesh.fMaxInstancesPerDraw *
- mesh.fIndicesPerInstance;
- fInstanceBatch.fVertexCount = mesh.fMaxInstancesPerDraw *
- mesh.fVerticesPerInstance;
- fInstanceBatch.fPrimitiveType = mesh.fPrimitiveType;
- fInstanceBatch.fStartIndex = mesh.fStartIndex;
- fInstanceBatch.fStartVertex = mesh.fStartVertex;
- fInstancesRemaining = mesh.fInstanceCount - mesh.fMaxInstancesPerDraw;
- return &fInstanceBatch;
- }
-
- const GrNonInstancedMesh* next() {
- if (!fInstancesRemaining) {
- return nullptr;
- }
- fInstanceBatch.fStartVertex += fInstanceBatch.fVertexCount;
- int instances = SkTMin(fInstancesRemaining, fMesh->fMaxInstancesPerDraw);
- fInstanceBatch.fIndexCount = instances * fMesh->fIndicesPerInstance;
- fInstanceBatch.fVertexCount = instances * fMesh->fVerticesPerInstance;
- fInstancesRemaining -= instances;
- return &fInstanceBatch;
- }
- private:
- GrNonInstancedMesh fInstanceBatch;
- const GrMesh* fMesh;
- int fInstancesRemaining;
- };
+ void operator++() {
+ fRepetitionIdx = SkTMin(fRepetitionIdx + fMesh.fMaxPatternRepetitionsInIndexBuffer,
+ fMesh.fPatternRepeatCount);
+ }
private:
- int fInstanceCount;
- int fVerticesPerInstance;
- int fIndicesPerInstance;
- int fMaxInstancesPerDraw;
+ const GrMesh& fMesh;
+ int fRepetitionIdx;
};
+inline GrMesh::PatternIterator begin(const GrMesh& mesh) {
+ return GrMesh::PatternIterator(mesh, 0);
+}
+
+inline GrMesh::PatternIterator end(const GrMesh& mesh) {
+ return GrMesh::PatternIterator(mesh, mesh.fPatternRepeatCount);
+}
+
+#ifdef SK_DEBUG
+inline void GrMesh::validate() const {
+ SkASSERT(!fIndexBuffer || fIndexCount > 0);
+ SkASSERT(fBaseIndex >= 0);
+
+ SkASSERT(fVertexBuffer);
+ SkASSERT(fVertexCount);
+ SkASSERT(fBaseVertex >= 0);
+
+ SkASSERT(fPatternRepeatCount > 0);
+ SkASSERT(fMaxPatternRepetitionsInIndexBuffer > 0);
+}
+#endif
+
#endif
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index d7b90873ed..ad92abfb77 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -313,7 +313,7 @@ sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey
return GrSurfaceProxy::MakeWrapped(std::move(texture));
}
-const GrBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern,
+const GrBuffer* GrResourceProvider::createPatternedIndexBuffer(const uint16_t* pattern,
int patternSize,
int reps,
int vertCount,
@@ -356,7 +356,7 @@ const GrBuffer* GrResourceProvider::createQuadIndexBuffer() {
GR_STATIC_ASSERT(4 * kMaxQuads <= 65535);
static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 };
- return this->createInstancedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
+ return this->createPatternedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey);
}
GrPath* GrResourceProvider::createPath(const SkPath& path, const GrStyle& style) {
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index e22a0d8428..14db3e6eda 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -106,9 +106,9 @@ public:
static const int kMinScratchTextureSize;
/**
- * Either finds and refs, or creates an index buffer for instanced drawing with a specific
- * pattern if the index buffer is not found. If the return is non-null, the caller owns
- * a ref on the returned GrBuffer.
+ * Either finds and refs, or creates an index buffer with a repeating pattern for drawing
+ * contiguous vertices of a repeated mesh. If the return is non-null, the caller owns a ref on
+ * the returned GrBuffer.
*
* @param pattern the pattern of indices to repeat
* @param patternSize size in bytes of the pattern
@@ -118,7 +118,7 @@ public:
*
* @return The index buffer if successful, otherwise nullptr.
*/
- const GrBuffer* findOrCreateInstancedIndexBuffer(const uint16_t* pattern,
+ const GrBuffer* findOrCreatePatternedIndexBuffer(const uint16_t* pattern,
int patternSize,
int reps,
int vertCount,
@@ -126,7 +126,7 @@ public:
if (GrBuffer* buffer = this->findAndRefTByUniqueKey<GrBuffer>(key)) {
return buffer;
}
- return this->createInstancedIndexBuffer(pattern, patternSize, reps, vertCount, key);
+ return this->createPatternedIndexBuffer(pattern, patternSize, reps, vertCount, key);
}
/**
@@ -268,7 +268,7 @@ private:
return !SkToBool(fCache);
}
- const GrBuffer* createInstancedIndexBuffer(const uint16_t* pattern,
+ const GrBuffer* createPatternedIndexBuffer(const uint16_t* pattern,
int patternSize,
int reps,
int vertCount,
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 4aa19203be..8d76faee88 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1984,34 +1984,29 @@ bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
}
void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
- const GrNonInstancedMesh& mesh,
- size_t* indexOffsetInBytes) {
- const GrBuffer* vbuf = mesh.vertexBuffer();
- SkASSERT(vbuf);
- SkASSERT(!vbuf->isMapped());
-
+ const GrBuffer* indexBuffer,
+ const GrBuffer* vertexBuffer,
+ int baseVertex) {
GrGLAttribArrayState* attribState;
- if (mesh.isIndexed()) {
- SkASSERT(indexOffsetInBytes);
-
- *indexOffsetInBytes = 0;
- const GrBuffer* ibuf = mesh.indexBuffer();
- SkASSERT(ibuf);
- SkASSERT(!ibuf->isMapped());
- *indexOffsetInBytes += ibuf->baseOffset();
- attribState = fHWVertexArrayState.bindInternalVertexArray(this, ibuf);
+ if (indexBuffer) {
+ SkASSERT(indexBuffer);
+ SkASSERT(!indexBuffer->isMapped());
+ attribState = fHWVertexArrayState.bindInternalVertexArray(this, indexBuffer);
} else {
attribState = fHWVertexArrayState.bindInternalVertexArray(this);
}
+ SkASSERT(vertexBuffer);
+ SkASSERT(!vertexBuffer->isMapped());
+
int vaCount = primProc.numAttribs();
if (vaCount > 0) {
GrGLsizei stride = static_cast<GrGLsizei>(primProc.getVertexStride());
- size_t vertexOffsetInBytes = stride * mesh.startVertex();
+ size_t vertexOffsetInBytes = stride * baseVertex;
- vertexOffsetInBytes += vbuf->baseOffset();
+ vertexOffsetInBytes += vertexBuffer->baseOffset();
uint32_t usedAttribArraysMask = 0;
size_t offset = 0;
@@ -2022,7 +2017,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
GrVertexAttribType attribType = attrib.fType;
attribState->set(this,
attribIndex,
- vbuf,
+ vertexBuffer,
attribType,
stride,
reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + offset));
@@ -2646,7 +2641,7 @@ void GrGLGpu::draw(const GrPipeline& pipeline,
bool hasPoints = false;
for (int i = 0; i < meshCount; ++i) {
- if (meshes[i].primitiveType() == kPoints_GrPrimitiveType) {
+ if (meshes[i].fPrimitiveType == kPoints_GrPrimitiveType) {
hasPoints = true;
break;
}
@@ -2661,41 +2656,38 @@ void GrGLGpu::draw(const GrPipeline& pipeline,
}
const GrMesh& mesh = meshes[i];
- GrMesh::Iterator iter;
- const GrNonInstancedMesh* nonInstMesh = iter.init(mesh);
- do {
- size_t indexOffsetInBytes = 0;
- this->setupGeometry(primProc, *nonInstMesh, &indexOffsetInBytes);
- if (nonInstMesh->isIndexed()) {
- GrGLvoid* indices =
- reinterpret_cast<GrGLvoid*>(indexOffsetInBytes +
- sizeof(uint16_t) * nonInstMesh->startIndex());
- // info.startVertex() was accounted for by setupGeometry.
+ for (GrMesh::PatternBatch batch : mesh) {
+ this->setupGeometry(primProc, mesh.fIndexBuffer.get(), mesh.fVertexBuffer.get(),
+ batch.fBaseVertex);
+ if (const GrBuffer* indexBuffer = mesh.fIndexBuffer.get()) {
+ GrGLvoid* indices = reinterpret_cast<void*>(indexBuffer->baseOffset() +
+ sizeof(uint16_t) * mesh.fBaseIndex);
+ // mesh.fBaseVertex was accounted for by setupGeometry.
if (this->glCaps().drawRangeElementsSupport()) {
// We assume here that the GrMeshDrawOps that generated the mesh used the full
// 0..vertexCount()-1 range.
int start = 0;
- int end = nonInstMesh->vertexCount() - 1;
- GL_CALL(DrawRangeElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
+ int end = mesh.fVertexCount * batch.fRepeatCount - 1;
+ GL_CALL(DrawRangeElements(gPrimitiveType2GLMode[mesh.fPrimitiveType],
start, end,
- nonInstMesh->indexCount(),
+ mesh.fIndexCount * batch.fRepeatCount,
GR_GL_UNSIGNED_SHORT,
indices));
} else {
- GL_CALL(DrawElements(gPrimitiveType2GLMode[nonInstMesh->primitiveType()],
- nonInstMesh->indexCount(),
+ GL_CALL(DrawElements(gPrimitiveType2GLMode[mesh.fPrimitiveType],
+ mesh.fIndexCount * batch.fRepeatCount,
GR_GL_UNSIGNED_SHORT,
indices));
}
} else {
// Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account
- // for startVertex in the DrawElements case. So we always rely on setupGeometry to
- // have accounted for startVertex.
- GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonInstMesh->primitiveType()], 0,
- nonInstMesh->vertexCount()));
+ // for mesh.fBaseVertex in the DrawElements case. So we always rely on setupGeometry
+ // to have accounted for mesh.fBaseVertex.
+ GL_CALL(DrawArrays(gPrimitiveType2GLMode[mesh.fPrimitiveType], 0,
+ mesh.fVertexCount * batch.fRepeatCount));
}
fStats.incNumDraws();
- } while ((nonInstMesh = iter.next()));
+ }
}
#if SWAP_PER_DRAW
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 6108445966..f192c2b5ba 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -26,7 +26,6 @@
class GrGLBuffer;
class GrPipeline;
-class GrNonInstancedMesh;
class GrSwizzle;
namespace gr_instanced { class GLInstancedRendering; }
@@ -254,8 +253,9 @@ private:
// an into the index buffer. It does not account for vertices.startIndex() but rather the start
// index is relative to the returned offset.
void setupGeometry(const GrPrimitiveProcessor&,
- const GrNonInstancedMesh& mesh,
- size_t* indexOffsetInBytes);
+ const GrBuffer* indexBuffer,
+ const GrBuffer* vertexBuffer,
+ int baseVertex);
void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index efc6622c15..f9e95c7b59 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -813,10 +813,13 @@ private:
extract_verts(tess, verts, vertexStride, fColor, idxs, canTweakAlphaForCoverage);
GrMesh mesh;
- mesh.initIndexed(kTriangles_GrPrimitiveType,
- vertexBuffer, indexBuffer,
- firstVertex, firstIndex,
- tess.numPts(), tess.numIndices());
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = tess.numIndices();
+ mesh.fBaseIndex = firstIndex;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = tess.numPts();
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}
}
@@ -875,12 +878,14 @@ private:
continue;
}
- const GrBuffer* vertexBuffer;
- int firstVertex;
+ GrMesh mesh;
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ const GrBuffer* vertexBuffer;
size_t vertexStride = quadProcessor->getVertexStride();
QuadVertex* verts = reinterpret_cast<QuadVertex*>(target->makeVertexSpace(
- vertexStride, vertexCount, &vertexBuffer, &firstVertex));
+ vertexStride, vertexCount, &vertexBuffer, &mesh.fBaseVertex));
+ mesh.fVertexBuffer.reset(vertexBuffer);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
@@ -888,26 +893,23 @@ private:
}
const GrBuffer* indexBuffer;
- int firstIndex;
-
- uint16_t *idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
+ uint16_t *idxs = target->makeIndexSpace(indexCount, &indexBuffer, &mesh.fBaseIndex);
if (!idxs) {
SkDebugf("Could not allocate indices\n");
return;
}
+ mesh.fIndexBuffer.reset(indexBuffer);
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
create_vertices(segments, fanPt, &draws, verts, idxs);
- GrMesh mesh;
-
for (int j = 0; j < draws.count(); ++j) {
const Draw& draw = draws[j];
- mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer,
- firstVertex, firstIndex, draw.fVertexCnt, draw.fIndexCnt);
+ mesh.fIndexCount = draw.fIndexCnt;
+ mesh.fVertexCount = draw.fVertexCnt;
target->draw(quadProcessor.get(), this->pipeline(), mesh);
- firstVertex += draw.fVertexCnt;
- firstIndex += draw.fIndexCnt;
+ mesh.fBaseIndex += draw.fIndexCnt;
+ mesh.fBaseVertex += draw.fVertexCnt;
}
}
}
diff --git a/src/gpu/ops/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp
index 7bf62ece23..ca91e94cd5 100644
--- a/src/gpu/ops/GrAAFillRectOp.cpp
+++ b/src/gpu/ops/GrAAFillRectOp.cpp
@@ -41,7 +41,7 @@ const GrBuffer* get_index_buffer(GrResourceProvider* resourceProvider) {
// clang-format on
GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
gFillAARectIdx, kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer,
kVertsPerAAFillRect, gAAFillRectIndexBufferKey);
}
@@ -231,7 +231,7 @@ private:
size_t vertexStride = gp->getVertexStride();
sk_sp<const GrBuffer> indexBuffer(get_index_buffer(target->resourceProvider()));
- InstancedHelper helper;
+ PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerAAFillRect, kIndicesPerAAFillRect, fRectCnt);
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index 274e308465..b8ec966d48 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -64,7 +64,7 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
static const GrBuffer* ref_quads_index_buffer(GrResourceProvider* resourceProvider) {
GR_DEFINE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
kQuadIdxBufPattern, kIdxsPerQuad, kQuadsNumInIdxBuffer, kQuadNumVertices,
gQuadsIndexBufferKey);
}
@@ -98,7 +98,7 @@ GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
static const GrBuffer* ref_lines_index_buffer(GrResourceProvider* resourceProvider) {
GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
kLineSegIdxBufPattern, kIdxsPerLineSeg, kLineSegsNumInIdxBuffer, kLineSegNumVertices,
gLinesIndexBufferKey);
}
@@ -861,9 +861,14 @@ void AAHairlineOp::onPrepareDraws(Target* target) const {
}
GrMesh mesh;
- mesh.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer.get(),
- firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, lineCount,
- kLineSegsNumInIdxBuffer);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(linesIndexBuffer.get());
+ mesh.fIndexCount = kIdxsPerLineSeg;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = kLineSegNumVertices;
+ mesh.fBaseVertex = firstVertex;
+ mesh.fPatternRepeatCount = lineCount;
+ mesh.fMaxPatternRepetitionsInIndexBuffer = kLineSegsNumInIdxBuffer;
target->draw(lineGP.get(), this->pipeline(), mesh);
}
@@ -918,18 +923,28 @@ void AAHairlineOp::onPrepareDraws(Target* target) const {
if (quadCount > 0) {
GrMesh mesh;
- mesh.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer.get(),
- firstVertex, kQuadNumVertices, kIdxsPerQuad, quadCount,
- kQuadsNumInIdxBuffer);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(quadsIndexBuffer.get());
+ mesh.fIndexCount = kIdxsPerQuad;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = kQuadNumVertices;
+ mesh.fBaseVertex = firstVertex;
+ mesh.fPatternRepeatCount = quadCount;
+ mesh.fMaxPatternRepetitionsInIndexBuffer = kQuadsNumInIdxBuffer;
target->draw(quadGP.get(), this->pipeline(), mesh);
firstVertex += quadCount * kQuadNumVertices;
}
if (conicCount > 0) {
GrMesh mesh;
- mesh.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer.get(),
- firstVertex, kQuadNumVertices, kIdxsPerQuad, conicCount,
- kQuadsNumInIdxBuffer);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(quadsIndexBuffer.get());
+ mesh.fIndexCount = kIdxsPerQuad;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = kQuadNumVertices;
+ mesh.fBaseVertex = firstVertex;
+ mesh.fPatternRepeatCount = conicCount;
+ mesh.fMaxPatternRepetitionsInIndexBuffer = kQuadsNumInIdxBuffer;
target->draw(conicGP.get(), this->pipeline(), mesh);
}
}
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 2a5464c130..6c94793a35 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -189,27 +189,30 @@ private:
if (vertexCount == 0 || indexCount == 0) {
return;
}
- const GrBuffer* vertexBuffer;
+
GrMesh mesh;
- int firstVertex;
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ const GrBuffer* vertexBuffer;
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
- &firstVertex);
+ &mesh.fBaseVertex);
if (!verts) {
SkDebugf("Could not allocate vertices\n");
return;
}
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = vertexCount;
memcpy(verts, vertices, vertexCount * vertexStride);
const GrBuffer* indexBuffer;
- int firstIndex;
- uint16_t* idxs = target->makeIndexSpace(indexCount, &indexBuffer, &firstIndex);
+ uint16_t* idxs = target->makeIndexSpace(indexCount, &indexBuffer, &mesh.fBaseIndex);
if (!idxs) {
SkDebugf("Could not allocate indices\n");
return;
}
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = indexCount;
memcpy(idxs, indices, indexCount * sizeof(uint16_t));
- mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
- firstIndex, vertexCount, indexCount);
+
target->draw(gp, this->pipeline(), mesh);
}
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index 8b47f5e30f..cf16d1bea4 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -262,7 +262,7 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) const {
const sk_sp<const GrBuffer> indexBuffer(
GetIndexBuffer(target->resourceProvider(), this->miterStroke()));
- InstancedHelper helper;
+ PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
verticesPerInstance, indicesPerInstance, instanceCount);
@@ -312,7 +312,7 @@ const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvi
// clang-format on
GR_STATIC_ASSERT(SK_ARRAY_COUNT(gMiterIndices) == kMiterIndexCnt);
GR_DEFINE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey);
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
gMiterIndices, kMiterIndexCnt, kNumMiterRectsInIndexBuffer, kMiterVertexCnt,
gMiterIndexBufferKey);
} else {
@@ -377,7 +377,7 @@ const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvi
GR_STATIC_ASSERT(SK_ARRAY_COUNT(gBevelIndices) == kBevelIndexCnt);
GR_DEFINE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey);
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
gBevelIndices, kBevelIndexCnt, kNumBevelRectsInIndexBuffer, kBevelVertexCnt,
gBevelIndexBufferKey);
}
diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp
index 64710e7d8d..5271d423d8 100644
--- a/src/gpu/ops/GrAtlasTextOp.cpp
+++ b/src/gpu/ops/GrAtlasTextOp.cpp
@@ -149,9 +149,14 @@ void GrAtlasTextOp::flush(GrLegacyMeshDrawOp::Target* target, FlushInfo* flushIn
GrMesh mesh;
int maxGlyphsPerDraw =
static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
- mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer.get(),
- flushInfo->fIndexBuffer.get(), flushInfo->fVertexOffset, kVerticesPerGlyph,
- kIndicesPerGlyph, flushInfo->fGlyphsToFlush, maxGlyphsPerDraw);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(flushInfo->fIndexBuffer.get());
+ mesh.fIndexCount = kIndicesPerGlyph;
+ mesh.fVertexBuffer.reset(flushInfo->fVertexBuffer.get());
+ mesh.fVertexCount = kVerticesPerGlyph;
+ mesh.fBaseVertex = flushInfo->fVertexOffset;
+ mesh.fPatternRepeatCount = flushInfo->fGlyphsToFlush;
+ mesh.fMaxPatternRepetitionsInIndexBuffer = maxGlyphsPerDraw;
target->draw(flushInfo->fGeometryProcessor.get(), this->pipeline(), mesh);
flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
flushInfo->fGlyphsToFlush = 0;
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index 762084cba8..b2baf2eaff 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -251,12 +251,15 @@ private:
}
GrMesh mesh;
+ mesh.fPrimitiveType = primitiveType;
if (isIndexed) {
- mesh.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
- vertexOffset, indexOffset);
- } else {
- mesh.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = indexOffset;
+ mesh.fBaseIndex = firstIndex;
}
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = vertexOffset;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
// put back reserves
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index c67233c9ed..aa90db9afd 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -236,13 +236,15 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) const {
}
GrMesh mesh;
+ mesh.fPrimitiveType = this->primitiveType();
if (indices) {
- mesh.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex, firstIndex,
- fVertexCount, fIndexCount);
-
- } else {
- mesh.init(this->primitiveType(), vertexBuffer, firstVertex, fVertexCount);
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = fIndexCount;
+ mesh.fBaseIndex = firstIndex;
}
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = fVertexCount;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}
diff --git a/src/gpu/ops/GrLatticeOp.cpp b/src/gpu/ops/GrLatticeOp.cpp
index 4b8f5e3c73..0ba0164302 100644
--- a/src/gpu/ops/GrLatticeOp.cpp
+++ b/src/gpu/ops/GrLatticeOp.cpp
@@ -86,7 +86,7 @@ private:
}
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
- InstancedHelper helper;
+ PatternHelper helper;
void* vertices = helper.init(target, kTriangles_GrPrimitiveType, vertexStride,
indexBuffer.get(), kVertsPerRect, kIndicesPerRect, numRects);
if (!vertices || !indexBuffer) {
diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp
index 8e320063e3..f4d14cdf71 100644
--- a/src/gpu/ops/GrMSAAPathRenderer.cpp
+++ b/src/gpu/ops/GrMSAAPathRenderer.cpp
@@ -413,14 +413,16 @@ private:
SkASSERT(lineVertexStride == lineGP->getVertexStride());
GrMesh lineMeshes;
+ lineMeshes.fPrimitiveType = primitiveType;
if (fIsIndexed) {
- lineMeshes.initIndexed(primitiveType, lineVertexBuffer, lineIndexBuffer,
- firstLineVertex, firstLineIndex, lineVertexOffset,
- lineIndexOffset);
- } else {
- lineMeshes.init(primitiveType, lineVertexBuffer, firstLineVertex,
- lineVertexOffset);
+ lineMeshes.fIndexBuffer.reset(lineIndexBuffer);
+ lineMeshes.fIndexCount = lineIndexOffset;
+ lineMeshes.fBaseIndex = firstLineIndex;
}
+ lineMeshes.fVertexBuffer.reset(lineVertexBuffer);
+ lineMeshes.fVertexCount = lineVertexOffset;
+ lineMeshes.fBaseVertex = firstLineVertex;
+
target->draw(lineGP.get(), this->pipeline(), lineMeshes);
}
@@ -435,20 +437,20 @@ private:
&firstQuadVertex);
memcpy(quadVertices, quads.vertices, quadVertexStride * quadVertexOffset);
GrMesh quadMeshes;
+ quadMeshes.fPrimitiveType = kTriangles_GrPrimitiveType;
if (fIsIndexed) {
const GrBuffer* quadIndexBuffer;
- int firstQuadIndex;
uint16_t* quadIndices = (uint16_t*) target->makeIndexSpace(quadIndexOffset,
&quadIndexBuffer,
- &firstQuadIndex);
+ &quadMeshes.fBaseIndex);
+ quadMeshes.fIndexBuffer.reset(quadIndexBuffer);
+ quadMeshes.fIndexCount = quadIndexOffset;
memcpy(quadIndices, quads.indices, sizeof(uint16_t) * quadIndexOffset);
- quadMeshes.initIndexed(kTriangles_GrPrimitiveType, quadVertexBuffer,
- quadIndexBuffer, firstQuadVertex, firstQuadIndex,
- quadVertexOffset, quadIndexOffset);
- } else {
- quadMeshes.init(kTriangles_GrPrimitiveType, quadVertexBuffer, firstQuadVertex,
- quadVertexOffset);
}
+ quadMeshes.fVertexBuffer.reset(quadVertexBuffer);
+ quadMeshes.fVertexCount = quadVertexOffset;
+ quadMeshes.fBaseVertex = firstQuadVertex;
+
target->draw(quadGP.get(), this->pipeline(), quadMeshes);
}
}
diff --git a/src/gpu/ops/GrMeshDrawOp.cpp b/src/gpu/ops/GrMeshDrawOp.cpp
index 378524541b..92571d6c70 100644
--- a/src/gpu/ops/GrMeshDrawOp.cpp
+++ b/src/gpu/ops/GrMeshDrawOp.cpp
@@ -17,17 +17,17 @@ void GrMeshDrawOp::onPrepare(GrOpFlushState* state) {
this->onPrepareDraws(&target);
}
-void* GrMeshDrawOp::InstancedHelper::init(Target* target, GrPrimitiveType primType,
+void* GrMeshDrawOp::PatternHelper::init(Target* target, GrPrimitiveType primType,
size_t vertexStride, const GrBuffer* indexBuffer,
- int verticesPerInstance, int indicesPerInstance,
- int instancesToDraw) {
+ int verticesPerRepetition, int indicesPerRepetition,
+ int repeatCount) {
SkASSERT(target);
if (!indexBuffer) {
return nullptr;
}
const GrBuffer* vertexBuffer;
int firstVertex;
- int vertexCount = verticesPerInstance * instancesToDraw;
+ int vertexCount = verticesPerRepetition * repeatCount;
void* vertices =
target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
if (!vertices) {
@@ -36,16 +36,22 @@ void* GrMeshDrawOp::InstancedHelper::init(Target* target, GrPrimitiveType primTy
}
SkASSERT(vertexBuffer);
size_t ibSize = indexBuffer->gpuMemorySize();
- int maxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
+ int maxRepetitions = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerRepetition));
- fMesh.initInstanced(primType, vertexBuffer, indexBuffer, firstVertex, verticesPerInstance,
- indicesPerInstance, instancesToDraw, maxInstancesPerDraw);
+ fMesh.fPrimitiveType = primType;
+ fMesh.fIndexBuffer.reset(indexBuffer);
+ fMesh.fIndexCount = indicesPerRepetition;
+ fMesh.fBaseIndex = 0;
+ fMesh.fVertexBuffer.reset(vertexBuffer);
+ fMesh.fVertexCount = verticesPerRepetition;
+ fMesh.fBaseVertex = firstVertex;
+ fMesh.fPatternRepeatCount = repeatCount;
+ fMesh.fMaxPatternRepetitionsInIndexBuffer = maxRepetitions;
return vertices;
}
-void GrMeshDrawOp::InstancedHelper::recordDraw(Target* target, const GrGeometryProcessor* gp,
+void GrMeshDrawOp::PatternHelper::recordDraw(Target* target, const GrGeometryProcessor* gp,
const GrPipeline* pipeline) {
- SkASSERT(fMesh.instanceCount());
target->draw(gp, pipeline, fMesh);
}
diff --git a/src/gpu/ops/GrMeshDrawOp.h b/src/gpu/ops/GrMeshDrawOp.h
index a4b172d357..92a4c1e89d 100644
--- a/src/gpu/ops/GrMeshDrawOp.h
+++ b/src/gpu/ops/GrMeshDrawOp.h
@@ -29,15 +29,15 @@ public:
protected:
GrMeshDrawOp(uint32_t classID);
- /** Helper for rendering instances using an instanced index buffer. This class creates the space
- for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
- class InstancedHelper {
+ /** Helper for rendering repeating meshes using a patterned index buffer. This class creates the
+ space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
+ class PatternHelper {
public:
- InstancedHelper() {}
+ PatternHelper() {}
/** Returns the allocated storage for the vertices. The caller should populate the vertices
before calling recordDraws(). */
void* init(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
- int verticesPerInstance, int indicesPerInstance, int instancesToDraw);
+ int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
/** Call after init() to issue draws to the GrMeshDrawOp::Target.*/
void recordDraw(Target*, const GrGeometryProcessor*, const GrPipeline*);
@@ -50,7 +50,7 @@ protected:
static const int kIndicesPerQuad = 6;
/** A specialization of InstanceHelper for quad rendering. */
- class QuadHelper : private InstancedHelper {
+ class QuadHelper : private PatternHelper {
public:
QuadHelper() : INHERITED() {}
/** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure
@@ -58,10 +58,10 @@ protected:
calling recordDraws(). */
void* init(Target*, size_t vertexStride, int quadsToDraw);
- using InstancedHelper::recordDraw;
+ using PatternHelper::recordDraw;
private:
- typedef InstancedHelper INHERITED;
+ typedef PatternHelper INHERITED;
};
private:
diff --git a/src/gpu/ops/GrNonAAFillRectOp.cpp b/src/gpu/ops/GrNonAAFillRectOp.cpp
index 69bfe291e2..b9c20e146a 100644
--- a/src/gpu/ops/GrNonAAFillRectOp.cpp
+++ b/src/gpu/ops/GrNonAAFillRectOp.cpp
@@ -133,7 +133,7 @@ private:
int instanceCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
- InstancedHelper helper;
+ PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerInstance, kIndicesPerInstance, instanceCount);
diff --git a/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp b/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp
index fef515421f..647f69e907 100644
--- a/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp
+++ b/src/gpu/ops/GrNonAAFillRectPerspectiveOp.cpp
@@ -158,7 +158,7 @@ private:
int instanceCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
- InstancedHelper helper;
+ PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerInstance, kIndicesPerInstance, instanceCount);
diff --git a/src/gpu/ops/GrNonAAStrokeRectOp.cpp b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
index 69958c0d41..c40364dcb1 100644
--- a/src/gpu/ops/GrNonAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrNonAAStrokeRectOp.cpp
@@ -157,7 +157,10 @@ private:
}
GrMesh mesh;
- mesh.init(primType, vertexBuffer, firstVertex, vertexCount);
+ mesh.fPrimitiveType = primType;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = vertexCount;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}
diff --git a/src/gpu/ops/GrOvalOpFactory.cpp b/src/gpu/ops/GrOvalOpFactory.cpp
index 71f8bb089f..4d44b13949 100644
--- a/src/gpu/ops/GrOvalOpFactory.cpp
+++ b/src/gpu/ops/GrOvalOpFactory.cpp
@@ -1097,8 +1097,13 @@ private:
}
GrMesh mesh;
- mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
- firstIndex, fVertCount, fIndexCount);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = fIndexCount;
+ mesh.fBaseIndex = firstIndex;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = fVertCount;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}
@@ -1998,8 +2003,13 @@ private:
}
GrMesh mesh;
- mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
- firstIndex, fVertCount, fIndexCount);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = fIndexCount;
+ mesh.fBaseIndex = firstIndex;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = fVertCount;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}
@@ -2055,11 +2065,11 @@ static const GrBuffer* ref_rrect_index_buffer(RRectType type,
GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
switch (type) {
case kFill_RRectType:
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
gStandardRRectIndices, kIndicesPerFillRRect, kNumRRectsInIndexBuffer,
kVertsPerStandardRRect, gRRectOnlyIndexBufferKey);
case kStroke_RRectType:
- return resourceProvider->findOrCreateInstancedIndexBuffer(
+ return resourceProvider->findOrCreatePatternedIndexBuffer(
gStandardRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer,
kVertsPerStandardRRect, gStrokeRRectOnlyIndexBufferKey);
default:
@@ -2185,7 +2195,7 @@ private:
sk_sp<const GrBuffer> indexBuffer(ref_rrect_index_buffer(
fStroked ? kStroke_RRectType : kFill_RRectType, target->resourceProvider()));
- InstancedHelper helper;
+ PatternHelper helper;
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerStandardRRect, indicesPerInstance, instanceCount));
diff --git a/src/gpu/ops/GrRegionOp.cpp b/src/gpu/ops/GrRegionOp.cpp
index 91191f3a3f..7c90ae7ea6 100644
--- a/src/gpu/ops/GrRegionOp.cpp
+++ b/src/gpu/ops/GrRegionOp.cpp
@@ -103,7 +103,7 @@ private:
size_t vertexStride = gp->getVertexStride();
sk_sp<const GrBuffer> indexBuffer(target->resourceProvider()->refQuadIndexBuffer());
- InstancedHelper helper;
+ PatternHelper helper;
void* vertices =
helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer.get(),
kVertsPerInstance, kIndicesPerInstance, numRects);
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index 4c2c322378..7803449346 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -608,8 +608,13 @@ private:
}
GrMesh mesh;
- mesh.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
- firstIndex, fVertCount, fIndexCount);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = fIndexCount;
+ mesh.fBaseIndex = firstIndex;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = fVertCount;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 0986a09141..53de77905c 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -682,9 +682,14 @@ private:
GrMesh mesh;
int maxInstancesPerDraw =
static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
- mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer.get(),
- flushInfo->fIndexBuffer.get(), flushInfo->fVertexOffset, kVerticesPerQuad,
- kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(flushInfo->fIndexBuffer.get());
+ mesh.fIndexCount = kIndicesPerQuad;
+ mesh.fVertexBuffer.reset(flushInfo->fVertexBuffer.get());
+ mesh.fVertexCount = kVerticesPerQuad;
+ mesh.fBaseVertex = flushInfo->fVertexOffset;
+ mesh.fPatternRepeatCount = flushInfo->fInstancesToFlush;
+ mesh.fMaxPatternRepetitionsInIndexBuffer = maxInstancesPerDraw;
target->draw(flushInfo->fGeometryProcessor.get(), this->pipeline(), mesh);
flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
flushInfo->fInstancesToFlush = 0;
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index 059d8314c4..96c91247d5 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -316,7 +316,10 @@ private:
GrPrimitiveType primitiveType = TESSELLATOR_WIREFRAME ? kLines_GrPrimitiveType
: kTriangles_GrPrimitiveType;
GrMesh mesh;
- mesh.init(primitiveType, vb, firstVertex, count);
+ mesh.fPrimitiveType = primitiveType;
+ mesh.fVertexBuffer.reset(vb);
+ mesh.fVertexCount = count;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp, this->pipeline(), mesh);
}
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index f1de386b76..7c54877ec2 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -40,7 +40,7 @@ public:
BarrierType barrierType,
void* barrier) const;
- void bindVertexBuffer(GrVkGpu* gpu, GrVkVertexBuffer* vbuffer) {
+ void bindVertexBuffer(GrVkGpu* gpu, const GrVkVertexBuffer* vbuffer) {
VkBuffer vkBuffer = vbuffer->buffer();
// TODO: once vbuffer->offset() no longer always returns 0, we will need to track the offset
// to know if we can skip binding or not.
@@ -57,7 +57,7 @@ public:
}
}
- void bindIndexBuffer(GrVkGpu* gpu, GrVkIndexBuffer* ibuffer) {
+ void bindIndexBuffer(GrVkGpu* gpu, const GrVkIndexBuffer* ibuffer) {
VkBuffer vkBuffer = ibuffer->buffer();
// TODO: once ibuffer->offset() no longer always returns 0, we will need to track the offset
// to know if we can skip binding or not.
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index b06d4c3b77..ac2192327d 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -22,7 +22,6 @@
#include "vk/GrVkDefines.h"
class GrPipeline;
-class GrNonInstancedMesh;
class GrVkBufferImpl;
class GrVkPipeline;
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.cpp b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
index e6593eff9a..475480b08a 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.cpp
@@ -425,27 +425,25 @@ void GrVkGpuCommandBuffer::inlineUpload(GrOpFlushState* state, GrDrawOp::Deferre
////////////////////////////////////////////////////////////////////////////////
void GrVkGpuCommandBuffer::bindGeometry(const GrPrimitiveProcessor& primProc,
- const GrNonInstancedMesh& mesh) {
- CommandBufferInfo& cbInfo = fCommandBufferInfos[fCurrentCmdInfo];
+ const GrBuffer* indexBuffer,
+ const GrBuffer* vertexBuffer) {
+ GrVkSecondaryCommandBuffer* currCmdBuf = fCommandBufferInfos[fCurrentCmdInfo].currentCmdBuf();
// There is no need to put any memory barriers to make sure host writes have finished here.
// When a command buffer is submitted to a queue, there is an implicit memory barrier that
// occurs for all host writes. Additionally, BufferMemoryBarriers are not allowed inside of
// an active RenderPass.
- SkASSERT(!mesh.vertexBuffer()->isCPUBacked());
- GrVkVertexBuffer* vbuf;
- vbuf = (GrVkVertexBuffer*)mesh.vertexBuffer();
- SkASSERT(vbuf);
- SkASSERT(!vbuf->isMapped());
+ SkASSERT(vertexBuffer);
+ SkASSERT(!vertexBuffer->isCPUBacked());
+ SkASSERT(!vertexBuffer->isMapped());
- cbInfo.currentCmdBuf()->bindVertexBuffer(fGpu, vbuf);
+ currCmdBuf->bindVertexBuffer(fGpu, static_cast<const GrVkVertexBuffer*>(vertexBuffer));
- if (mesh.isIndexed()) {
- SkASSERT(!mesh.indexBuffer()->isCPUBacked());
- GrVkIndexBuffer* ibuf = (GrVkIndexBuffer*)mesh.indexBuffer();
- SkASSERT(ibuf);
- SkASSERT(!ibuf->isMapped());
+ if (indexBuffer) {
+ SkASSERT(indexBuffer);
+ SkASSERT(!indexBuffer->isMapped());
+ SkASSERT(!indexBuffer->isCPUBacked());
- cbInfo.currentCmdBuf()->bindIndexBuffer(fGpu, ibuf);
+ currCmdBuf->bindIndexBuffer(fGpu, static_cast<const GrVkIndexBuffer*>(indexBuffer));
}
}
@@ -539,7 +537,7 @@ void GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
set_texture_layout(dstTexture, fGpu);
}
- GrPrimitiveType primitiveType = meshes[0].primitiveType();
+ GrPrimitiveType primitiveType = meshes[0].fPrimitiveType;
sk_sp<GrVkPipelineState> pipelineState = this->prepareDrawState(pipeline,
primProc,
primitiveType);
@@ -551,16 +549,14 @@ void GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
for (int i = 0; i < meshCount; ++i) {
const GrMesh& mesh = meshes[i];
- GrMesh::Iterator iter;
- const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh);
- do {
- if (nonIdxMesh->primitiveType() != primitiveType) {
+ for (GrMesh::PatternBatch batch : mesh) {
+ if (mesh.fPrimitiveType != primitiveType) {
// Technically we don't have to call this here (since there is a safety check in
// pipelineState:setData but this will allow for quicker freeing of resources if the
// pipelineState sits in a cache for a while.
pipelineState->freeTempResources(fGpu);
SkDEBUGCODE(pipelineState = nullptr);
- primitiveType = nonIdxMesh->primitiveType();
+ primitiveType = mesh.fPrimitiveType;
pipelineState = this->prepareDrawState(pipeline,
primProc,
primitiveType);
@@ -569,26 +565,26 @@ void GrVkGpuCommandBuffer::onDraw(const GrPipeline& pipeline,
}
}
SkASSERT(pipelineState);
- this->bindGeometry(primProc, *nonIdxMesh);
+ this->bindGeometry(primProc, mesh.fIndexBuffer.get(), mesh.fVertexBuffer.get());
- if (nonIdxMesh->isIndexed()) {
+ if (mesh.fIndexBuffer) {
cbInfo.currentCmdBuf()->drawIndexed(fGpu,
- nonIdxMesh->indexCount(),
- 1,
- nonIdxMesh->startIndex(),
- nonIdxMesh->startVertex(),
- 0);
+ mesh.fIndexCount * batch.fRepeatCount,
+ 1,
+ mesh.fBaseIndex,
+ batch.fBaseVertex,
+ 0);
} else {
cbInfo.currentCmdBuf()->draw(fGpu,
- nonIdxMesh->vertexCount(),
- 1,
- nonIdxMesh->startVertex(),
- 0);
+ mesh.fVertexCount * batch.fRepeatCount,
+ 1,
+ batch.fBaseVertex,
+ 0);
}
cbInfo.fIsEmpty = false;
fGpu->stats()->incNumDraws();
- } while ((nonIdxMesh = iter.next()));
+ }
}
// Update command buffer bounds
diff --git a/src/gpu/vk/GrVkGpuCommandBuffer.h b/src/gpu/vk/GrVkGpuCommandBuffer.h
index 519edb37b6..3d4d3ee590 100644
--- a/src/gpu/vk/GrVkGpuCommandBuffer.h
+++ b/src/gpu/vk/GrVkGpuCommandBuffer.h
@@ -14,7 +14,6 @@
#include "GrTypes.h"
#include "GrVkPipelineState.h"
-class GrNonInstancedMesh;
class GrVkGpu;
class GrVkImage;
class GrVkRenderPass;
@@ -46,7 +45,9 @@ private:
void onSubmit() override;
// Bind vertex and index buffers
- void bindGeometry(const GrPrimitiveProcessor&, const GrNonInstancedMesh&);
+ void bindGeometry(const GrPrimitiveProcessor&,
+ const GrBuffer* indexBuffer,
+ const GrBuffer* vertexBuffer);
sk_sp<GrVkPipelineState> prepareDrawState(const GrPipeline&,
const GrPrimitiveProcessor&,
diff --git a/src/gpu/vk/GrVkPipeline.h b/src/gpu/vk/GrVkPipeline.h
index b4788deee9..585014e53c 100644
--- a/src/gpu/vk/GrVkPipeline.h
+++ b/src/gpu/vk/GrVkPipeline.h
@@ -14,7 +14,6 @@
#include "vk/GrVkDefines.h"
-class GrNonInstancedVertices;
class GrPipeline;
class GrPrimitiveProcessor;
class GrStencilSettings;
diff --git a/tests/PreFlushCallbackTest.cpp b/tests/PreFlushCallbackTest.cpp
index da7f93b583..fc736a4647 100644
--- a/tests/PreFlushCallbackTest.cpp
+++ b/tests/PreFlushCallbackTest.cpp
@@ -145,10 +145,13 @@ private:
}
GrMesh mesh;
- mesh.initIndexed(kTriangles_GrPrimitiveType,
- vertexBuffer, indexBuffer,
- firstVertex, firstIndex,
- 4, 6);
+ mesh.fPrimitiveType = kTriangles_GrPrimitiveType;
+ mesh.fIndexBuffer.reset(indexBuffer);
+ mesh.fIndexCount = 6;
+ mesh.fBaseIndex = firstIndex;
+ mesh.fVertexBuffer.reset(vertexBuffer);
+ mesh.fVertexCount = 4;
+ mesh.fBaseVertex = firstVertex;
target->draw(gp.get(), this->pipeline(), mesh);
}