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;
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;

View File

@ -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',

View File

@ -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];

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
int fInstancesRemaining;
int fMaxInstancesPerDraw;
GrVertices fVertices;
};
static const int kVerticesPerQuad = 4;

View File

@ -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]);
}
}
}

View File

@ -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 {

View File

@ -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,
vertexCount,
&vertexBuffer,
&firstVertex);
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,
this->vertexCount(),
&vertexBuffer,
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; }

View File

@ -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,
maxVertices,
&vertexBuffer,
&firstVertex);
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));

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_START_IDX -1

View File

@ -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:

View File

@ -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) {

View File

@ -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;

View File

@ -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,
count,
&vertexBuffer,
&firstVertex);
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;

View File

@ -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
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 "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();

View File

@ -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.