Start on simplifying generateGeometry() overrides
Review URL: https://codereview.chromium.org/1122673002
This commit is contained in:
parent
b327c3a84a
commit
f28381c686
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
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; }
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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];
|
||||
|
||||
intptr_t offset = GrTCast<intptr_t>(vertices) + kVertsPerRect * i * vertexStride;
|
||||
for (int i = 0; i < instanceCount; i++) {
|
||||
const Geometry& geom = fGeoData[i];
|
||||
|
||||
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;
|
||||
};
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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; }
|
||||
|
Loading…
Reference in New Issue
Block a user