aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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, 734 insertions, 433 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index d543c149c7..6568422898 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -16,6 +16,7 @@
#include "GrBufferAllocPool.h"
#include "GrContext.h"
#include "GrPathUtils.h"
+#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTestBatch.h"
#include "SkColorPriv.h"
@@ -66,14 +67,25 @@ private:
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- QuadHelper helper;
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ batchTarget->resourceProvider()->refQuadIndexBuffer());
+
size_t vertexStride = this->geometryProcessor()->getVertexStride();
- SkASSERT(vertexStride == sizeof(Vertex));
- Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
- if (!verts) {
+ const GrVertexBuffer* vertexBuffer;
+ int firstVertex;
+ void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+ kVertsPerCubic,
+ &vertexBuffer,
+ &firstVertex);
+
+ if (!vertices || !indexBuffer) {
+ SkDebugf("Could not allocate buffers\n");
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));
@@ -82,7 +94,16 @@ 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);
}
- helper.issueDraws(batchTarget);
+
+ 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);
}
Geometry fGeometry;
@@ -454,19 +475,42 @@ private:
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- QuadHelper helper;
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ batchTarget->resourceProvider()->refQuadIndexBuffer());
+
size_t vertexStride = this->geometryProcessor()->getVertexStride();
- SkASSERT(vertexStride == sizeof(Vertex));
- GrDrawTarget::DrawInfo drawInfo;
- Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
- if (!verts) {
+ const GrVertexBuffer* vertexBuffer;
+ int firstVertex;
+
+ void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+ kVertsPerCubic,
+ &vertexBuffer,
+ &firstVertex);
+
+ if (!vertices || !indexBuffer) {
+ SkDebugf("Could not allocate buffers\n");
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);
- helper.issueDraws(batchTarget);
+
+
+ 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);
}
Geometry fGeometry;
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index cd9b3d10e5..60b73c571d 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -17,6 +17,7 @@
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h"
+#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTestBatch.h"
#include "SkColorPriv.h"
@@ -52,24 +53,47 @@ private:
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ batchTarget->resourceProvider()->refQuadIndexBuffer());
+
size_t vertexStride = this->geometryProcessor()->getVertexStride();
- SkASSERT(vertexStride == sizeof(SkPoint));
- QuadHelper helper;
- SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(batchTarget, vertexStride, 1));
- if (!verts) {
+ const GrVertexBuffer* vertexBuffer;
+ int firstVertex;
+
+ void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+ kVertsPerCubic,
+ &vertexBuffer,
+ &firstVertex);
+
+ if (!vertices || !indexBuffer) {
+ SkDebugf("Could not allocate buffers\n");
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);
- helper.issueDraws(batchTarget);
+ 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);
}
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 f20306404a..3a548aa60a 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -824,14 +824,19 @@ 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.initIndexed(kTriangles_GrPrimitiveType, vertexBuffer, indexBuffer, firstVertex,
- firstIndex, draw.fVertexCnt, draw.fIndexCnt);
+ info.setStartVertex(vOffset + firstVertex);
+ info.setVertexCount(draw.fVertexCnt);
+ info.setIndexCount(draw.fIndexCnt);
batchTarget->draw(info);
- firstVertex += draw.fVertexCnt;
- firstIndex += draw.fIndexCnt;
+ vOffset += draw.fVertexCnt;
}
}
}
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index 312b731fd7..ca8c52fa34 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,13 +169,6 @@ 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();
@@ -202,25 +195,43 @@ public:
this->initDraw(batchTarget, dfProcessor, pipeline);
- FlushInfo flushInfo;
+ static const int kVertsPerQuad = 4;
+ static const int kIndicesPerQuad = 6;
+
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ batchTarget->resourceProvider()->refQuadIndexBuffer());
// allocate vertices
size_t vertexStride = dfProcessor->getVertexStride();
SkASSERT(vertexStride == 2 * sizeof(SkPoint));
-
const GrVertexBuffer* vertexBuffer;
+ int vertexCount = kVertsPerQuad * instanceCount;
+ int firstVertex;
+
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
- kVerticesPerQuad * instanceCount,
+ vertexCount,
&vertexBuffer,
- &flushInfo.fVertexOffset);
- flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
- flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer());
- if (!vertices || !flushInfo.fIndexBuffer) {
+ &firstVertex);
+
+ if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
- flushInfo.fInstancesToFlush = 0;
+ // 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;
for (int i = 0; i < instanceCount; i++) {
Geometry& args = fGeoData[i];
@@ -254,7 +265,9 @@ public:
if (!this->addPathToAtlas(batchTarget,
dfProcessor,
pipeline,
- &flushInfo,
+ &drawInfo,
+ &instancesToFlush,
+ maxInstancesPerDraw,
atlas,
args.fPathData,
args.fPath,
@@ -271,21 +284,21 @@ public:
// Now set vertices
intptr_t offset = reinterpret_cast<intptr_t>(vertices);
- offset += i * kVerticesPerQuad * vertexStride;
+ offset += i * kVertsPerQuad * vertexStride;
SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
- this->writePathVertices(batchTarget,
- atlas,
- pipeline,
- dfProcessor,
- positions,
- vertexStride,
- this->viewMatrix(),
- args.fPath,
- args.fPathData);
- flushInfo.fInstancesToFlush++;
+ this->drawPath(batchTarget,
+ atlas,
+ pipeline,
+ dfProcessor,
+ positions,
+ vertexStride,
+ this->viewMatrix(),
+ args.fPath,
+ args.fPathData);
+ instancesToFlush++;
}
- this->flush(batchTarget, &flushInfo);
+ this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -312,7 +325,9 @@ private:
bool addPathToAtlas(GrBatchTarget* batchTarget,
const GrGeometryProcessor* dfProcessor,
const GrPipeline* pipeline,
- FlushInfo* flushInfo,
+ GrDrawTarget::DrawInfo* drawInfo,
+ int* instancesToFlush,
+ int maxInstancesPerDraw,
GrBatchAtlas* atlas,
PathData* pathData,
const SkPath& path,
@@ -414,8 +429,9 @@ private:
bool success = atlas->addToAtlas(&id, batchTarget, width, height, dfStorage.get(),
&atlasLocation);
if (!success) {
- this->flush(batchTarget, flushInfo);
+ this->flush(batchTarget, drawInfo, *instancesToFlush, maxInstancesPerDraw);
this->initDraw(batchTarget, dfProcessor, pipeline);
+ *instancesToFlush = 0;
SkDEBUGCODE(success =) atlas->addToAtlas(&id, batchTarget, width, height,
dfStorage.get(), &atlasLocation);
@@ -451,15 +467,15 @@ private:
return true;
}
- 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) {
+ 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) {
GrTexture* texture = atlas->getTexture();
SkScalar dx = pathData->fBounds.fLeft;
@@ -506,18 +522,20 @@ private:
dfProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init);
}
- 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;
+ 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();
+ }
}
GrColor color() const { return fBatch.fColor; }
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index ba6dcecd43..f046af871f 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -888,14 +888,23 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
}
{
- int linesLeft = lineCount;
GrDrawTarget::DrawInfo info;
- info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer,
- firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft,
- kLineSegsNumInIdxBuffer);
- do {
+ 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);
batchTarget->draw(info);
- } while (info.nextInstances(&linesLeft, kLineSegsNumInIdxBuffer));
+
+ lines += n;
+ }
}
}
@@ -944,15 +953,23 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
quadGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
{
- int quadsLeft = quadCount;
- GrDrawTarget::DrawInfo info;
- info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
- firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft,
- kQuadsNumInIdxBuffer);
- do {
+ 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);
batchTarget->draw(info);
- } while (info.nextInstances(&quadsLeft, kQuadsNumInIdxBuffer));
- firstVertex += quadCount * kQuadNumVertices;
+
+ quads += n;
+ }
}
}
@@ -968,14 +985,23 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
conicGP->initBatchTracker(batchTarget->currentBatchTracker(), init);
{
- int conicsLeft = conicCount;
GrDrawTarget::DrawInfo info;
- info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
- firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft,
- kQuadsNumInIdxBuffer);
- do {
+ 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);
batchTarget->draw(info);
- } while (info.nextInstances(&conicsLeft, kQuadsNumInIdxBuffer));
+
+ conics += n;
+ }
}
}
}
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index 267d970c62..d1c377aa53 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -112,17 +112,22 @@ 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;
@@ -140,7 +145,28 @@ public:
canTweakAlphaForCoverage);
}
- helper.issueDraws(batchTarget);
+ 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();
+ }
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -459,6 +485,9 @@ 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
@@ -476,24 +505,28 @@ public:
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
int innerVertexNum = 4;
int outerVertexNum = this->miterStroke() ? 4 : 8;
- int verticesPerInstance = (outerVertexNum + innerVertexNum) * 2;
- int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
+ int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
+
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 * verticesPerInstance * vertexStride,
+ i * totalVertexNum * vertexStride,
vertexStride,
outerVertexNum,
innerVertexNum,
@@ -504,7 +537,30 @@ public:
args.fMiterStroke,
canTweakAlphaForCoverage);
}
- helper.issueDraws(batchTarget);
+ 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();
+ }
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index c8688b0adc..33e4f7ed86 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -1474,13 +1474,6 @@ 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
@@ -1513,8 +1506,6 @@ public:
localMatrix));
}
- FlushInfo flushInfo;
- flushInfo.fGlyphsToFlush = 0;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == (fUseDistanceFields ?
get_vertex_stride_df(fMaskFormat, fUseLCDText) :
@@ -1524,21 +1515,35 @@ public:
int glyphCount = this->numGlyphs();
int instanceCount = fInstanceCount;
- const GrVertexBuffer* vertexBuffer;
+ SkAutoTUnref<const GrIndexBuffer> indexBuffer(
+ batchTarget->resourceProvider()->refQuadIndexBuffer());
+ const GrVertexBuffer* vertexBuffer;
+ int firstVertex;
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
glyphCount * kVerticesPerGlyph,
&vertexBuffer,
- &flushInfo.fVertexOffset);
- flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
- flushInfo.fIndexBuffer.reset(batchTarget->resourceProvider()->refQuadIndexBuffer());
- if (!vertices || !flushInfo.fVertexBuffer) {
+ &firstVertex);
+ if (!vertices || !indexBuffer) {
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;
@@ -1546,6 +1551,7 @@ 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;
@@ -1629,8 +1635,10 @@ public:
if (!fFontCache->hasGlyph(glyph) &&
!strike->addGlyphToAtlas(batchTarget, glyph, scaler)) {
- this->flush(batchTarget, &flushInfo);
+ this->flush(batchTarget, &drawInfo, instancesToFlush,
+ maxInstancesPerDraw);
this->initDraw(batchTarget, gp, pipeline);
+ instancesToFlush = 0;
brokenRun = glyphIdx > 0;
SkDEBUGCODE(bool success =) strike->addGlyphToAtlas(batchTarget,
@@ -1666,7 +1674,7 @@ public:
SkScalar transY = args.fTransY;
this->regeneratePositions(vertex, vertexStride, transX, transY);
}
- flushInfo.fGlyphsToFlush++;
+ instancesToFlush++;
}
// We my have changed the color so update it here
@@ -1679,7 +1687,7 @@ public:
fFontCache->atlasGeneration(fMaskFormat);
}
} else {
- flushInfo.fGlyphsToFlush += glyphCount;
+ instancesToFlush += glyphCount;
// set use tokens for all of the glyphs in our subrun. This is only valid if we
// have a valid atlas generation
@@ -1698,7 +1706,7 @@ public:
if (cache) {
SkGlyphCache::AttachCache(cache);
}
- this->flush(batchTarget, &flushInfo);
+ this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDraw);
}
// The minimum number of Geometry we will try to allocate.
@@ -1825,19 +1833,20 @@ private:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
}
- 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;
+ 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();
+ }
}
GrColor color() const { return fBatch.fColor; }
diff --git a/src/gpu/GrBatch.cpp b/src/gpu/GrBatch.cpp
index 1ef6c9797c..ce30499ff8 100644
--- a/src/gpu/GrBatch.cpp
+++ b/src/gpu/GrBatch.cpp
@@ -6,8 +6,6 @@
*/
#include "GrBatch.h"
-#include "GrBatchTarget.h"
-#include "GrResourceProvider.h"
#include "GrMemoryPool.h"
#include "SkSpinlock.h"
@@ -45,43 +43,3 @@ 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 38316cebad..7b5c888a70 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,48 +113,6 @@ 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 a9c6ce0b5a..819774a076 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -502,7 +502,15 @@ public:
}
GrDrawTarget::DrawInfo drawInfo;
- drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount);
+ 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);
batchTarget->draw(drawInfo);
}
@@ -821,8 +829,8 @@ public:
return;
}
- const GrIndexBuffer* indexBuffer = NULL;
- int firstIndex = 0;
+ const GrIndexBuffer* indexBuffer;
+ int firstIndex;
void* indices = NULL;
if (this->hasIndices()) {
@@ -862,12 +870,17 @@ public:
}
GrDrawTarget::DrawInfo drawInfo;
+ drawInfo.setPrimitiveType(this->primitiveType());
+ drawInfo.setVertexBuffer(vertexBuffer);
+ drawInfo.setStartVertex(firstVertex);
+ drawInfo.setVertexCount(this->vertexCount());
if (this->hasIndices()) {
- drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
- firstIndex, this->vertexCount(), this->indexCount());
-
+ drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setStartIndex(firstIndex);
+ drawInfo.setIndexCount(this->indexCount());
} else {
- drawInfo.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
+ drawInfo.setStartIndex(0);
+ drawInfo.setIndexCount(0);
}
batchTarget->draw(drawInfo);
}
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index a86d117f59..93d64abab2 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -329,8 +329,8 @@ public:
return;
}
- const GrIndexBuffer* indexBuffer = NULL;
- int firstIndex = 0;
+ const GrIndexBuffer* indexBuffer;
+ int firstIndex;
void* indices = NULL;
if (isIndexed) {
@@ -370,11 +370,17 @@ public:
}
GrDrawTarget::DrawInfo drawInfo;
+ drawInfo.setPrimitiveType(primitiveType);
+ drawInfo.setVertexBuffer(vertexBuffer);
+ drawInfo.setStartVertex(firstVertex);
+ drawInfo.setVertexCount(vertexOffset);
if (isIndexed) {
- drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
- vertexOffset, indexOffset);
+ drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setStartIndex(firstIndex);
+ drawInfo.setIndexCount(indexOffset);
} else {
- drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
+ drawInfo.setStartIndex(0);
+ drawInfo.setIndexCount(0);
}
batchTarget->draw(drawInfo);
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7ae2c99825..850309797c 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -37,8 +37,16 @@ GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
fVerticesPerInstance = di.fVerticesPerInstance;
fIndicesPerInstance = di.fIndicesPerInstance;
- fVertexBuffer.reset(di.vertexBuffer());
- fIndexBuffer.reset(di.indexBuffer());
+ if (di.fDevBounds) {
+ SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
+ fDevBoundsStorage = di.fDevBoundsStorage;
+ fDevBounds = &fDevBoundsStorage;
+ } else {
+ fDevBounds = NULL;
+ }
+
+ this->setVertexBuffer(di.vertexBuffer());
+ this->setIndexBuffer(di.indexBuffer());
return *this;
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index c584181396..0dca57a9db 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -225,132 +225,65 @@ public:
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
/**
- * Used to communicate draw index vertex offsets and counts toto GPUs / subclasses
+ * Used to communicate draws to GPUs / subclasses
*/
class DrawInfo {
public:
- DrawInfo() {}
+ DrawInfo() { fDevBounds = NULL; }
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
- /** 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;
+ // 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;
}
-
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;
@@ -366,6 +299,9 @@ 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 a766af2c7e..bf78a90743 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -8,6 +8,7 @@
#include "GrInOrderDrawBuffer.h"
#include "GrDefaultGeoProcFactory.h"
+#include "GrResourceProvider.h"
#include "GrTemplates.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context,
@@ -131,49 +132,79 @@ 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);
- if (!vertices) {
+ 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");
return;
}
-
for (int i = 0; i < instanceCount; i++) {
- const Geometry& geom = fGeoData[i];
+ const Geometry& args = fGeoData[i];
- intptr_t offset = GrTCast<intptr_t>(vertices) + kVerticesPerQuad * i * vertexStride;
+ intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
SkPoint* positions = GrTCast<SkPoint*>(offset);
- positions->setRectFan(geom.fRect.fLeft, geom.fRect.fTop,
- geom.fRect.fRight, geom.fRect.fBottom, vertexStride);
- geom.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVerticesPerQuad);
+ positions->setRectFan(args.fRect.fLeft, args.fRect.fTop,
+ args.fRect.fRight, args.fRect.fBottom, vertexStride);
+ args.fViewMatrix.mapPointsWithStride(positions, vertexStride, kVertsPerRect);
- if (geom.fHasLocalRect) {
+ if (args.fHasLocalRect) {
static const int kLocalOffset = sizeof(SkPoint) + sizeof(GrColor);
SkPoint* coords = GrTCast<SkPoint*>(offset + kLocalOffset);
- coords->setRectFan(geom.fLocalRect.fLeft, geom.fLocalRect.fTop,
- geom.fLocalRect.fRight, geom.fLocalRect.fBottom,
+ coords->setRectFan(args.fLocalRect.fLeft, args.fLocalRect.fTop,
+ args.fLocalRect.fRight, args.fLocalRect.fBottom,
vertexStride);
- if (geom.fHasLocalMatrix) {
- geom.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVerticesPerQuad);
+ if (args.fHasLocalMatrix) {
+ args.fLocalMatrix.mapPointsWithStride(coords, vertexStride, kVertsPerRect);
}
}
static const int kColorOffset = sizeof(SkPoint);
GrColor* vertColor = GrTCast<GrColor*>(offset + kColorOffset);
for (int j = 0; j < 4; ++j) {
- *vertColor = geom.fColor;
+ *vertColor = args.fColor;
vertColor = (GrColor*) ((intptr_t) vertColor + vertexStride);
}
}
- helper.issueDraws(batchTarget);
+ 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();
+ }
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -232,6 +263,9 @@ 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 a5dc991e70..38efefa857 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -744,22 +744,34 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
+ int vertexCount = kVertsPerCircle * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(CircleVertex));
- QuadHelper helper;
- CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, vertexStride,
- instanceCount));
- if (!verts) {
+
+ 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");
return;
}
+ CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices);
+
for (int i = 0; i < instanceCount; i++) {
- Geometry& geom = fGeoData[i];
+ Geometry& args = fGeoData[i];
- SkScalar innerRadius = geom.fInnerRadius;
- SkScalar outerRadius = geom.fOuterRadius;
+ SkScalar innerRadius = args.fInnerRadius;
+ SkScalar outerRadius = args.fOuterRadius;
- const SkRect& bounds = geom.fDevBounds;
+ const SkRect& bounds = args.fDevBounds;
// The inner radius in the vertex data must be specified in normalized space.
innerRadius = innerRadius / outerRadius;
@@ -783,9 +795,31 @@ public:
verts[3].fOuterRadius = outerRadius;
verts[3].fInnerRadius = innerRadius;
- verts += kVerticesPerQuad;
+ 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();
}
- helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -833,6 +867,9 @@ private:
bool fCoverageIgnored;
};
+ static const int kVertsPerCircle = 4;
+ static const int kIndicesPerCircle = 6;
+
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -972,28 +1009,40 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
- QuadHelper helper;
+ int vertexCount = kVertsPerEllipse * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(EllipseVertex));
- EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
- helper.init(batchTarget, vertexStride, instanceCount));
- if (!verts) {
+
+ 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");
return;
}
+ EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices);
+
for (int i = 0; i < instanceCount; i++) {
- Geometry& geom = fGeoData[i];
+ Geometry& args = fGeoData[i];
- SkScalar xRadius = geom.fXRadius;
- SkScalar yRadius = geom.fYRadius;
+ SkScalar xRadius = args.fXRadius;
+ SkScalar yRadius = args.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(geom.fInnerXRadius);
- SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius);
+ SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius);
+ SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius);
- const SkRect& bounds = geom.fDevBounds;
+ const SkRect& bounds = args.fDevBounds;
// The inner radius in the vertex data must be specified in normalized space.
verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
@@ -1016,9 +1065,31 @@ public:
verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
- verts += kVerticesPerQuad;
+ 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();
}
- helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1066,6 +1137,9 @@ private:
bool fCoverageIgnored;
};
+ static const int kVertsPerEllipse = 4;
+ static const int kIndicesPerEllipse = 6;
+
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -1243,30 +1317,41 @@ 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));
- QuadHelper helper;
- DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(
- helper.init(batchTarget, vertexStride, instanceCount));
- if (!verts) {
+ const GrVertexBuffer* vertexBuffer;
+ int firstVertex;
+ void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+ vertexCount,
+ &vertexBuffer,
+ &firstVertex);
+
+ if (!vertices || !indexBuffer) {
+ SkDebugf("Could not allocate buffers\n");
return;
}
+ DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices);
+
for (int i = 0; i < instanceCount; i++) {
- Geometry& geom = fGeoData[i];
+ Geometry& args = fGeoData[i];
- SkScalar xRadius = geom.fXRadius;
- SkScalar yRadius = geom.fYRadius;
+ SkScalar xRadius = args.fXRadius;
+ SkScalar yRadius = args.fYRadius;
- const SkRect& bounds = geom.fBounds;
+ const SkRect& bounds = args.fBounds;
// This adjusts the "radius" to include the half-pixel border
- SkScalar offsetDx = SkScalarDiv(geom.fGeoDx, xRadius);
- SkScalar offsetDy = SkScalarDiv(geom.fGeoDy, yRadius);
+ SkScalar offsetDx = SkScalarDiv(args.fGeoDx, xRadius);
+ SkScalar offsetDy = SkScalarDiv(args.fGeoDy, yRadius);
- SkScalar innerRatioX = SkScalarDiv(xRadius, geom.fInnerXRadius);
- SkScalar innerRatioY = SkScalarDiv(yRadius, geom.fInnerYRadius);
+ SkScalar innerRatioX = SkScalarDiv(xRadius, args.fInnerXRadius);
+ SkScalar innerRatioY = SkScalarDiv(yRadius, args.fInnerYRadius);
verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy);
@@ -1284,9 +1369,31 @@ public:
verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy);
verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
- verts += kVerticesPerQuad;
+ 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();
}
- helper.issueDraws(batchTarget);
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1334,6 +1441,9 @@ private:
bool fCoverageIgnored;
};
+ static const int kVertsPerEllipse = 4;
+ static const int kIndicesPerEllipse = 6;
+
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -1612,22 +1722,27 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
+ int vertexCount = kVertsPerRRect * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(CircleVertex));
- // drop out the middle quad if we're stroked
- int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect;
+ const GrVertexBuffer* vertexBuffer;
SkAutoTUnref<const GrIndexBuffer> indexBuffer(
ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
+ int firstVertex;
+
+ void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+ vertexCount,
+ &vertexBuffer,
+ &firstVertex);
- InstancedHelper helper;
- CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget,
- vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance, instanceCount));
- if (!verts || !indexBuffer) {
+ if (!vertices || !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];
@@ -1672,7 +1787,32 @@ public:
}
}
- helper.issueDraws(batchTarget);
+ // 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();
+ }
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@@ -1793,23 +1933,27 @@ public:
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
int instanceCount = fGeoData.count();
+ int vertexCount = kVertsPerRRect * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(EllipseVertex));
- // drop out the middle quad if we're stroked
- int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect;
+ const GrVertexBuffer* vertexBuffer;
SkAutoTUnref<const GrIndexBuffer> indexBuffer(
ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
+ int firstVertex;
+
+ void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
+ vertexCount,
+ &vertexBuffer,
+ &firstVertex);
- InstancedHelper helper;
- EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
- helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance,
- instanceCount));
- if (!verts || !indexBuffer) {
+ if (!vertices || !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];
@@ -1864,7 +2008,33 @@ public:
verts++;
}
}
- helper.issueDraws(batchTarget);
+
+ // 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();
+ }
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp
index 5fd1bcd479..7a9c5a7751 100644
--- a/src/gpu/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/GrTessellatingPathRenderer.cpp
@@ -1459,7 +1459,12 @@ public:
GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
: kTriangles_GrPrimitiveType;
GrDrawTarget::DrawInfo drawInfo;
- drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount);
+ drawInfo.setPrimitiveType(primitiveType);
+ drawInfo.setVertexBuffer(vertexBuffer);
+ drawInfo.setStartVertex(firstVertex);
+ drawInfo.setVertexCount(actualCount);
+ drawInfo.setStartIndex(0);
+ drawInfo.setIndexCount(0);
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 b941d8be7d..fa8b3a2dcf 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -19,6 +19,7 @@
#include "GrDrawTargetCaps.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
+#include "GrResourceProvider.h"
#include "GrStrokeInfo.h"
#include "GrVertexBuffer.h"
#include "SkGr.h"
@@ -535,29 +536,38 @@ public:
draw.fHasEndRect = hasEndRect;
}
- QuadHelper helper;
- void* vertices = helper.init(batchTarget, gp->getVertexStride(), instanceCount);
- if (!vertices) {
+ 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");
return;
}
int curVIdx = 0;
int rectIndex = 0;
for (int i = 0; i < instanceCount; i++) {
- Geometry& geom = fGeoData[i];
+ Geometry& args = fGeoData[i];
if (!draws[i].fLineDone) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+ setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
draws[i].fDevBloatY, draws[i].fLineLength,
- draws[i].fHalfDevStroke, geom.fIntervals[0],
- geom.fIntervals[1], draws[i].fStrokeWidth,
+ draws[i].fHalfDevStroke, args.fIntervals[0],
+ args.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, geom.fSrcRotInv, verts);
+ setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
}
curVIdx += 4;
}
@@ -565,16 +575,16 @@ public:
if (draws[i].fHasStartRect) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+ setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, geom.fIntervals[0],
- draws[i].fHalfDevStroke, geom.fIntervals[0],
- geom.fIntervals[1], draws[i].fStrokeWidth, capType,
+ draws[i].fDevBloatY, args.fIntervals[0],
+ draws[i].fHalfDevStroke, args.fIntervals[0],
+ args.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, geom.fSrcRotInv, verts);
+ setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
}
curVIdx += 4;
@@ -583,22 +593,43 @@ public:
if (draws[i].fHasEndRect) {
if (fullDash) {
- setup_dashed_rect(rects[rectIndex], vertices, curVIdx, geom.fSrcRotInv,
+ setup_dashed_rect(rects[rectIndex], vertices, curVIdx, args.fSrcRotInv,
draws[i].fStartOffset, draws[i].fDevBloatX,
- draws[i].fDevBloatY, geom.fIntervals[0],
- draws[i].fHalfDevStroke, geom.fIntervals[0],
- geom.fIntervals[1], draws[i].fStrokeWidth, capType,
+ draws[i].fDevBloatY, args.fIntervals[0],
+ draws[i].fHalfDevStroke, args.fIntervals[0],
+ args.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, geom.fSrcRotInv, verts);
+ setup_dashed_rect_pos(rects[rectIndex], curVIdx, args.fSrcRotInv, verts);
}
curVIdx += 4;
}
rectIndex++;
}
- helper.issueDraws(batchTarget);
+
+ 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();
+ }
}
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }