Move DrawInfo out from GrDrawTarget and rename to GrVertices.

Review URL: https://codereview.chromium.org/1124733004
This commit is contained in:
bsalomon 2015-05-05 09:51:38 -07:00 committed by Commit bot
parent e46760e8b2
commit cb8979d088
21 changed files with 273 additions and 256 deletions

View File

@ -457,7 +457,6 @@ private:
QuadHelper helper; QuadHelper helper;
size_t vertexStride = this->geometryProcessor()->getVertexStride(); size_t vertexStride = this->geometryProcessor()->getVertexStride();
SkASSERT(vertexStride == sizeof(Vertex)); SkASSERT(vertexStride == sizeof(Vertex));
GrDrawTarget::DrawInfo drawInfo;
Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1)); Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
if (!verts) { if (!verts) {
return; return;

View File

@ -207,6 +207,7 @@
'<(skia_src_path)/gpu/GrTextureAccess.cpp', '<(skia_src_path)/gpu/GrTextureAccess.cpp',
'<(skia_src_path)/gpu/GrTRecorder.h', '<(skia_src_path)/gpu/GrTRecorder.h',
'<(skia_src_path)/gpu/GrVertexBuffer.h', '<(skia_src_path)/gpu/GrVertexBuffer.h',
'<(skia_src_path)/gpu/GrVertices.h',
'<(skia_src_path)/gpu/GrXferProcessor.cpp', '<(skia_src_path)/gpu/GrXferProcessor.cpp',
'<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h', '<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h',

View File

@ -823,7 +823,7 @@ public:
SkSTArray<kPreallocDrawCnt, Draw, true> draws; SkSTArray<kPreallocDrawCnt, Draw, true> draws;
create_vertices(segments, fanPt, &draws, verts, idxs); create_vertices(segments, fanPt, &draws, verts, idxs);
GrDrawTarget::DrawInfo info; GrVertices info;
for (int i = 0; i < draws.count(); ++i) { for (int i = 0; i < draws.count(); ++i) {
const Draw& draw = draws[i]; const Draw& draw = draws[i];

View File

@ -507,15 +507,15 @@ private:
} }
void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) { void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
GrDrawTarget::DrawInfo drawInfo; GrVertices vertices;
int instancesToFlush = flushInfo->fInstancesToFlush; int instancesToFlush = flushInfo->fInstancesToFlush;
int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads(); int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads();
drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer, vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad, flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad,
kIndicesPerQuad, &instancesToFlush, maxInstancesPerDraw); kIndicesPerQuad, &instancesToFlush, maxInstancesPerDraw);
do { do {
batchTarget->draw(drawInfo); batchTarget->draw(vertices);
} while (drawInfo.nextInstances(&instancesToFlush, maxInstancesPerDraw)); } while (vertices.nextInstances(&instancesToFlush, maxInstancesPerDraw));
flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush; flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
flushInfo->fInstancesToFlush = 0; flushInfo->fInstancesToFlush = 0;
} }

View File

@ -889,7 +889,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
{ {
int linesLeft = lineCount; int linesLeft = lineCount;
GrDrawTarget::DrawInfo info; GrVertices info;
info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer, info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer,
firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft, firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft,
kLineSegsNumInIdxBuffer); kLineSegsNumInIdxBuffer);
@ -945,7 +945,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
{ {
int quadsLeft = quadCount; int quadsLeft = quadCount;
GrDrawTarget::DrawInfo info; GrVertices info;
info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer, info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft, firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft,
kQuadsNumInIdxBuffer); kQuadsNumInIdxBuffer);
@ -969,7 +969,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
{ {
int conicsLeft = conicCount; int conicsLeft = conicCount;
GrDrawTarget::DrawInfo info; GrVertices info;
info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer, info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft, firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft,
kQuadsNumInIdxBuffer); kQuadsNumInIdxBuffer);

View File

@ -1826,16 +1826,16 @@ private:
} }
void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) { void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
GrDrawTarget::DrawInfo drawInfo; GrVertices vertices;
int glyphsToFlush = flushInfo->fGlyphsToFlush; int glyphsToFlush = flushInfo->fGlyphsToFlush;
int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads(); int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer, vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
flushInfo->fIndexBuffer, flushInfo->fVertexOffset, flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlush, kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlush,
maxGlyphsPerDraw); maxGlyphsPerDraw);
do { do {
batchTarget->draw(drawInfo); batchTarget->draw(vertices);
} while (drawInfo.nextInstances(&glyphsToFlush, maxGlyphsPerDraw)); } while (vertices.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush; flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
flushInfo->fGlyphsToFlush = 0; flushInfo->fGlyphsToFlush = 0;
} }

View File

@ -69,7 +69,7 @@ void* GrBatch::InstancedHelper::init(GrBatchTarget* batchTarget, GrPrimitiveType
size_t ibSize = indexBuffer->gpuMemorySize(); size_t ibSize = indexBuffer->gpuMemorySize();
fMaxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance)); fMaxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
fDrawInfo.initInstanced(primType, vertexBuffer, indexBuffer, fVertices.initInstanced(primType, vertexBuffer, indexBuffer,
firstVertex, verticesPerInstance, indicesPerInstance, &fInstancesRemaining, firstVertex, verticesPerInstance, indicesPerInstance, &fInstancesRemaining,
fMaxInstancesPerDraw); fMaxInstancesPerDraw);
SkASSERT(fMaxInstancesPerDraw > 0); SkASSERT(fMaxInstancesPerDraw > 0);

View File

@ -9,10 +9,9 @@
#define GrBatch_DEFINED #define GrBatch_DEFINED
#include <new> #include <new>
// TODO remove this header when we move entirely to batch
#include "GrDrawTarget.h"
#include "GrBatchTarget.h" #include "GrBatchTarget.h"
#include "GrGeometryProcessor.h" #include "GrGeometryProcessor.h"
#include "GrVertices.h"
#include "SkRefCnt.h" #include "SkRefCnt.h"
#include "SkThread.h" #include "SkThread.h"
#include "SkTypes.h" #include "SkTypes.h"
@ -126,15 +125,15 @@ protected:
/** Call after init() to issue draws to the batch target.*/ /** Call after init() to issue draws to the batch target.*/
void issueDraws(GrBatchTarget* batchTarget) { void issueDraws(GrBatchTarget* batchTarget) {
SkASSERT(fDrawInfo.instanceCount()); SkASSERT(fVertices.instanceCount());
do { do {
batchTarget->draw(fDrawInfo); batchTarget->draw(fVertices);
} while (fDrawInfo.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw)); } while (fVertices.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
} }
private: private:
int fInstancesRemaining; int fInstancesRemaining;
int fMaxInstancesPerDraw; int fMaxInstancesPerDraw;
GrDrawTarget::DrawInfo fDrawInfo; GrVertices fVertices;
}; };
static const int kVerticesPerQuad = 4; static const int kVerticesPerQuad = 4;

View File

@ -46,10 +46,10 @@ void GrBatchTarget::flushNext(int n) {
GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker); GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);
int drawCount = bf->fDraws.count(); int drawCount = bf->fVertexDraws.count();
const SkSTArray<1, DrawInfo, true>& draws = bf->fDraws; const SkSTArray<1, GrVertices, true>& vertexDraws = bf->fVertexDraws;
for (int i = 0; i < drawCount; i++) { for (int i = 0; i < drawCount; i++) {
fGpu->draw(args, draws[i]); fGpu->draw(args, vertexDraws[i]);
} }
} }
} }

View File

@ -12,8 +12,8 @@
#include "GrBufferAllocPool.h" #include "GrBufferAllocPool.h"
#include "GrPendingProgramElement.h" #include "GrPendingProgramElement.h"
#include "GrPipeline.h" #include "GrPipeline.h"
#include "GrGpu.h"
#include "GrTRecorder.h" #include "GrTRecorder.h"
#include "GrVertices.h"
/* /*
* GrBatch instances use this object to allocate space for their geometry and to issue the draws * GrBatch instances use this object to allocate space for their geometry and to issue the draws
@ -30,7 +30,6 @@ public:
GrVertexBufferAllocPool* vpool, GrVertexBufferAllocPool* vpool,
GrIndexBufferAllocPool* ipool); GrIndexBufferAllocPool* ipool);
typedef GrDrawTarget::DrawInfo DrawInfo;
void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) { void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) {
GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline)); GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline));
fNumberOfDraws++; fNumberOfDraws++;
@ -83,8 +82,8 @@ public:
} }
} }
void draw(const GrDrawTarget::DrawInfo& draw) { void draw(const GrVertices& vertices) {
fFlushBuffer.back().fDraws.push_back(draw); fFlushBuffer.back().fVertexDraws.push_back(vertices);
} }
bool isIssued(BatchToken token) const { return fLastFlushedToken >= token; } bool isIssued(BatchToken token) const { return fLastFlushedToken >= token; }
@ -145,7 +144,7 @@ private:
ProgramPrimitiveProcessor fPrimitiveProcessor; ProgramPrimitiveProcessor fPrimitiveProcessor;
const GrPipeline* fPipeline; const GrPipeline* fPipeline;
GrBatchTracker fBatchTracker; GrBatchTracker fBatchTracker;
SkSTArray<1, DrawInfo, true> fDraws; SkSTArray<1, GrVertices, true> fVertexDraws;
}; };
enum { enum {

View File

@ -36,6 +36,7 @@
#include "GrTexturePriv.h" #include "GrTexturePriv.h"
#include "GrTraceMarker.h" #include "GrTraceMarker.h"
#include "GrTracing.h" #include "GrTracing.h"
#include "GrVertices.h"
#include "SkDashPathPriv.h" #include "SkDashPathPriv.h"
#include "SkConfig8888.h" #include "SkConfig8888.h"
#include "SkGr.h" #include "SkGr.h"
@ -473,17 +474,17 @@ public:
const GrVertexBuffer* vertexBuffer; const GrVertexBuffer* vertexBuffer;
int firstVertex; int firstVertex;
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
vertexCount, vertexCount,
&vertexBuffer, &vertexBuffer,
&firstVertex); &firstVertex);
if (!vertices) { if (!verts) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;
} }
SkPoint* vertex = reinterpret_cast<SkPoint*>(vertices); SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
GrPrimitiveType primType; GrPrimitiveType primType;
@ -501,9 +502,9 @@ public:
vertex[4].set(args.fRect.fLeft, args.fRect.fTop); vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
} }
GrDrawTarget::DrawInfo drawInfo; GrVertices vertices;
drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount); vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
batchTarget->draw(drawInfo); batchTarget->draw(vertices);
} }
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
@ -811,12 +812,12 @@ public:
const GrVertexBuffer* vertexBuffer; const GrVertexBuffer* vertexBuffer;
int firstVertex; int firstVertex;
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
this->vertexCount(), this->vertexCount(),
&vertexBuffer, &vertexBuffer,
&firstVertex); &firstVertex);
if (!vertices) { if (!verts) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;
} }
@ -849,27 +850,27 @@ public:
} }
for (int j = 0; j < args.fPositions.count(); ++j) { for (int j = 0; j < args.fPositions.count(); ++j) {
*((SkPoint*)vertices) = args.fPositions[j]; *((SkPoint*)verts) = args.fPositions[j];
if (this->hasColors()) { if (this->hasColors()) {
*(GrColor*)((intptr_t)vertices + colorOffset) = args.fColors[j]; *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
} }
if (this->hasLocalCoords()) { if (this->hasLocalCoords()) {
*(SkPoint*)((intptr_t)vertices + texOffset) = args.fLocalCoords[j]; *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j];
} }
vertices = (void*)((intptr_t)vertices + vertexStride); verts = (void*)((intptr_t)verts + vertexStride);
vertexOffset++; vertexOffset++;
} }
} }
GrDrawTarget::DrawInfo drawInfo; GrVertices vertices;
if (this->hasIndices()) { if (this->hasIndices()) {
drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex, vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
firstIndex, this->vertexCount(), this->indexCount()); firstIndex, this->vertexCount(), this->indexCount());
} else { } else {
drawInfo.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount()); vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
} }
batchTarget->draw(drawInfo); batchTarget->draw(vertices);
} }
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }

View File

@ -14,7 +14,7 @@
#include "GrDefaultGeoProcFactory.h" #include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h" #include "GrPathUtils.h"
#include "GrPipelineBuilder.h" #include "GrPipelineBuilder.h"
#include "GrVertexBuffer.h" #include "GrVertices.h"
#include "SkGeometry.h" #include "SkGeometry.h"
#include "SkString.h" #include "SkString.h"
#include "SkStrokeRec.h" #include "SkStrokeRec.h"
@ -319,12 +319,12 @@ public:
const GrVertexBuffer* vertexBuffer; const GrVertexBuffer* vertexBuffer;
int firstVertex; int firstVertex;
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
maxVertices, maxVertices,
&vertexBuffer, &vertexBuffer,
&firstVertex); &firstVertex);
if (!vertices) { if (!verts) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;
} }
@ -352,7 +352,7 @@ public:
int vertexCnt = 0; int vertexCnt = 0;
int indexCnt = 0; int indexCnt = 0;
if (!this->createGeom(vertices, if (!this->createGeom(verts,
vertexOffset, vertexOffset,
indices, indices,
indexOffset, indexOffset,
@ -369,14 +369,14 @@ public:
SkASSERT(vertexOffset <= maxVertices && indexOffset <= maxIndices); SkASSERT(vertexOffset <= maxVertices && indexOffset <= maxIndices);
} }
GrDrawTarget::DrawInfo drawInfo; GrVertices vertices;
if (isIndexed) { if (isIndexed) {
drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex, vertices.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
vertexOffset, indexOffset); vertexOffset, indexOffset);
} else { } else {
drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset); vertices.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
} }
batchTarget->draw(drawInfo); batchTarget->draw(vertices);
// put back reserves // put back reserves
batchTarget->putBackIndices((size_t)(maxIndices - indexOffset)); batchTarget->putBackIndices((size_t)(maxIndices - indexOffset));

View File

@ -26,25 +26,6 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
fPrimitiveType = di.fPrimitiveType;
fStartVertex = di.fStartVertex;
fStartIndex = di.fStartIndex;
fVertexCount = di.fVertexCount;
fIndexCount = di.fIndexCount;
fInstanceCount = di.fInstanceCount;
fVerticesPerInstance = di.fVerticesPerInstance;
fIndicesPerInstance = di.fIndicesPerInstance;
fVertexBuffer.reset(di.vertexBuffer());
fIndexBuffer.reset(di.indexBuffer());
return *this;
}
////////////////////////////////////////////////////////////////////////////////
#define DEBUG_INVAL_BUFFER 0xdeadcafe #define DEBUG_INVAL_BUFFER 0xdeadcafe
#define DEBUG_INVAL_START_IDX -1 #define DEBUG_INVAL_START_IDX -1

View File

@ -224,152 +224,6 @@ public:
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); } virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
/**
* Used to communicate draw index vertex offsets and counts toto GPUs / subclasses
*/
class DrawInfo {
public:
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; }
bool isIndexed() const { return fIndexCount > 0; }
bool isInstanced() const { return fInstanceCount > 0; }
/** 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(); }
private:
friend class GrDrawTarget;
GrPrimitiveType fPrimitiveType;
int fStartVertex;
int fStartIndex;
int fVertexCount;
int fIndexCount;
int fInstanceCount;
int fVerticesPerInstance;
int fIndicesPerInstance;
GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer;
};
bool programUnitTest(int maxStages); bool programUnitTest(int maxStages);
protected: protected:

View File

@ -18,6 +18,24 @@
#include "GrRenderTargetPriv.h" #include "GrRenderTargetPriv.h"
#include "GrStencilAttachment.h" #include "GrStencilAttachment.h"
#include "GrVertexBuffer.h" #include "GrVertexBuffer.h"
#include "GrVertices.h"
GrVertices& GrVertices::operator =(const GrVertices& di) {
fPrimitiveType = di.fPrimitiveType;
fStartVertex = di.fStartVertex;
fStartIndex = di.fStartIndex;
fVertexCount = di.fVertexCount;
fIndexCount = di.fIndexCount;
fInstanceCount = di.fInstanceCount;
fVerticesPerInstance = di.fVerticesPerInstance;
fIndicesPerInstance = di.fIndicesPerInstance;
fVertexBuffer.reset(di.vertexBuffer());
fIndexBuffer.reset(di.indexBuffer());
return *this;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -269,9 +287,9 @@ void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void GrGpu::draw(const DrawArgs& args, const GrDrawTarget::DrawInfo& info) { void GrGpu::draw(const DrawArgs& args, const GrVertices& vertices) {
this->handleDirtyContext(); this->handleDirtyContext();
this->onDraw(args, info); this->onDraw(args, vertices);
} }
void GrGpu::stencilPath(const GrPath* path, const StencilPathState& state) { void GrGpu::stencilPath(const GrPath* path, const StencilPathState& state) {

View File

@ -23,6 +23,7 @@ class GrPipeline;
class GrPrimitiveProcessor; class GrPrimitiveProcessor;
class GrStencilAttachment; class GrStencilAttachment;
class GrVertexBufferAllocPool; class GrVertexBufferAllocPool;
class GrVertices;
class GrGpu : public SkRefCnt { class GrGpu : public SkRefCnt {
public: public:
@ -280,7 +281,6 @@ public:
virtual void xferBarrier(GrXferBarrierType) = 0; virtual void xferBarrier(GrXferBarrierType) = 0;
struct DrawArgs { struct DrawArgs {
typedef GrDrawTarget::DrawInfo DrawInfo;
DrawArgs(const GrPrimitiveProcessor* primProc, DrawArgs(const GrPrimitiveProcessor* primProc,
const GrPipeline* pipeline, const GrPipeline* pipeline,
const GrProgramDesc* desc, const GrProgramDesc* desc,
@ -297,7 +297,7 @@ public:
const GrBatchTracker* fBatchTracker; const GrBatchTracker* fBatchTracker;
}; };
void draw(const DrawArgs&, const GrDrawTarget::DrawInfo&); void draw(const DrawArgs&, const GrVertices&);
/** None of these params are optional, pointers used just to avoid making copies. */ /** None of these params are optional, pointers used just to avoid making copies. */
struct StencilPathState { struct StencilPathState {
@ -435,7 +435,7 @@ private:
virtual void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0; virtual void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0;
// overridden by backend-specific derived class to perform the draw call. // overridden by backend-specific derived class to perform the draw call.
virtual void onDraw(const DrawArgs&, const GrDrawTarget::DrawInfo&) = 0; virtual void onDraw(const DrawArgs&, const GrVertices&) = 0;
virtual void onStencilPath(const GrPath*, const StencilPathState&) = 0; virtual void onStencilPath(const GrPath*, const StencilPathState&) = 0;
virtual void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) = 0; virtual void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) = 0;

View File

@ -11,7 +11,7 @@
#include "GrBatchTarget.h" #include "GrBatchTarget.h"
#include "GrDefaultGeoProcFactory.h" #include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h" #include "GrPathUtils.h"
#include "GrVertexBuffer.h" #include "GrVertices.h"
#include "SkChunkAlloc.h" #include "SkChunkAlloc.h"
#include "SkGeometry.h" #include "SkGeometry.h"
@ -1439,28 +1439,28 @@ public:
size_t stride = gp->getVertexStride(); size_t stride = gp->getVertexStride();
const GrVertexBuffer* vertexBuffer; const GrVertexBuffer* vertexBuffer;
int firstVertex; int firstVertex;
void* vertices = batchTarget->vertexPool()->makeSpace(stride, void* verts = batchTarget->vertexPool()->makeSpace(stride,
count, count,
&vertexBuffer, &vertexBuffer,
&firstVertex); &firstVertex);
if (!vertices) { if (!verts) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;
} }
LOG("emitting %d verts\n", count); LOG("emitting %d verts\n", count);
void* end = polys_to_triangles(polys, fillType, vertices); void* end = polys_to_triangles(polys, fillType, verts);
int actualCount = static_cast<int>( int actualCount = static_cast<int>(
(static_cast<char*>(end) - static_cast<char*>(vertices)) / stride); (static_cast<char*>(end) - static_cast<char*>(verts)) / stride);
LOG("actual count: %d\n", actualCount); LOG("actual count: %d\n", actualCount);
SkASSERT(actualCount <= count); SkASSERT(actualCount <= count);
GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
: kTriangles_GrPrimitiveType; : kTriangles_GrPrimitiveType;
GrDrawTarget::DrawInfo drawInfo; GrVertices vertices;
drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount); vertices.init(primitiveType, vertexBuffer, firstVertex, actualCount);
batchTarget->draw(drawInfo); batchTarget->draw(vertices);
batchTarget->putBackVertices((size_t)(count - actualCount), stride); batchTarget->putBackVertices((size_t)(count - actualCount), stride);
return; return;

View File

@ -200,7 +200,7 @@ private:
void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {} void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) override {}
void onDraw(const DrawArgs&, const GrDrawTarget::DrawInfo&) override {} void onDraw(const DrawArgs&, const GrVertices&) override {}
void onStencilPath(const GrPath* path, const StencilPathState& state) override {} void onStencilPath(const GrPath* path, const StencilPathState& state) override {}

161
src/gpu/GrVertices.h Normal file
View File

@ -0,0 +1,161 @@
/*
* Copyright 2015 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrVertices_DEFINED
#define GrVertices_DEFINED
#include "GrIndexBuffer.h"
#include "GrVertexBuffer.h"
/**
* Used to communicate index and vertex buffers, counts, and offsets for a draw from GrBatch to
* GrGpu. It also holds the primitive type for the draw. TODO: Consider moving ownership of this
* and draw-issuing responsibility to GrPrimitiveProcessor. The rest of the vertex info lives there
* already (stride, attribute mappings).
*/
class GrVertices {
public:
GrVertices() {}
GrVertices(const GrVertices& di) { (*this) = di; }
GrVertices& operator =(const GrVertices& 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 GrVertices. */
int verticesPerInstance() const { return fVerticesPerInstance; }
int indicesPerInstance() const { return fIndicesPerInstance; }
int instanceCount() const { return fInstanceCount; }
bool isIndexed() const { return fIndexCount > 0; }
bool isInstanced() const { return fInstanceCount > 0; }
/** 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 GrVertices 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(); }
private:
GrPrimitiveType fPrimitiveType;
int fStartVertex;
int fStartIndex;
int fVertexCount;
int fIndexCount;
int fInstanceCount;
int fVerticesPerInstance;
int fIndicesPerInstance;
GrPendingIOResource<const GrVertexBuffer, kRead_GrIOType> fVertexBuffer;
GrPendingIOResource<const GrIndexBuffer, kRead_GrIOType> fIndexBuffer;
};
#endif

View File

@ -16,6 +16,7 @@
#include "GrTemplates.h" #include "GrTemplates.h"
#include "GrTexturePriv.h" #include "GrTexturePriv.h"
#include "GrTypes.h" #include "GrTypes.h"
#include "GrVertices.h"
#include "SkStrokeRec.h" #include "SkStrokeRec.h"
#include "SkTemplates.h" #include "SkTemplates.h"
@ -1408,7 +1409,7 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
} }
void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
const GrDrawTarget::DrawInfo& info, const GrVertices& info,
size_t* indexOffsetInBytes) { size_t* indexOffsetInBytes) {
GrGLVertexBuffer* vbuf; GrGLVertexBuffer* vbuf;
vbuf = (GrGLVertexBuffer*) info.vertexBuffer(); vbuf = (GrGLVertexBuffer*) info.vertexBuffer();
@ -1851,29 +1852,31 @@ GrGLenum gPrimitiveType2GLMode[] = {
#endif #endif
#endif #endif
void GrGLGpu::onDraw(const DrawArgs& args, const GrDrawTarget::DrawInfo& info) { void GrGLGpu::onDraw(const DrawArgs& args, const GrVertices& vertices) {
if (!this->flushGLState(args)) { if (!this->flushGLState(args)) {
return; return;
} }
size_t indexOffsetInBytes = 0; size_t indexOffsetInBytes = 0;
this->setupGeometry(*args.fPrimitiveProcessor, info, &indexOffsetInBytes); this->setupGeometry(*args.fPrimitiveProcessor, vertices, &indexOffsetInBytes);
SkASSERT((size_t)info.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode)); SkASSERT((size_t)vertices.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GLMode));
if (info.isIndexed()) { if (vertices.isIndexed()) {
GrGLvoid* indices = GrGLvoid* indices =
reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) * info.startIndex()); reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) *
vertices.startIndex());
// info.startVertex() was accounted for by setupGeometry. // info.startVertex() was accounted for by setupGeometry.
GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()], GL_CALL(DrawElements(gPrimitiveType2GLMode[vertices.primitiveType()],
info.indexCount(), vertices.indexCount(),
GR_GL_UNSIGNED_SHORT, GR_GL_UNSIGNED_SHORT,
indices)); indices));
} else { } else {
// Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for // Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for
// startVertex in the DrawElements case. So we always rely on setupGeometry to have // startVertex in the DrawElements case. So we always rely on setupGeometry to have
// accounted for startVertex. // accounted for startVertex.
GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount())); GL_CALL(DrawArrays(gPrimitiveType2GLMode[vertices.primitiveType()], 0,
vertices.vertexCount()));
} }
#if SWAP_PER_DRAW #if SWAP_PER_DRAW
glFlush(); glFlush();

View File

@ -24,6 +24,7 @@
#include "SkTypes.h" #include "SkTypes.h"
class GrPipeline; class GrPipeline;
class GrVertices;
#ifdef SK_DEVELOPER #ifdef SK_DEVELOPER
#define PROGRAM_CACHE_STATS #define PROGRAM_CACHE_STATS
@ -148,7 +149,7 @@ private:
void onResolveRenderTarget(GrRenderTarget* target) override; void onResolveRenderTarget(GrRenderTarget* target) override;
void onDraw(const DrawArgs&, const GrDrawTarget::DrawInfo&) override; void onDraw(const DrawArgs&, const GrVertices&) override;
void onStencilPath(const GrPath*, const StencilPathState&) override; void onStencilPath(const GrPath*, const StencilPathState&) override;
void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override; void onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override;
void onDrawPaths(const DrawArgs&, void onDrawPaths(const DrawArgs&,
@ -173,10 +174,10 @@ private:
bool flushGLState(const DrawArgs&); bool flushGLState(const DrawArgs&);
// Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset // Sets up vertex attribute pointers and strides. On return indexOffsetInBytes gives the offset
// an into the index buffer. It does not account for drawInfo.startIndex() but rather the start // an into the index buffer. It does not account for vertices.startIndex() but rather the start
// index is relative to the returned offset. // index is relative to the returned offset.
void setupGeometry(const GrPrimitiveProcessor&, void setupGeometry(const GrPrimitiveProcessor&,
const GrDrawTarget::DrawInfo& info, const GrVertices& vertices,
size_t* indexOffsetInBytes); size_t* indexOffsetInBytes);
// Subclasses should call this to flush the blend state. // Subclasses should call this to flush the blend state.