Move DrawInfo out from GrDrawTarget and rename to GrVertices.
Review URL: https://codereview.chromium.org/1124733004
This commit is contained in:
parent
e46760e8b2
commit
cb8979d088
@ -457,7 +457,6 @@ private:
|
||||
QuadHelper helper;
|
||||
size_t vertexStride = this->geometryProcessor()->getVertexStride();
|
||||
SkASSERT(vertexStride == sizeof(Vertex));
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
Vertex* verts = reinterpret_cast<Vertex*>(helper.init(batchTarget, vertexStride, 1));
|
||||
if (!verts) {
|
||||
return;
|
||||
|
@ -207,6 +207,7 @@
|
||||
'<(skia_src_path)/gpu/GrTextureAccess.cpp',
|
||||
'<(skia_src_path)/gpu/GrTRecorder.h',
|
||||
'<(skia_src_path)/gpu/GrVertexBuffer.h',
|
||||
'<(skia_src_path)/gpu/GrVertices.h',
|
||||
'<(skia_src_path)/gpu/GrXferProcessor.cpp',
|
||||
|
||||
'<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h',
|
||||
|
@ -823,7 +823,7 @@ public:
|
||||
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
|
||||
create_vertices(segments, fanPt, &draws, verts, idxs);
|
||||
|
||||
GrDrawTarget::DrawInfo info;
|
||||
GrVertices info;
|
||||
|
||||
for (int i = 0; i < draws.count(); ++i) {
|
||||
const Draw& draw = draws[i];
|
||||
|
@ -507,15 +507,15 @@ private:
|
||||
}
|
||||
|
||||
void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
GrVertices vertices;
|
||||
int instancesToFlush = flushInfo->fInstancesToFlush;
|
||||
int maxInstancesPerDraw = flushInfo->fIndexBuffer->maxQuads();
|
||||
drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
|
||||
vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
|
||||
flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad,
|
||||
kIndicesPerQuad, &instancesToFlush, maxInstancesPerDraw);
|
||||
do {
|
||||
batchTarget->draw(drawInfo);
|
||||
} while (drawInfo.nextInstances(&instancesToFlush, maxInstancesPerDraw));
|
||||
batchTarget->draw(vertices);
|
||||
} while (vertices.nextInstances(&instancesToFlush, maxInstancesPerDraw));
|
||||
flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
|
||||
flushInfo->fInstancesToFlush = 0;
|
||||
}
|
||||
|
@ -889,7 +889,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
|
||||
|
||||
{
|
||||
int linesLeft = lineCount;
|
||||
GrDrawTarget::DrawInfo info;
|
||||
GrVertices info;
|
||||
info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, linesIndexBuffer,
|
||||
firstVertex, kLineSegNumVertices, kIdxsPerLineSeg, &linesLeft,
|
||||
kLineSegsNumInIdxBuffer);
|
||||
@ -945,7 +945,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
|
||||
|
||||
{
|
||||
int quadsLeft = quadCount;
|
||||
GrDrawTarget::DrawInfo info;
|
||||
GrVertices info;
|
||||
info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
|
||||
firstVertex, kQuadNumVertices, kIdxsPerQuad, &quadsLeft,
|
||||
kQuadsNumInIdxBuffer);
|
||||
@ -969,7 +969,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
|
||||
|
||||
{
|
||||
int conicsLeft = conicCount;
|
||||
GrDrawTarget::DrawInfo info;
|
||||
GrVertices info;
|
||||
info.initInstanced(kTriangles_GrPrimitiveType, vertexBuffer, quadsIndexBuffer,
|
||||
firstVertex, kQuadNumVertices, kIdxsPerQuad, &conicsLeft,
|
||||
kQuadsNumInIdxBuffer);
|
||||
|
@ -1826,16 +1826,16 @@ private:
|
||||
}
|
||||
|
||||
void flush(GrBatchTarget* batchTarget, FlushInfo* flushInfo) {
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
GrVertices vertices;
|
||||
int glyphsToFlush = flushInfo->fGlyphsToFlush;
|
||||
int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
|
||||
drawInfo.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
|
||||
vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer,
|
||||
flushInfo->fIndexBuffer, flushInfo->fVertexOffset,
|
||||
kVerticesPerGlyph, kIndicesPerGlyph, &glyphsToFlush,
|
||||
maxGlyphsPerDraw);
|
||||
do {
|
||||
batchTarget->draw(drawInfo);
|
||||
} while (drawInfo.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
|
||||
batchTarget->draw(vertices);
|
||||
} while (vertices.nextInstances(&glyphsToFlush, maxGlyphsPerDraw));
|
||||
flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
|
||||
flushInfo->fGlyphsToFlush = 0;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ void* GrBatch::InstancedHelper::init(GrBatchTarget* batchTarget, GrPrimitiveType
|
||||
size_t ibSize = indexBuffer->gpuMemorySize();
|
||||
fMaxInstancesPerDraw = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerInstance));
|
||||
|
||||
fDrawInfo.initInstanced(primType, vertexBuffer, indexBuffer,
|
||||
fVertices.initInstanced(primType, vertexBuffer, indexBuffer,
|
||||
firstVertex, verticesPerInstance, indicesPerInstance, &fInstancesRemaining,
|
||||
fMaxInstancesPerDraw);
|
||||
SkASSERT(fMaxInstancesPerDraw > 0);
|
||||
|
@ -9,10 +9,9 @@
|
||||
#define GrBatch_DEFINED
|
||||
|
||||
#include <new>
|
||||
// TODO remove this header when we move entirely to batch
|
||||
#include "GrDrawTarget.h"
|
||||
#include "GrBatchTarget.h"
|
||||
#include "GrGeometryProcessor.h"
|
||||
#include "GrVertices.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkThread.h"
|
||||
#include "SkTypes.h"
|
||||
@ -126,15 +125,15 @@ protected:
|
||||
|
||||
/** Call after init() to issue draws to the batch target.*/
|
||||
void issueDraws(GrBatchTarget* batchTarget) {
|
||||
SkASSERT(fDrawInfo.instanceCount());
|
||||
SkASSERT(fVertices.instanceCount());
|
||||
do {
|
||||
batchTarget->draw(fDrawInfo);
|
||||
} while (fDrawInfo.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
|
||||
batchTarget->draw(fVertices);
|
||||
} while (fVertices.nextInstances(&fInstancesRemaining, fMaxInstancesPerDraw));
|
||||
}
|
||||
private:
|
||||
int fInstancesRemaining;
|
||||
int fMaxInstancesPerDraw;
|
||||
GrDrawTarget::DrawInfo fDrawInfo;
|
||||
GrVertices fVertices;
|
||||
};
|
||||
|
||||
static const int kVerticesPerQuad = 4;
|
||||
|
@ -46,10 +46,10 @@ void GrBatchTarget::flushNext(int n) {
|
||||
|
||||
GrGpu::DrawArgs args(primProc, pipeline, &desc, &bf->fBatchTracker);
|
||||
|
||||
int drawCount = bf->fDraws.count();
|
||||
const SkSTArray<1, DrawInfo, true>& draws = bf->fDraws;
|
||||
int drawCount = bf->fVertexDraws.count();
|
||||
const SkSTArray<1, GrVertices, true>& vertexDraws = bf->fVertexDraws;
|
||||
for (int i = 0; i < drawCount; i++) {
|
||||
fGpu->draw(args, draws[i]);
|
||||
fGpu->draw(args, vertexDraws[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "GrBufferAllocPool.h"
|
||||
#include "GrPendingProgramElement.h"
|
||||
#include "GrPipeline.h"
|
||||
#include "GrGpu.h"
|
||||
#include "GrTRecorder.h"
|
||||
#include "GrVertices.h"
|
||||
|
||||
/*
|
||||
* GrBatch instances use this object to allocate space for their geometry and to issue the draws
|
||||
@ -30,7 +30,6 @@ public:
|
||||
GrVertexBufferAllocPool* vpool,
|
||||
GrIndexBufferAllocPool* ipool);
|
||||
|
||||
typedef GrDrawTarget::DrawInfo DrawInfo;
|
||||
void initDraw(const GrPrimitiveProcessor* primProc, const GrPipeline* pipeline) {
|
||||
GrNEW_APPEND_TO_RECORDER(fFlushBuffer, BufferedFlush, (primProc, pipeline));
|
||||
fNumberOfDraws++;
|
||||
@ -83,8 +82,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void draw(const GrDrawTarget::DrawInfo& draw) {
|
||||
fFlushBuffer.back().fDraws.push_back(draw);
|
||||
void draw(const GrVertices& vertices) {
|
||||
fFlushBuffer.back().fVertexDraws.push_back(vertices);
|
||||
}
|
||||
|
||||
bool isIssued(BatchToken token) const { return fLastFlushedToken >= token; }
|
||||
@ -145,7 +144,7 @@ private:
|
||||
ProgramPrimitiveProcessor fPrimitiveProcessor;
|
||||
const GrPipeline* fPipeline;
|
||||
GrBatchTracker fBatchTracker;
|
||||
SkSTArray<1, DrawInfo, true> fDraws;
|
||||
SkSTArray<1, GrVertices, true> fVertexDraws;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "GrTexturePriv.h"
|
||||
#include "GrTraceMarker.h"
|
||||
#include "GrTracing.h"
|
||||
#include "GrVertices.h"
|
||||
#include "SkDashPathPriv.h"
|
||||
#include "SkConfig8888.h"
|
||||
#include "SkGr.h"
|
||||
@ -473,17 +474,17 @@ public:
|
||||
const GrVertexBuffer* vertexBuffer;
|
||||
int firstVertex;
|
||||
|
||||
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
||||
void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
|
||||
vertexCount,
|
||||
&vertexBuffer,
|
||||
&firstVertex);
|
||||
|
||||
if (!vertices) {
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
}
|
||||
|
||||
SkPoint* vertex = reinterpret_cast<SkPoint*>(vertices);
|
||||
SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
|
||||
|
||||
GrPrimitiveType primType;
|
||||
|
||||
@ -501,9 +502,9 @@ public:
|
||||
vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
|
||||
}
|
||||
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
drawInfo.init(primType, vertexBuffer, firstVertex, vertexCount);
|
||||
batchTarget->draw(drawInfo);
|
||||
GrVertices vertices;
|
||||
vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
|
||||
batchTarget->draw(vertices);
|
||||
}
|
||||
|
||||
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
|
||||
@ -811,12 +812,12 @@ public:
|
||||
const GrVertexBuffer* vertexBuffer;
|
||||
int firstVertex;
|
||||
|
||||
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
||||
void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
|
||||
this->vertexCount(),
|
||||
&vertexBuffer,
|
||||
&firstVertex);
|
||||
|
||||
if (!vertices) {
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
}
|
||||
@ -849,27 +850,27 @@ public:
|
||||
}
|
||||
|
||||
for (int j = 0; j < args.fPositions.count(); ++j) {
|
||||
*((SkPoint*)vertices) = args.fPositions[j];
|
||||
*((SkPoint*)verts) = args.fPositions[j];
|
||||
if (this->hasColors()) {
|
||||
*(GrColor*)((intptr_t)vertices + colorOffset) = args.fColors[j];
|
||||
*(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
|
||||
}
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
GrVertices vertices;
|
||||
if (this->hasIndices()) {
|
||||
drawInfo.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
|
||||
vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
|
||||
firstIndex, this->vertexCount(), this->indexCount());
|
||||
|
||||
} 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; }
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "GrDefaultGeoProcFactory.h"
|
||||
#include "GrPathUtils.h"
|
||||
#include "GrPipelineBuilder.h"
|
||||
#include "GrVertexBuffer.h"
|
||||
#include "GrVertices.h"
|
||||
#include "SkGeometry.h"
|
||||
#include "SkString.h"
|
||||
#include "SkStrokeRec.h"
|
||||
@ -319,12 +319,12 @@ public:
|
||||
const GrVertexBuffer* vertexBuffer;
|
||||
int firstVertex;
|
||||
|
||||
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
||||
void* verts = batchTarget->vertexPool()->makeSpace(vertexStride,
|
||||
maxVertices,
|
||||
&vertexBuffer,
|
||||
&firstVertex);
|
||||
|
||||
if (!vertices) {
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
}
|
||||
@ -352,7 +352,7 @@ public:
|
||||
|
||||
int vertexCnt = 0;
|
||||
int indexCnt = 0;
|
||||
if (!this->createGeom(vertices,
|
||||
if (!this->createGeom(verts,
|
||||
vertexOffset,
|
||||
indices,
|
||||
indexOffset,
|
||||
@ -369,14 +369,14 @@ public:
|
||||
SkASSERT(vertexOffset <= maxVertices && indexOffset <= maxIndices);
|
||||
}
|
||||
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
GrVertices vertices;
|
||||
if (isIndexed) {
|
||||
drawInfo.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
|
||||
vertices.initIndexed(primitiveType, vertexBuffer, indexBuffer, firstVertex, firstIndex,
|
||||
vertexOffset, indexOffset);
|
||||
} else {
|
||||
drawInfo.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
|
||||
vertices.init(primitiveType, vertexBuffer, firstVertex, vertexOffset);
|
||||
}
|
||||
batchTarget->draw(drawInfo);
|
||||
batchTarget->draw(vertices);
|
||||
|
||||
// put back reserves
|
||||
batchTarget->putBackIndices((size_t)(maxIndices - indexOffset));
|
||||
|
@ -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_START_IDX -1
|
||||
|
||||
|
@ -224,152 +224,6 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
|
@ -18,6 +18,24 @@
|
||||
#include "GrRenderTargetPriv.h"
|
||||
#include "GrStencilAttachment.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->onDraw(args, info);
|
||||
this->onDraw(args, vertices);
|
||||
}
|
||||
|
||||
void GrGpu::stencilPath(const GrPath* path, const StencilPathState& state) {
|
||||
|
@ -23,6 +23,7 @@ class GrPipeline;
|
||||
class GrPrimitiveProcessor;
|
||||
class GrStencilAttachment;
|
||||
class GrVertexBufferAllocPool;
|
||||
class GrVertices;
|
||||
|
||||
class GrGpu : public SkRefCnt {
|
||||
public:
|
||||
@ -280,7 +281,6 @@ public:
|
||||
virtual void xferBarrier(GrXferBarrierType) = 0;
|
||||
|
||||
struct DrawArgs {
|
||||
typedef GrDrawTarget::DrawInfo DrawInfo;
|
||||
DrawArgs(const GrPrimitiveProcessor* primProc,
|
||||
const GrPipeline* pipeline,
|
||||
const GrProgramDesc* desc,
|
||||
@ -297,7 +297,7 @@ public:
|
||||
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. */
|
||||
struct StencilPathState {
|
||||
@ -435,7 +435,7 @@ private:
|
||||
virtual void onClearStencilClip(GrRenderTarget*, const SkIRect& rect, bool insideClip) = 0;
|
||||
|
||||
// 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 onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) = 0;
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "GrBatchTarget.h"
|
||||
#include "GrDefaultGeoProcFactory.h"
|
||||
#include "GrPathUtils.h"
|
||||
#include "GrVertexBuffer.h"
|
||||
#include "GrVertices.h"
|
||||
#include "SkChunkAlloc.h"
|
||||
#include "SkGeometry.h"
|
||||
|
||||
@ -1439,28 +1439,28 @@ public:
|
||||
size_t stride = gp->getVertexStride();
|
||||
const GrVertexBuffer* vertexBuffer;
|
||||
int firstVertex;
|
||||
void* vertices = batchTarget->vertexPool()->makeSpace(stride,
|
||||
void* verts = batchTarget->vertexPool()->makeSpace(stride,
|
||||
count,
|
||||
&vertexBuffer,
|
||||
&firstVertex);
|
||||
|
||||
if (!vertices) {
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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>(
|
||||
(static_cast<char*>(end) - static_cast<char*>(vertices)) / stride);
|
||||
(static_cast<char*>(end) - static_cast<char*>(verts)) / stride);
|
||||
LOG("actual count: %d\n", actualCount);
|
||||
SkASSERT(actualCount <= count);
|
||||
|
||||
GrPrimitiveType primitiveType = WIREFRAME ? kLines_GrPrimitiveType
|
||||
: kTriangles_GrPrimitiveType;
|
||||
GrDrawTarget::DrawInfo drawInfo;
|
||||
drawInfo.init(primitiveType, vertexBuffer, firstVertex, actualCount);
|
||||
batchTarget->draw(drawInfo);
|
||||
GrVertices vertices;
|
||||
vertices.init(primitiveType, vertexBuffer, firstVertex, actualCount);
|
||||
batchTarget->draw(vertices);
|
||||
|
||||
batchTarget->putBackVertices((size_t)(count - actualCount), stride);
|
||||
return;
|
||||
|
@ -200,7 +200,7 @@ private:
|
||||
|
||||
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 {}
|
||||
|
||||
|
161
src/gpu/GrVertices.h
Normal file
161
src/gpu/GrVertices.h
Normal 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
|
@ -16,6 +16,7 @@
|
||||
#include "GrTemplates.h"
|
||||
#include "GrTexturePriv.h"
|
||||
#include "GrTypes.h"
|
||||
#include "GrVertices.h"
|
||||
#include "SkStrokeRec.h"
|
||||
#include "SkTemplates.h"
|
||||
|
||||
@ -1408,7 +1409,7 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
|
||||
}
|
||||
|
||||
void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
|
||||
const GrDrawTarget::DrawInfo& info,
|
||||
const GrVertices& info,
|
||||
size_t* indexOffsetInBytes) {
|
||||
GrGLVertexBuffer* vbuf;
|
||||
vbuf = (GrGLVertexBuffer*) info.vertexBuffer();
|
||||
@ -1851,29 +1852,31 @@ GrGLenum gPrimitiveType2GLMode[] = {
|
||||
#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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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 =
|
||||
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.
|
||||
GL_CALL(DrawElements(gPrimitiveType2GLMode[info.primitiveType()],
|
||||
info.indexCount(),
|
||||
GL_CALL(DrawElements(gPrimitiveType2GLMode[vertices.primitiveType()],
|
||||
vertices.indexCount(),
|
||||
GR_GL_UNSIGNED_SHORT,
|
||||
indices));
|
||||
} else {
|
||||
// Pass 0 for parameter first. We have to adjust glVertexAttribPointer() to account for
|
||||
// startVertex in the DrawElements case. So we always rely on setupGeometry to have
|
||||
// accounted for startVertex.
|
||||
GL_CALL(DrawArrays(gPrimitiveType2GLMode[info.primitiveType()], 0, info.vertexCount()));
|
||||
GL_CALL(DrawArrays(gPrimitiveType2GLMode[vertices.primitiveType()], 0,
|
||||
vertices.vertexCount()));
|
||||
}
|
||||
#if SWAP_PER_DRAW
|
||||
glFlush();
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "SkTypes.h"
|
||||
|
||||
class GrPipeline;
|
||||
class GrVertices;
|
||||
|
||||
#ifdef SK_DEVELOPER
|
||||
#define PROGRAM_CACHE_STATS
|
||||
@ -148,7 +149,7 @@ private:
|
||||
|
||||
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 onDrawPath(const DrawArgs&, const GrPath*, const GrStencilSettings&) override;
|
||||
void onDrawPaths(const DrawArgs&,
|
||||
@ -173,10 +174,10 @@ private:
|
||||
bool flushGLState(const DrawArgs&);
|
||||
|
||||
// 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.
|
||||
void setupGeometry(const GrPrimitiveProcessor&,
|
||||
const GrDrawTarget::DrawInfo& info,
|
||||
const GrVertices& vertices,
|
||||
size_t* indexOffsetInBytes);
|
||||
|
||||
// Subclasses should call this to flush the blend state.
|
||||
|
Loading…
Reference in New Issue
Block a user