aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-05-04 11:27:45 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-04 11:27:45 -0700
commitf28381c6866cad92af8ebe5b9d2db074613b1963 (patch)
treee47de7c53417db3d49025d2f3204d9e1cf0923b1
parentb327c3a84a90f966afa00c705f2e7f511321ef6e (diff)
Start on simplifying generateGeometry() overrides
-rw-r--r--gm/beziereffects.cpp66
-rw-r--r--gm/convexpolyeffect.cpp34
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp13
-rwxr-xr-xsrc/gpu/GrAADistanceFieldPathRenderer.cpp122
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp66
-rw-r--r--src/gpu/GrAARectRenderer.cpp92
-rw-r--r--src/gpu/GrAtlasTextContext.cpp71
-rw-r--r--src/gpu/GrBatch.cpp42
-rw-r--r--src/gpu/GrBatch.h44
-rwxr-xr-xsrc/gpu/GrContext.cpp27
-rw-r--r--src/gpu/GrDefaultPathRenderer.cpp16
-rw-r--r--src/gpu/GrDrawTarget.cpp12
-rw-r--r--src/gpu/GrDrawTarget.h146
-rw-r--r--src/gpu/GrInOrderDrawBuffer.cpp68
-rw-r--r--src/gpu/GrOvalRenderer.cpp272
-rw-r--r--src/gpu/GrTessellatingPathRenderer.cpp7
-rw-r--r--src/gpu/effects/GrDashingEffect.cpp69
17 files changed, 433 insertions, 734 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 6568422898..d543c149c7 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -16,7 +16,6 @@
#include "GrBufferAllocPool.h"
#include "GrContext.h"
#include "GrPathUtils.h"
-#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTestBatch.h"
#include "SkColorPriv.h"
@@ -67,25 +66,14 @@ private:
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
+ QuadHelper helper;
size_t vertexStride = this->geometryProcessor()->getVertexStride();
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- kVertsPerCubic,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ SkASSERT(vertexStride == sizeof(Vertex));
+ Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
+ if (!verts) {
return;
}
- SkASSERT(vertexStride == sizeof(Vertex));
- Vertex* verts = reinterpret_cast<Vertex*>(vertices);
-
verts[0].fPosition.setRectFan(fGeometry.fBounds.fLeft, fGeometry.fBounds.fTop,
fGeometry.fBounds.fRight, fGeometry.fBounds.fBottom,
sizeof(Vertex));
@@ -94,16 +82,7 @@ private:
verts[v].fKLM[1] = eval_line(verts[v].fPosition, fKlmEqs + 3, fSign);
verts[v].fKLM[2] = eval_line(verts[v].fPosition, fKlmEqs + 6, 1.f);
}
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(kVertsPerCubic);
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(kIndicesPerCubic);
- drawInfo.setIndexBuffer(indexBuffer);
- batchTarget->draw(drawInfo);
+ helper.issueDraws(batchTarget);
}
Geometry fGeometry;
@@ -475,42 +454,19 @@ private:
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
+ QuadHelper helper;
size_t vertexStride = this->geometryProcessor()->getVertexStride();
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- kVertsPerCubic,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ SkASSERT(vertexStride == sizeof(Vertex));
+ GrDrawTarget::DrawInfo drawInfo;
+ Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
+ if (!verts) {
return;
}
-
- SkASSERT(vertexStride == sizeof(Vertex));
- Vertex* verts = reinterpret_cast<Vertex*>(vertices);
-
verts[0].fPosition.setRectFan(fGeometry.fBounds.fLeft, fGeometry.fBounds.fTop,
fGeometry.fBounds.fRight, fGeometry.fBounds.fBottom,
sizeof(Vertex));
-
fDevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
-
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(kVertsPerCubic);
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(kIndicesPerCubic);
- drawInfo.setIndexBuffer(indexBuffer);
- batchTarget->draw(drawInfo);
+ helper.issueDraws(batchTarget);
}
Geometry fGeometry;
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 60b73c571d..cd9b3d10e5 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -17,7 +17,6 @@
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h"
-#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTestBatch.h"
#include "SkColorPriv.h"
@@ -53,47 +52,24 @@ private:
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
size_t vertexStride = this->geometryProcessor()->getVertexStride();
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- kVertsPerCubic,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ SkASSERT(vertexStride == sizeof(SkPoint));
+ QuadHelper helper;
+ SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(batchTarget, vertexStride, 1));
+ if (!verts) {
return;
}
- SkASSERT(vertexStride == sizeof(SkPoint));
- SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
-
// Make sure any artifacts around the exterior of path are visible by using overly
// conservative bounding geometry.
fGeometry.fBounds.outset(5.f, 5.f);
fGeometry.fBounds.toQuad(verts);
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangleFan_GrPrimitiveType);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(kVertsPerCubic);
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(kIndicesPerCubic);
- drawInfo.setIndexBuffer(indexBuffer);
- batchTarget->draw(drawInfo);
+ helper.issueDraws(batchTarget);
}
Geometry fGeometry;
- static const int kVertsPerCubic = 4;
- static const int kIndicesPerCubic = 6;
-
typedef GrTestBatch INHERITED;
};
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 3a548aa60a..f20306404a 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -824,19 +824,14 @@ public:
create_vertices(segments, fanPt, &draws, verts, idxs);
GrDrawTarget::DrawInfo info;
- info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(indexBuffer);
- info.setPrimitiveType(kTriangles_GrPrimitiveType);
- info.setStartIndex(firstIndex);
- int vOffset = 0;
for (int i = 0; i < draws.count(); ++i) {
const Draw& draw = draws[i];
- info.setStartVertex(vOffset + firstVertex);
- info.setVertexCount(draw.fVertexCnt);
- info.setIndexCount(draw.fIndexCnt);
+ info.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
+ firstIndex, draw.fVertexCnt, draw.fIndexCnt);
batchTarget->draw(info);
- vOffset += draw.fVertexCnt;
+ firstVertex += draw.fVertexCnt;
+ firstIndex += draw.fIndexCnt;
}
}
}
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index ca8c52fa34..312b731fd7 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -13,9 +13,9 @@
#include "GrBufferAllocPool.h"
#include "GrContext.h"
#include "GrPipelineBuilder.h"
+#include "GrResourceProvider.h"
#include "GrSurfacePriv.h"
#include "GrSWMaskHelper.h"
-#include "GrResourceProvider.h"
#include "GrTexturePriv.h"
#include "GrVertexBuffer.h"
#include "effects/GrDistanceFieldGeoProc.h"
@@ -169,6 +169,13 @@ public:
fBatch.fCoverageIgnored = init.fCoverageIgnored;
}
+ struct FlushInfo {
+ SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
+ SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
+ int fVertexOffset;
+ int fInstancesToFlush;
+ };
+
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
int instanceCount = fGeoData.count();
@@ -195,43 +202,25 @@ public:
this->initDraw(batchTarget, dfProcessor, pipeline);
- static const int kVertsPerQuad = 4;
- static const int kIndicesPerQuad = 6;
-
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
+ FlushInfo flushInfo;
// allocate vertices
size_t vertexStride = dfProcessor->getVertexStride();
SkASSERT(vertexStride == 2 * sizeof(SkPoint));
- const GrVertexBuffer* vertexBuffer;
- int vertexCount = kVertsPerQuad * instanceCount;
- int firstVertex;
+ const GrVertexBuffer* vertexBuffer;
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
+ kVerticesPerQuad * instanceCount,
&vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
+ &flushInfo.fVertexOffset);
+ flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
+ flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer());
+ if (!vertices || !flushInfo.fIndexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
- // We may have to flush while uploading path data to the atlas, so we set up the draw here
- int maxInstancesPerDraw = indexBuffer->maxQuads();
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerQuad);
- drawInfo.setIndicesPerInstance(kIndicesPerQuad);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int instancesToFlush = 0;
+ flushInfo.fInstancesToFlush = 0;
for (int i = 0; i < instanceCount; i++) {
Geometry& args = fGeoData[i];
@@ -265,9 +254,7 @@ public:
if (!this->addPathToAtlas(batchTarget,
dfProcessor,
pipeline,
- &drawInfo,
- &instancesToFlush,
- maxInstancesPerDraw,
+ &flushInfo,
atlas,
args.fPathData,
args.fPath,
@@ -284,21 +271,21 @@ public:
// Now set vertices
intptr_t offset = reinterpret_cast<intptr_t>(vertices);
- offset += i * kVertsPerQuad * vertexStride;
+ offset += i * kVerticesPerQuad * vertexStride;
SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
- this->drawPath(batchTarget,
- atlas,
- pipeline,
- dfProcessor,
- positions,
- vertexStride,
- this->viewMatrix(),
- args.fPath,
- args.fPathData);
- instancesToFlush++;
+ this->writePathVertices(batchTarget,
+ atlas,
+ pipeline,
+ dfProcessor,
+ positions,
+ vertexStride,
+ this->viewMatrix(),
+ args.fPath,
+ args.fPathData);
+ flushInfo.fInstancesToFlush++;
}
- this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
+ this->flush(batchTarget, &flushInfo);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -325,9 +312,7 @@ private:
bool addPathToAtlas(GrBatchTarget* batchTarget,
const GrGeometryProcessor* dfProcessor,
const GrPipeline* pipeline,
- GrDrawTarget::DrawInfo* drawInfo,
- int* instancesToFlush,
- int maxInstancesPerDraw,
+ FlushInfo* flushInfo,
GrBatchAtlas* atlas,
PathData* pathData,
const SkPath& path,
@@ -429,9 +414,8 @@ private:
bool success = atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(),
&atlasLocation);
if (!success) {
- this->flush(batchTarget, drawInfo, *instancesToFlush, maxInstancesPerDraw);
+ this->flush(batchTarget, flushInfo);
this->initDraw(batchTarget, dfProcessor, pipeline);
- *instancesToFlush = 0;
SkDEBUGCODE(success =) atlas->addToAtlas(&id, batchTarget, width, height,
dfStorage.get(), &atlasLocation);
@@ -467,15 +451,15 @@ private:
return true;
}
- void drawPath(GrBatchTarget* target,
- GrBatchAtlas* atlas,
- const GrPipeline* pipeline,
- const GrGeometryProcessor* gp,
- SkPoint* positions,
- size_t vertexStride,
- const SkMatrix& viewMatrix,
- const SkPath& path,
- const PathData* pathData) {
+ void writePathVertices(GrBatchTarget* target,
+ GrBatchAtlas* atlas,
+ const GrPipeline* pipeline,
+ const GrGeometryProcessor* gp,
+ SkPoint* positions,
+ size_t vertexStride,
+ const SkMatrix& viewMatrix,
+ const SkPath& path,
+ const PathData* pathData) {
GrTexture* texture = atlas->getTexture();
SkScalar dx = pathData->fBounds.fLeft;
@@ -522,20 +506,18 @@ private:
dfProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init);
}
- void flush(GrBatchTarget* batchTarget,
- GrDrawTarget::DrawInfo* drawInfo,
- int instanceCount,
- int maxInstancesPerDraw) {
- while (instanceCount) {
- drawInfo->setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo->setVertexCount(drawInfo->instanceCount() * drawInfo->verticesPerInstance());
- drawInfo->setIndexCount(drawInfo->instanceCount() * drawInfo->indicesPerInstance());
-
- batchTarget->draw(*drawInfo);
-
- drawInfo->setStartVertex(drawInfo->startVertex() + drawInfo->vertexCount());
- instanceCount -= drawInfo->instanceCount();
- }
+ void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
+ GrDrawTarget::DrawInfo drawInfo;
+ int instancesToFlush = flushInfo->fInstancesToFlush;
+ int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads();
+ drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
+ flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad,
+ kIndicesPerQuad, &instancesToFlush, maxInstancesPerDraw);
+ do {
+ batchTarget->draw(drawInfo);
+ } while (drawInfo.nextInstances(&instancesToFlush, maxInstancesPerDraw));
+ flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
+ flushInfo->fInstancesToFlush = 0;
}
GrColor color() const { return fBatch.fColor; }
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index f046af871f..ba6dcecd43 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -888,23 +888,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
}
{
+ int linesLeft = lineCount;
GrDrawTarget::DrawInfo info;
- info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(linesIndexBuffer);
- info.setPrimitiveType(kTriangles_GrPrimitiveType);
- info.setStartIndex(0);
-
- int lines = 0;
- while (lines < lineCount) {
- int n = SkTMin(lineCount - lines, kLineSegsNumInIdxBuffer);
-
- info.setStartVertex(kLineSegNumVertices*lines + firstVertex);
- info.setVertexCount(kLineSegNumVertices*n);
- info.setIndexCount(kIdxsPerLineSeg*n);
+ info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer,
+ firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft,
+ kLineSegsNumInIdxBuffer);
+ do {
batchTarget->draw(info);
-
- lines += n;
- }
+ } while (info.nextInstances(&linesLeft, kLineSegsNumInIdxBuffer));
}
}
@@ -953,23 +944,15 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
{
- GrDrawTarget::DrawInfo info;
- info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(quadsIndexBuffer);
- info.setPrimitiveType(kTriangles_GrPrimitiveType);
- info.setStartIndex(0);
-
- int quads = 0;
- while (quads < quadCount) {
- int n = SkTMin(quadCount - quads, kQuadsNumInIdxBuffer);
-
- info.setStartVertex(kQuadNumVertices*quads + firstVertex);
- info.setVertexCount(kQuadNumVertices*n);
- info.setIndexCount(kIdxsPerQuad*n);
+ int quadsLeft = quadCount;
+ GrDrawTarget::DrawInfo info;
+ info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
+ firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft,
+ kQuadsNumInIdxBuffer);
+ do {
batchTarget->draw(info);
-
- quads += n;
- }
+ } while (info.nextInstances(&quadsLeft, kQuadsNumInIdxBuffer));
+ firstVertex += quadCount * kQuadNumVertices;
}
}
@@ -985,23 +968,14 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
{
+ int conicsLeft = conicCount;
GrDrawTarget::DrawInfo info;
- info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(quadsIndexBuffer);
- info.setPrimitiveType(kTriangles_GrPrimitiveType);
- info.setStartIndex(0);
-
- int conics = 0;
- while (conics < conicCount) {
- int n = SkTMin(conicCount - conics, kQuadsNumInIdxBuffer);
-
- info.setStartVertex(kQuadNumVertices*(quadCount + conics) + firstVertex);
- info.setVertexCount(kQuadNumVertices*n);
- info.setIndexCount(kIdxsPerQuad*n);
+ info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
+ firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft,
+ kQuadsNumInIdxBuffer);
+ do {
batchTarget->draw(info);
-
- conics += n;
- }
+ } while (info.nextInstances(&conicsLeft, kQuadsNumInIdxBuffer));
}
}
}
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index d1c377aa53..267d970c62 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -112,22 +112,17 @@ public:
init.fUsesLocalCoords = this->usesLocalCoords();
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
- batchTarget->resourceProvider()));
-
size_t vertexStride = gp->getVertexStride();
SkASSERT(canTweakAlphaForCoverage ?
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
int instanceCount = fGeoData.count();
- int vertexCount = kVertsPerAAFillRect * instanceCount;
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(this->getIndexBuffer(
+ batchTarget->resourceProvider()));
+ InstancedHelper helper;
+ void* vertices = helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerAAFillRect,
+ kIndicesPerAAFillRect, instanceCount);
if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
@@ -145,28 +140,7 @@ public:
canTweakAlphaForCoverage);
}
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerAAFillRect);
- drawInfo.setIndicesPerInstance(kIndicesPerAAFillRect);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = kNumAAFillRectsInIndexBuffer;
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
- }
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -485,9 +459,6 @@ public:
batchTarget->initDraw(gp, pipeline);
- const SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke()));
-
// TODO this is hacky, but the only way we have to initialize the GP is to use the
// GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch
// everywhere we can remove this nastiness
@@ -505,28 +476,24 @@ public:
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
int innerVertexNum = 4;
int outerVertexNum = this->miterStroke() ? 4 : 8;
- int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
-
+ int verticesPerInstance = (outerVertexNum + innerVertexNum) * 2;
+ int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
int instanceCount = fGeoData.count();
- int vertexCount = totalVertexNum * instanceCount;
-
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
+ const SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke()));
+ InstancedHelper helper;
+ void* vertices = helper.init(batchTarget, vertexStride, indexBuffer, verticesPerInstance,
+ indicesPerInstance, instanceCount);
if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate vertices\n");
- return;
- }
+ SkDebugf("Could not allocate vertices\n");
+ return;
+ }
for (int i = 0; i < instanceCount; i++) {
const Geometry& args = fGeoData[i];
this->generateAAStrokeRectGeometry(vertices,
- i * totalVertexNum * vertexStride,
+ i * verticesPerInstance * vertexStride,
vertexStride,
outerVertexNum,
innerVertexNum,
@@ -537,30 +504,7 @@ public:
args.fMiterStroke,
canTweakAlphaForCoverage);
}
- int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(totalVertexNum);
- drawInfo.setIndicesPerInstance(indicesPerInstance);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = this->miterStroke() ? kNumMiterRectsInIndexBuffer :
- kNumBevelRectsInIndexBuffer;
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
- }
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 33e4f7ed86..c8688b0adc 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -1474,6 +1474,13 @@ public:
fBatch.fCoverageIgnored = init.fCoverageIgnored;
}
+ struct FlushInfo {
+ SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
+ SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
+ int fGlyphsToFlush;
+ int fVertexOffset;
+ };
+
void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
// if we have RGB, then we won't have any SkShaders so no need to use a localmatrix.
// TODO actually only invert if we don't have RGBA
@@ -1506,6 +1513,8 @@ public:
localMatrix));
}
+ FlushInfo flushInfo;
+ flushInfo.fGlyphsToFlush = 0;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == (fUseDistanceFields ?
get_vertex_stride_df(fMaskFormat, fUseLCDText) :
@@ -1515,35 +1524,21 @@ public:
int glyphCount = this->numGlyphs();
int instanceCount = fInstanceCount;
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
const GrVertexBuffer* vertexBuffer;
- int firstVertex;
+
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
glyphCount * kVerticesPerGlyph,
&vertexBuffer,
- &firstVertex);
- if (!vertices || !indexBuffer) {
+ &flushInfo.fVertexOffset);
+ flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
+ flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer());
+ if (!vertices || !flushInfo.fVertexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);
- // setup drawinfo
- int maxInstancesPerDraw = indexBuffer->maxQuads();
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVerticesPerGlyph);
- drawInfo.setIndicesPerInstance(kIndicesPerGlyph);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
// We cache some values to avoid going to the glyphcache for the same fontScaler twice
// in a row
const SkDescriptor* desc = NULL;
@@ -1551,7 +1546,6 @@ public:
GrFontScaler* scaler = NULL;
SkTypeface* typeface = NULL;
- int instancesToFlush = 0;
for (int i = 0; i < instanceCount; i++) {
Geometry& args = fGeoData[i];
Blob* blob = args.fBlob;
@@ -1635,10 +1629,8 @@ public:
if (!fFontCache->hasGlyph(glyph) &&
!strike->addGlyphToAtlas(batchTarget, glyph, scaler)) {
- this->flush(batchTarget, &drawInfo, instancesToFlush,
- maxInstancesPerDraw);
+ this->flush(batchTarget, &flushInfo);
this->initDraw(batchTarget, gp, pipeline);
- instancesToFlush = 0;
brokenRun = glyphIdx > 0;
SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget,
@@ -1674,7 +1666,7 @@ public:
SkScalar transY = args.fTransY;
this->regeneratePositions(vertex, vertexStride, transX, transY);
}
- instancesToFlush++;
+ flushInfo.fGlyphsToFlush++;
}
// We my have changed the color so update it here
@@ -1687,7 +1679,7 @@ public:
fFontCache->atlasGeneration(fMaskFormat);
}
} else {
- instancesToFlush += glyphCount;
+ flushInfo.fGlyphsToFlush += glyphCount;
// set use tokens for all of the glyphs in our subrun. This is only valid if we
// have a valid atlas generation
@@ -1706,7 +1698,7 @@ public:
if (cache) {
SkGlyphCache::AttachCache(cache);
}
- this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
+ this->flush(batchTarget, &flushInfo);
}
// The minimum number of Geometry we will try to allocate.
@@ -1833,20 +1825,19 @@ private:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
}
- void flush(GrBatchTarget* batchTarget,
- GrDrawTarget::DrawInfo* drawInfo,
- int instanceCount,
- int maxInstancesPerDraw) {
- while (instanceCount) {
- drawInfo->setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo->setVertexCount(drawInfo->instanceCount() * drawInfo->verticesPerInstance());
- drawInfo->setIndexCount(drawInfo->instanceCount() * drawInfo->indicesPerInstance());
-
- batchTarget->draw(*drawInfo);
-
- drawInfo->setStartVertex(drawInfo->startVertex() + drawInfo->vertexCount());
- instanceCount -= drawInfo->instanceCount();
- }
+ void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
+ GrDrawTarget::DrawInfo drawInfo;
+ int glyphsToFlush = flushInfo->fGlyphsToFlush;
+ int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
+ drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
+ flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
+ kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlush,
+ maxGlyphsPerDraw);
+ do {
+ batchTarget->draw(drawInfo);
+ } while (drawInfo.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
+ flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
+ flushInfo->fGlyphsToFlush = 0;
}
GrColor color() const { return fBatch.fColor; }
diff --git a/src/gpu/GrBatch.cpp b/src/gpu/GrBatch.cpp
index ce30499ff8..1ef6c9797c 100644
--- a/src/gpu/GrBatch.cpp
+++ b/src/gpu/GrBatch.cpp
@@ -6,6 +6,8 @@
*/
#include "GrBatch.h"
+#include "GrBatchTarget.h"
+#include "GrResourceProvider.h"
#include "GrMemoryPool.h"
#include "SkSpinlock.h"
@@ -43,3 +45,43 @@ void* GrBatch::operator new(size_t size) {
void GrBatch::operator delete(void* target) {
return MemoryPoolAccessor().pool()->release(target);
}
+
+void* GrBatch::InstancedHelper::init(GrBatchTarget* batchTarget, size_t vertexStride,
+ const GrIndexBuffer* indexBuffer, int verticesPerInstance,
+ int indicesPerInstance, int instancesToDraw) {
+ SkASSERT(!fInstancesRemaining);
+ SkASSERT(batchTarget);
+ if (!indexBuffer) {
+ return NULL;
+ }
+ const GrVertexBuffer* vertexBuffer;
+ int firstVertex;
+ int vertexCount = verticesPerInstance * instancesToDraw;
+ void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, vertexCount, &vertexBuffer,
+ &firstVertex);
+ if (!vertices) {
+ SkDebugf("Vertices could not be allocated for instanced rendering.");
+ return NULL;
+ }
+ SkASSERT(vertexBuffer);
+ fInstancesRemaining = instancesToDraw;
+
+ fDrawInfo.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer,
+ firstVertex, verticesPerInstance, indicesPerInstance, &fInstancesRemaining,
+ indexBuffer->maxQuads());
+ size_t ibSize = fDrawInfo.indexBuffer()->gpuMemorySize();
+ fMaxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
+ SkASSERT(fMaxInstancesPerDraw > 0);
+ return vertices;
+}
+
+void* GrBatch::QuadHelper::init(GrBatchTarget* batchTarget, size_t vertexStride, int quadsToDraw) {
+ SkAutoTUnref<const GrIndexBuffer> quadIndexBuffer(
+ batchTarget->resourceProvider()->refQuadIndexBuffer());
+ if (!quadIndexBuffer) {
+ SkDebugf("Could not get quad index buffer.");
+ return NULL;
+ }
+ return this->INHERITED::init(batchTarget, vertexStride, quadIndexBuffer, kVerticesPerQuad,
+ kIndicesPerQuad, quadsToDraw);
+}
diff --git a/src/gpu/GrBatch.h b/src/gpu/GrBatch.h
index 7b5c888a70..38316cebad 100644
--- a/src/gpu/GrBatch.h
+++ b/src/gpu/GrBatch.h
@@ -11,12 +11,12 @@
#include <new>
// TODO remove this header when we move entirely to batch
#include "GrDrawTarget.h"
+#include "GrBatchTarget.h"
#include "GrGeometryProcessor.h"
#include "SkRefCnt.h"
#include "SkThread.h"
#include "SkTypes.h"
-class GrBatchTarget;
class GrGpu;
class GrIndexBufferAllocPool;
class GrPipeline;
@@ -113,6 +113,48 @@ protected:
return fBounds.joinPossiblyEmptyRect(otherBounds);
}
+ /** Helper for rendering instances using an instanced index index buffer. This class creates the
+ space for the vertices and flushes the draws to the batch target.*/
+ class InstancedHelper {
+ public:
+ InstancedHelper() : fInstancesRemaining(0) {}
+ /** Returns the allocated storage for the vertices. The caller should populate the before
+ vertices before calling issueDraws(). */
+ void* init(GrBatchTarget* batchTarget, size_t vertexStride,
+ const GrIndexBuffer* indexBuffer, int verticesPerInstance,
+ int indicesPerInstance, int instancesToDraw);
+
+ /** Call after init() to issue draws to the batch target.*/
+ void issueDraws(GrBatchTarget* batchTarget) {
+ SkASSERT(fDrawInfo.instanceCount());
+ do {
+ batchTarget->draw(fDrawInfo);
+ } while (fDrawInfo.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
+ }
+ private:
+ int fInstancesRemaining;
+ int fMaxInstancesPerDraw;
+ GrDrawTarget::DrawInfo fDrawInfo;
+ };
+
+ static const int kVerticesPerQuad = 4;
+ static const int kIndicesPerQuad = 6;
+
+ /** A specialization of InstanceHelper for quad rendering. */
+ class QuadHelper : private InstancedHelper {
+ public:
+ QuadHelper() : INHERITED() {}
+ /** Finds the cached quad index buffer and reserves vertex space. Returns NULL on failure
+ and on sucess a pointer to the vertex data that the caller should populate before
+ calling issueDraws(). */
+ void* init(GrBatchTarget* batchTarget, size_t vertexStride, int quadsToDraw);
+
+ using InstancedHelper::issueDraws;
+
+ private:
+ typedef InstancedHelper INHERITED;
+ };
+
SkRect fBounds;
private:
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 819774a076..a9c6ce0b5a 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -502,15 +502,7 @@ public:
}
GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(primType);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(vertexCount);
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(0);
- drawInfo.setInstanceCount(0);
- drawInfo.setVerticesPerInstance(0);
- drawInfo.setIndicesPerInstance(0);
+ drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount);
batchTarget->draw(drawInfo);
}
@@ -829,8 +821,8 @@ public:
return;
}
- const GrIndexBuffer* indexBuffer;
- int firstIndex;
+ const GrIndexBuffer* indexBuffer = NULL;
+ int firstIndex = 0;
void* indices = NULL;
if (this->hasIndices()) {
@@ -870,17 +862,12 @@ public:
}
GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(this->primitiveType());
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(this->vertexCount());
if (this->hasIndices()) {
- drawInfo.setIndexBuffer(indexBuffer);
- drawInfo.setStartIndex(firstIndex);
- drawInfo.setIndexCount(this->indexCount());
+ drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
+ firstIndex, this->vertexCount(), this->indexCount());
+
} else {
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(0);
+ drawInfo.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
}
batchTarget->draw(drawInfo);
}
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 93d64abab2..a86d117f59 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -329,8 +329,8 @@ public:
return;
}
- const GrIndexBuffer* indexBuffer;
- int firstIndex;
+ const GrIndexBuffer* indexBuffer = NULL;
+ int firstIndex = 0;
void* indices = NULL;
if (isIndexed) {
@@ -370,17 +370,11 @@ public:
}
GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(primitiveType);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(vertexOffset);
if (isIndexed) {
- drawInfo.setIndexBuffer(indexBuffer);
- drawInfo.setStartIndex(firstIndex);
- drawInfo.setIndexCount(indexOffset);
+ drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
+ vertexOffset, indexOffset);
} else {
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(0);
+ drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
}
batchTarget->draw(drawInfo);
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 850309797c..7ae2c99825 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -37,16 +37,8 @@ GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
fVerticesPerInstance = di.fVerticesPerInstance;
fIndicesPerInstance = di.fIndicesPerInstance;
- if (di.fDevBounds) {
- SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
- fDevBoundsStorage = di.fDevBoundsStorage;
- fDevBounds = &fDevBoundsStorage;
- } else {
- fDevBounds = NULL;
- }
-
- this->setVertexBuffer(di.vertexBuffer());
- this->setIndexBuffer(di.indexBuffer());
+ fVertexBuffer.reset(di.vertexBuffer());
+ fIndexBuffer.reset(di.indexBuffer());
return *this;
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 0dca57a9db..c584181396 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -225,65 +225,132 @@ public:
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
/**
- * Used to communicate draws to GPUs / subclasses
+ * Used to communicate draw index vertex offsets and counts toto GPUs / subclasses
*/
class DrawInfo {
public:
- DrawInfo() { fDevBounds = NULL; }
+ DrawInfo() {}
DrawInfo(const DrawInfo& di) { (*this) = di; }
DrawInfo& operator =(const DrawInfo& di);
+ void init(GrPrimitiveType primType, const GrVertexBuffer* vertexBuffer, int startVertex,
+ int vertexCount) {
+ SkASSERT(vertexBuffer);
+ SkASSERT(vertexCount);
+ SkASSERT(startVertex >= 0);
+ fPrimitiveType = primType;
+ fVertexBuffer.reset(SkRef(vertexBuffer));
+ fIndexBuffer.reset(NULL);
+ fStartVertex = startVertex;
+ fStartIndex = 0;
+ fVertexCount = vertexCount;
+ fIndexCount = 0;
+ fInstanceCount = 0;
+ fVerticesPerInstance = 0;
+ fIndicesPerInstance = 0;
+ }
+
+ void initIndexed(GrPrimitiveType primType,
+ const GrVertexBuffer* vertexBuffer,
+ const GrIndexBuffer* 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(SkRef(vertexBuffer));
+ fIndexBuffer.reset(SkRef(indexBuffer));
+ fStartVertex = startVertex;
+ fStartIndex = startIndex;
+ fVertexCount = vertexCount;
+ fIndexCount = indexCount;
+ fInstanceCount = 0;
+ fVerticesPerInstance = 0;
+ fIndicesPerInstance = 0;
+ }
+
+ void initInstanced(GrPrimitiveType primType,
+ const GrVertexBuffer* vertexBuffer,
+ const GrIndexBuffer* indexBuffer,
+ int startVertex,
+ int verticesPerInstance,
+ int indicesPerInstance,
+ int instanceCount) {
+ SkASSERT(vertexBuffer);
+ SkASSERT(indexBuffer);
+ SkASSERT(instanceCount);
+ SkASSERT(verticesPerInstance);
+ SkASSERT(indicesPerInstance);
+ SkASSERT(startVertex >= 0);
+ fPrimitiveType = primType;
+ fVertexBuffer.reset(SkRef(vertexBuffer));
+ fIndexBuffer.reset(SkRef(indexBuffer));
+ fStartVertex = startVertex;
+ fStartIndex = 0;
+ fVerticesPerInstance = verticesPerInstance;
+ fIndicesPerInstance = indicesPerInstance;
+ fInstanceCount = instanceCount;
+ fVertexCount = instanceCount * fVerticesPerInstance;
+ fIndexCount = instanceCount * fIndicesPerInstance;
+ }
+
+ /** 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 GrVertexBuffer* vertexBuffer,
+ const GrIndexBuffer* indexBuffer,
+ int startVertex,
+ int verticesPerInstance,
+ int indicesPerInstance,
+ int* instancesRemaining,
+ int maxInstancesPerDraw) {
+ int instanceCount = SkTMin(*instancesRemaining, maxInstancesPerDraw);
+ *instancesRemaining -= instanceCount;
+ this->initInstanced(primType, vertexBuffer, indexBuffer, startVertex,
+ verticesPerInstance, indicesPerInstance, instanceCount);
+ }
+
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; }
+
+ /** These return 0 if initInstanced was not used to initialize the DrawInfo. */
int verticesPerInstance() const { return fVerticesPerInstance; }
int indicesPerInstance() const { return fIndicesPerInstance; }
int instanceCount() const { return fInstanceCount; }
- void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
- void setStartVertex(int startVertex) { fStartVertex = startVertex; }
- void setStartIndex(int startIndex) { fStartIndex = startIndex; }
- void setVertexCount(int vertexCount) { fVertexCount = vertexCount; }
- void setIndexCount(int indexCount) { fIndexCount = indexCount; }
- void setVerticesPerInstance(int verticesPerI) { fVerticesPerInstance = verticesPerI; }
- void setIndicesPerInstance(int indicesPerI) { fIndicesPerInstance = indicesPerI; }
- void setInstanceCount(int instanceCount) { fInstanceCount = instanceCount; }
-
bool isIndexed() const { return fIndexCount > 0; }
-#ifdef SK_DEBUG
- bool isInstanced() const; // this version is longer because of asserts
-#else
bool isInstanced() const { return fInstanceCount > 0; }
-#endif
- // adds or remove instances
- void adjustInstanceCount(int instanceOffset);
- // shifts the start vertex
- void adjustStartVertex(int vertexOffset) {
- fStartVertex += vertexOffset;
- SkASSERT(fStartVertex >= 0);
- }
- // shifts the start index
- void adjustStartIndex(int indexOffset) {
- SkASSERT(this->isIndexed());
- fStartIndex += indexOffset;
- SkASSERT(fStartIndex >= 0);
- }
- void setDevBounds(const SkRect& bounds) {
- fDevBoundsStorage = bounds;
- fDevBounds = &fDevBoundsStorage;
+ /** Called after using this draw info to draw the next set of instances.
+ The vertex offset is advanced while the index buffer is reused at the same
+ position. instancesRemaining is number of instances that remain, maxInstances is
+ the most number of instances that can be used with the index buffer. If there
+ are no instances remaining, the DrawInfo is unmodified and false is returned.*/
+ bool nextInstances(int* instancesRemaining, int maxInstances) {
+ SkASSERT(this->isInstanced());
+ if (!*instancesRemaining) {
+ return false;
+ }
+ fStartVertex += fVertexCount;
+ fInstanceCount = SkTMin(*instancesRemaining, maxInstances);
+ fVertexCount = fInstanceCount * fVerticesPerInstance;
+ fIndexCount = fInstanceCount * fIndicesPerInstance;
+ *instancesRemaining -= fInstanceCount;
+ return true;
}
+
const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); }
const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); }
- void setVertexBuffer(const GrVertexBuffer* vb) {
- fVertexBuffer.reset(vb);
- }
- void setIndexBuffer(const GrIndexBuffer* ib) {
- fIndexBuffer.reset(ib);
- }
- const SkRect* getDevBounds() const { return fDevBounds; }
private:
friend class GrDrawTarget;
@@ -299,9 +366,6 @@ public:
int fVerticesPerInstance;
int fIndicesPerInstance;
- SkRect fDevBoundsStorage;
- SkRect* fDevBounds;
-
GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer;
};
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index bf78a90743..a766af2c7e 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -8,7 +8,6 @@
#include "GrInOrderDrawBuffer.h"
#include "GrDefaultGeoProcFactory.h"
-#include "GrResourceProvider.h"
#include "GrTemplates.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context,
@@ -132,79 +131,49 @@ public:
init.fUsesLocalCoords = this->usesLocalCoords();
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
+ int instanceCount = fGeoData.count();
size_t vertexStride = gp->getVertexStride();
-
SkASSERT(hasExplicitLocalCoords ?
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorLocalCoordAttr) :
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
+ QuadHelper helper;
+ void* vertices = helper.init(batchTarget, vertexStride, instanceCount);
- int instanceCount = fGeoData.count();
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
- int vertexCount = kVertsPerRect * instanceCount;
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ if (!vertices) {
return;
}
+
for (int i = 0; i < instanceCount; i++) {
- const Geometry& args = fGeoData[i];
+ const Geometry& geom = fGeoData[i];
- intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
+ intptr_t offset = GrTCast<intptr_t>(vertices) + kVerticesPerQuad * i * vertexStride;
SkPoint* positions = GrTCast<SkPoint*>(offset);
- positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
- args.fRect.fRight, args.fRect.fBottom, vertexStride);
- args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
+ positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop,
+ geom.fRect.fRight, geom.fRect.fBottom, vertexStride);
+ geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerticesPerQuad);
- if (args.fHasLocalRect) {
+ if (geom.fHasLocalRect) {
static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
- coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
- args.fLocalRect.fRight, args.fLocalRect.fBottom,
+ coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop,
+ geom.fLocalRect.fRight, geom.fLocalRect.fBottom,
vertexStride);
- if (args.fHasLocalMatrix) {
- args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
+ if (geom.fHasLocalMatrix) {
+ geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad);
}
}
static const int kColorOffset = sizeof(SkPoint);
GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
for (int j = 0; j < 4; ++j) {
- *vertColor = args.fColor;
+ *vertColor = geom.fColor;
vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
}
}
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerRect);
- drawInfo.setIndicesPerInstance(kIndicesPerRect);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = indexBuffer->maxQuads();
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
- }
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -263,9 +232,6 @@ private:
bool fCoverageIgnored;
};
- const static int kVertsPerRect = 4;
- const static int kIndicesPerRect = 6;
-
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 38efefa857..a5dc991e70 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -744,34 +744,22 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
- int vertexCount = kVertsPerCircle * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(CircleVertex));
-
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
-
- void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ QuadHelper helper;
+ CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, vertexStride,
+ instanceCount));
+ if (!verts) {
return;
}
- CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices);
-
for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
+ Geometry& geom = fGeoData[i];
- SkScalar innerRadius = args.fInnerRadius;
- SkScalar outerRadius = args.fOuterRadius;
+ SkScalar innerRadius = geom.fInnerRadius;
+ SkScalar outerRadius = geom.fOuterRadius;
- const SkRect& bounds = args.fDevBounds;
+ const SkRect& bounds = geom.fDevBounds;
// The inner radius in the vertex data must be specified in normalized space.
innerRadius = innerRadius / outerRadius;
@@ -795,31 +783,9 @@ public:
verts[3].fOuterRadius = outerRadius;
verts[3].fInnerRadius = innerRadius;
- verts += kVertsPerCircle;
- }
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerCircle);
- drawInfo.setIndicesPerInstance(kIndicesPerCircle);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = indexBuffer->maxQuads();
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
+ verts += kVerticesPerQuad;
}
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -867,9 +833,6 @@ private:
bool fCoverageIgnored;
};
- static const int kVertsPerCircle = 4;
- static const int kIndicesPerCircle = 6;
-
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -1009,40 +972,28 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
- int vertexCount = kVertsPerEllipse * instanceCount;
+ QuadHelper helper;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(EllipseVertex));
-
- const GrVertexBuffer* vertexBuffer;
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
- int firstVertex;
-
- void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
+ helper.init(batchTarget, vertexStride, instanceCount));
+ if (!verts) {
return;
}
- EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices);
-
for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
+ Geometry& geom = fGeoData[i];
- SkScalar xRadius = args.fXRadius;
- SkScalar yRadius = args.fYRadius;
+ SkScalar xRadius = geom.fXRadius;
+ SkScalar yRadius = geom.fYRadius;
// Compute the reciprocals of the radii here to save time in the shader
SkScalar xRadRecip = SkScalarInvert(xRadius);
SkScalar yRadRecip = SkScalarInvert(yRadius);
- SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius);
- SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius);
+ SkScalar xInnerRadRecip = SkScalarInvert(geom.fInnerXRadius);
+ SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius);
- const SkRect& bounds = args.fDevBounds;
+ const SkRect& bounds = geom.fDevBounds;
// The inner radius in the vertex data must be specified in normalized space.
verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
@@ -1065,31 +1016,9 @@ public:
verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
- verts += kVertsPerEllipse;
- }
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerEllipse);
- drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = indexBuffer->maxQuads();
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
+ verts += kVerticesPerQuad;
}
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1137,9 +1066,6 @@ private:
bool fCoverageIgnored;
};
- static const int kVertsPerEllipse = 4;
- static const int kIndicesPerEllipse = 6;
-
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -1317,41 +1243,30 @@ public:
init.fUsesLocalCoords = this->usesLocalCoords();
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
int instanceCount = fGeoData.count();
- int vertexCount = kVertsPerEllipse * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(DIEllipseVertex));
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
- void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
-
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ QuadHelper helper;
+ DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(
+ helper.init(batchTarget, vertexStride, instanceCount));
+ if (!verts) {
return;
}
- DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices);
-
for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
+ Geometry& geom = fGeoData[i];
- SkScalar xRadius = args.fXRadius;
- SkScalar yRadius = args.fYRadius;
+ SkScalar xRadius = geom.fXRadius;
+ SkScalar yRadius = geom.fYRadius;
- const SkRect& bounds = args.fBounds;
+ const SkRect& bounds = geom.fBounds;
// This adjusts the "radius" to include the half-pixel border
- SkScalar offsetDx = SkScalarDiv(args.fGeoDx, xRadius);
- SkScalar offsetDy = SkScalarDiv(args.fGeoDy, yRadius);
+ SkScalar offsetDx = SkScalarDiv(geom.fGeoDx, xRadius);
+ SkScalar offsetDy = SkScalarDiv(geom.fGeoDy, yRadius);
- SkScalar innerRatioX = SkScalarDiv(xRadius, args.fInnerXRadius);
- SkScalar innerRatioY = SkScalarDiv(yRadius, args.fInnerYRadius);
+ SkScalar innerRatioX = SkScalarDiv(xRadius, geom.fInnerXRadius);
+ SkScalar innerRatioY = SkScalarDiv(yRadius, geom.fInnerYRadius);
verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy);
@@ -1369,31 +1284,9 @@ public:
verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy);
verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
- verts += kVertsPerEllipse;
- }
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerEllipse);
- drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = indexBuffer->maxQuads();
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
+ verts += kVerticesPerQuad;
}
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1441,9 +1334,6 @@ private:
bool fCoverageIgnored;
};
- static const int kVertsPerEllipse = 4;
- static const int kIndicesPerEllipse = 6;
-
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -1722,27 +1612,22 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
- int vertexCount = kVertsPerRRect * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(CircleVertex));
- const GrVertexBuffer* vertexBuffer;
+ // drop out the middle quad if we're stroked
+ int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect;
SkAutoTUnref<const GrIndexBuffer> indexBuffer(
ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
- int firstVertex;
-
- void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
- if (!vertices || !indexBuffer) {
+ InstancedHelper helper;
+ CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget,
+ vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance, instanceCount));
+ if (!verts || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
- CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices);
-
for (int i = 0; i < instanceCount; i++) {
Geometry& args = fGeoData[i];
@@ -1787,32 +1672,7 @@ public:
}
}
- // drop out the middle quad if we're stroked
- int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
- SK_ARRAY_COUNT(gRRectIndices);
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerRRect);
- drawInfo.setIndicesPerInstance(indexCnt);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
- }
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1933,27 +1793,23 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
- int vertexCount = kVertsPerRRect * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(EllipseVertex));
- const GrVertexBuffer* vertexBuffer;
+ // drop out the middle quad if we're stroked
+ int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect;
SkAutoTUnref<const GrIndexBuffer> indexBuffer(
ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
- int firstVertex;
-
- void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- vertexCount,
- &vertexBuffer,
- &firstVertex);
- if (!vertices || !indexBuffer) {
+ InstancedHelper helper;
+ EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
+ helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance,
+ instanceCount));
+ if (!verts || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
- EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices);
-
for (int i = 0; i < instanceCount; i++) {
Geometry& args = fGeoData[i];
@@ -2008,33 +1864,7 @@ public:
verts++;
}
}
-
- // drop out the middle quad if we're stroked
- int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
- SK_ARRAY_COUNT(gRRectIndices);
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerRRect);
- drawInfo.setIndicesPerInstance(indexCnt);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
-
- while (instanceCount) {
- drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- instanceCount -= drawInfo.instanceCount();
- }
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp
index 7a9c5a7751..5fd1bcd479 100644
--- a/src/gpu/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/GrTessellatingPathRenderer.cpp
@@ -1459,12 +1459,7 @@ public:
GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
: kTriangles_GrPrimitiveType;
GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(primitiveType);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setStartVertex(firstVertex);
- drawInfo.setVertexCount(actualCount);
- drawInfo.setStartIndex(0);
- drawInfo.setIndexCount(0);
+ drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount);
batchTarget->draw(drawInfo);
batchTarget->putBackVertices((size_t)(count - actualCount), stride);
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index fa8b3a2dcf..b941d8be7d 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -19,7 +19,6 @@
#include "GrDrawTargetCaps.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
-#include "GrResourceProvider.h"
#include "GrStrokeInfo.h"
#include "GrVertexBuffer.h"
#include "SkGr.h"
@@ -536,38 +535,29 @@ public:
draw.fHasEndRect = hasEndRect;
}
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
- const GrVertexBuffer* vertexBuffer;
- int firstVertex;
- size_t vertexStride = gp->getVertexStride();
- void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- totalRectCount * kVertsPerDash,
- &vertexBuffer,
- &firstVertex);
- if (!vertices || !indexBuffer) {
- SkDebugf("Could not allocate buffers\n");
+ QuadHelper helper;
+ void* vertices = helper.init(batchTarget, gp->getVertexStride(), instanceCount);
+ if (!vertices) {
return;
}
int curVIdx = 0;
int rectIndex = 0;
for (int i = 0; i < instanceCount; i++) {
- Geometry& args = fGeoData[i];
+ Geometry& geom = fGeoData[i];
if (!draws[i].fLineDone) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
+ setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
draws[i].fDevBloatY, draws[i].fLineLength,
- draws[i].fHalfDevStroke, args.fIntervals[0],
- args.fIntervals[1], draws[i].fStrokeWidth,
+ draws[i].fHalfDevStroke, geom.fIntervals[0],
+ geom.fIntervals[1], draws[i].fStrokeWidth,
capType, gp->getVertexStride());
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
- setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
+ setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
}
curVIdx += 4;
}
@@ -575,16 +565,16 @@ public:
if (draws[i].fHasStartRect) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
+ setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, args.fIntervals[0],
- draws[i].fHalfDevStroke, args.fIntervals[0],
- args.fIntervals[1], draws[i].fStrokeWidth, capType,
+ draws[i].fDevBloatY, geom.fIntervals[0],
+ draws[i].fHalfDevStroke, geom.fIntervals[0],
+ geom.fIntervals[1], draws[i].fStrokeWidth, capType,
gp->getVertexStride());
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
- setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
+ setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
}
curVIdx += 4;
@@ -593,43 +583,22 @@ public:
if (draws[i].fHasEndRect) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
+ setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, args.fIntervals[0],
- draws[i].fHalfDevStroke, args.fIntervals[0],
- args.fIntervals[1], draws[i].fStrokeWidth, capType,
+ draws[i].fDevBloatY, geom.fIntervals[0],
+ draws[i].fHalfDevStroke, geom.fIntervals[0],
+ geom.fIntervals[1], draws[i].fStrokeWidth, capType,
gp->getVertexStride());
} else {
SkPoint* verts = reinterpret_cast<SkPoint*>(vertices);
SkASSERT(gp->getVertexStride() == sizeof(SkPoint));
- setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
+ setup_dashed_rect_pos(rects[rectIndex], curVIdx, geom.fSrcRotInv, verts);
}
curVIdx += 4;
}
rectIndex++;
}
-
- GrDrawTarget::DrawInfo drawInfo;
- drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
- drawInfo.setStartVertex(0);
- drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerDash);
- drawInfo.setIndicesPerInstance(kIndicesPerDash);
- drawInfo.adjustStartVertex(firstVertex);
- drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
-
- int maxInstancesPerDraw = indexBuffer->maxQuads();
- while (totalRectCount) {
- drawInfo.setInstanceCount(SkTMin(totalRectCount, maxInstancesPerDraw));
- drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
- drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPerInstance());
-
- batchTarget->draw(drawInfo);
-
- drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCount());
- totalRectCount -= drawInfo.instanceCount();
- }
+ helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }