Store GrMeshDrawOps' meshes in GrOpFlushState's arena.

Remove late draw consolidation in GrOpFlushState. Rarely did anything
and doesn't work with new allocation strategy. Ops can use GrMesh arrays
to acheive the same thing. (Each Op that cared to would have to implement
but it isn't applicable to most Ops).

Modify GrMeshDrawOp::Target::draw() to take array of meshes, with single
mesh as a special case.

Change-Id: I552677de47b9ffd2fcaf55af85f70f290e5aa9c7
Reviewed-on: https://skia-review.googlesource.com/145426
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Brian Salomon 2018-08-05 21:30:33 -04:00 committed by Skia Commit-Bot
parent c0b03d8dfc
commit b948572c78
29 changed files with 214 additions and 205 deletions

View File

@ -199,9 +199,9 @@ private:
} }
} }
GrMesh mesh(GrPrimitiveType::kTriangleStrip); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangleStrip);
mesh.setNonIndexedNonInstanced(kVertexCount); mesh->setNonIndexedNonInstanced(kVertexCount);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(), auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
target->detachAppliedClip()); target->detachAppliedClip());
target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh);

View File

@ -92,9 +92,9 @@ private:
: INHERITED(std::move(gp), rect, color, ClassID()) {} : INHERITED(std::move(gp), rect, color, ClassID()) {}
void onPrepareDraws(Target* target) override { void onPrepareDraws(Target* target) override {
QuadHelper helper;
SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(SkPoint)); SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(SkPoint));
SkPoint* pts = reinterpret_cast<SkPoint*>(helper.init(target, sizeof(SkPoint), 1)); QuadHelper helper(target, sizeof(SkPoint), 1);
SkPoint* pts = reinterpret_cast<SkPoint*>(helper.vertices());
if (!pts) { if (!pts) {
return; return;
} }
@ -284,9 +284,9 @@ private:
}; };
void onPrepareDraws(Target* target) override { void onPrepareDraws(Target* target) override {
QuadHelper helper;
SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(Vertex)); SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(Vertex));
Vertex* verts = reinterpret_cast<Vertex*>(helper.init(target, sizeof(Vertex), 1)); QuadHelper helper(target, sizeof(Vertex), 1);
Vertex* verts = reinterpret_cast<Vertex*>(helper.vertices());
if (!verts) { if (!verts) {
return; return;
} }
@ -506,9 +506,9 @@ private:
}; };
void onPrepareDraws(Target* target) override { void onPrepareDraws(Target* target) override {
QuadHelper helper;
SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(Vertex)); SkASSERT(this->gp()->debugOnly_vertexStride() == sizeof(Vertex));
Vertex* verts = reinterpret_cast<Vertex*>(helper.init(target, sizeof(Vertex), 1)); QuadHelper helper(target, sizeof(Vertex), 1);
Vertex* verts = reinterpret_cast<Vertex*>(helper.vertices());
if (!verts) { if (!verts) {
return; return;
} }

View File

@ -87,8 +87,8 @@ private:
SkMatrix::I())); SkMatrix::I()));
SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint)); SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint));
QuadHelper helper; QuadHelper helper(target, sizeof(SkPoint), 1);
SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, sizeof(SkPoint), 1)); SkPoint* verts = reinterpret_cast<SkPoint*>(helper.vertices());
if (!verts) { if (!verts) {
return; return;
} }

View File

@ -21,12 +21,12 @@ class GrPrimitiveProcessor;
*/ */
class GrMesh { class GrMesh {
public: public:
GrMesh(GrPrimitiveType primitiveType) GrMesh(GrPrimitiveType primitiveType = GrPrimitiveType::kTriangles)
: fPrimitiveType(primitiveType) : fPrimitiveType(primitiveType), fBaseVertex(0) {
, fBaseVertex(0) {
SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;) SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;)
} }
void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
GrPrimitiveType primitiveType() const { return fPrimitiveType; } GrPrimitiveType primitiveType() const { return fPrimitiveType; }
bool isIndexed() const { return SkToBool(fIndexBuffer.get()); } bool isIndexed() const { return SkToBool(fIndexBuffer.get()); }

View File

@ -45,8 +45,7 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const Sk
SkASSERT(fCurrDraw->fPipeline->proxy() == this->drawOpArgs().fProxy); SkASSERT(fCurrDraw->fPipeline->proxy() == this->drawOpArgs().fProxy);
this->rtCommandBuffer()->draw(*fCurrDraw->fGeometryProcessor, *fCurrDraw->fPipeline, this->rtCommandBuffer()->draw(*fCurrDraw->fGeometryProcessor, *fCurrDraw->fPipeline,
fCurrDraw->fFixedDynamicState, fCurrDraw->fDynamicStateArrays, fCurrDraw->fFixedDynamicState, fCurrDraw->fDynamicStateArrays,
fMeshes.begin() + fCurrMesh, fCurrDraw->fMeshCnt, opBounds); fCurrDraw->fMeshes, fCurrDraw->fMeshCnt, opBounds);
fCurrMesh += fCurrDraw->fMeshCnt;
fTokenTracker->flushToken(); fTokenTracker->flushToken();
++fCurrDraw; ++fCurrDraw;
} }
@ -61,7 +60,6 @@ void GrOpFlushState::preExecuteDraws() {
// Setup execution iterators. // Setup execution iterators.
fCurrDraw = fDraws.begin(); fCurrDraw = fDraws.begin();
fCurrUpload = fInlineUploads.begin(); fCurrUpload = fInlineUploads.begin();
fCurrMesh = 0;
} }
void GrOpFlushState::reset() { void GrOpFlushState::reset() {
@ -73,8 +71,6 @@ void GrOpFlushState::reset() {
fASAPUploads.reset(); fASAPUploads.reset();
fInlineUploads.reset(); fInlineUploads.reset();
fDraws.reset(); fDraws.reset();
fMeshes.reset();
fCurrMesh = 0;
fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken(); fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken();
} }
@ -106,29 +102,12 @@ GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&&
void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline, void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState, const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrMesh& mesh) { const GrMesh meshes[], int meshCnt) {
SkASSERT(fOpArgs); SkASSERT(fOpArgs);
SkASSERT(fOpArgs->fOp); SkASSERT(fOpArgs->fOp);
fMeshes.push_back(mesh);
bool firstDraw = fDraws.begin() == fDraws.end(); bool firstDraw = fDraws.begin() == fDraws.end();
if (!firstDraw) {
Draw& lastDraw = *fDraws.begin();
// If the last draw shares a geometry processor and pipeline and there are no intervening
// uploads, add this mesh to it.
// Note, we could attempt to convert fixed dynamic states into dynamic state arrays here
// if everything else is equal. Maybe it's better to rely on Ops to do that?
if (lastDraw.fGeometryProcessor == gp && lastDraw.fPipeline == pipeline &&
lastDraw.fFixedDynamicState == fixedDynamicState) {
if (fInlineUploads.begin() == fInlineUploads.end() ||
fInlineUploads.tail()->fUploadBeforeToken != fTokenTracker->nextDrawToken()) {
++lastDraw.fMeshCnt;
return;
}
}
}
auto& draw = fDraws.append(&fArena); auto& draw = fDraws.append(&fArena);
GrDeferredUploadToken token = fTokenTracker->issueDrawToken(); GrDeferredUploadToken token = fTokenTracker->issueDrawToken();
for (int i = 0; i < gp->numTextureSamplers(); ++i) { for (int i = 0; i < gp->numTextureSamplers(); ++i) {
fixedDynamicState->fPrimitiveProcessorTextures[i]->addPendingRead(); fixedDynamicState->fPrimitiveProcessorTextures[i]->addPendingRead();
} }
@ -136,7 +115,8 @@ void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline*
draw.fPipeline = pipeline; draw.fPipeline = pipeline;
draw.fFixedDynamicState = fixedDynamicState; draw.fFixedDynamicState = fixedDynamicState;
draw.fDynamicStateArrays = nullptr; draw.fDynamicStateArrays = nullptr;
draw.fMeshCnt = 1; draw.fMeshes = meshes;
draw.fMeshCnt = meshCnt;
draw.fOpID = fOpArgs->fOp->uniqueID(); draw.fOpID = fOpArgs->fOp->uniqueID();
if (firstDraw) { if (firstDraw) {
fBaseDrawToken = token; fBaseDrawToken = token;

View File

@ -73,9 +73,11 @@ public:
GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final; GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final;
/** Overrides of GrMeshDrawOp::Target. */ /** Overrides of GrMeshDrawOp::Target. */
void draw(sk_sp<const GrGeometryProcessor>,
void draw(sk_sp<const GrGeometryProcessor>, const GrPipeline*, const GrPipeline*,
const GrPipeline::FixedDynamicState*, const GrMesh&) final; const GrPipeline::FixedDynamicState*,
const GrMesh[],
int meshCount) final;
void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**, void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**,
int* startVertex) final; int* startVertex) final;
uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) final; uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) final;
@ -123,12 +125,13 @@ private:
fFixedDynamicState->fPrimitiveProcessorTextures[i]->completedRead(); fFixedDynamicState->fPrimitiveProcessorTextures[i]->completedRead();
} }
} }
int fMeshCnt = 0;
sk_sp<const GrGeometryProcessor> fGeometryProcessor; sk_sp<const GrGeometryProcessor> fGeometryProcessor;
const GrPipeline* fPipeline; const GrPipeline* fPipeline = nullptr;
const GrPipeline::FixedDynamicState* fFixedDynamicState; const GrPipeline::FixedDynamicState* fFixedDynamicState;
const GrPipeline::DynamicStateArrays* fDynamicStateArrays; const GrPipeline::DynamicStateArrays* fDynamicStateArrays;
uint32_t fOpID; const GrMesh* fMeshes = nullptr;
int fMeshCnt = 0;
uint32_t fOpID = SK_InvalidUniqueID;
}; };
// Storage for ops' pipelines, draws, and inline uploads. // Storage for ops' pipelines, draws, and inline uploads.
@ -142,9 +145,6 @@ private:
SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads; SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads;
SkArenaAllocList<InlineUpload> fInlineUploads; SkArenaAllocList<InlineUpload> fInlineUploads;
SkArenaAllocList<Draw> fDraws; SkArenaAllocList<Draw> fDraws;
// TODO: These should go in the arena. However, GrGpuCommandBuffer and other classes currently
// accept contiguous arrays of meshes.
SkSTArray<16, GrMesh> fMeshes;
// All draws we store have an implicit draw token. This is the draw token for the first draw // All draws we store have an implicit draw token. This is the draw token for the first draw
// in fDraws. // in fDraws.
@ -161,7 +161,6 @@ private:
// Variables that are used to track where we are in lists as ops are executed // Variables that are used to track where we are in lists as ops are executed
SkArenaAllocList<Draw>::Iter fCurrDraw; SkArenaAllocList<Draw>::Iter fCurrDraw;
int fCurrMesh;
SkArenaAllocList<InlineUpload>::Iter fCurrUpload; SkArenaAllocList<InlineUpload>::Iter fCurrUpload;
// Used to track the proxies that need to be uninstantiated after we finish a flush // Used to track the proxies that need to be uninstantiated after we finish a flush

View File

@ -843,10 +843,10 @@ private:
extract_lines_only_verts(tess, verts, vertexStride, args.fColor, idxs, extract_lines_only_verts(tess, verts, vertexStride, args.fColor, idxs,
fHelper.compatibleWithAlphaAsCoverage()); fHelper.compatibleWithAlphaAsCoverage());
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1, mesh->setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1,
GrPrimitiveRestart::kNo); GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }
} }
@ -928,17 +928,18 @@ private:
SkSTArray<kPreallocDrawCnt, Draw, true> draws; SkSTArray<kPreallocDrawCnt, Draw, true> draws;
create_vertices(segments, fanPt, args.fColor, &draws, verts, idxs); create_vertices(segments, fanPt, args.fColor, &draws, verts, idxs);
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* meshes = target->allocMeshes(draws.count());
for (int j = 0; j < draws.count(); ++j) { for (int j = 0; j < draws.count(); ++j) {
const Draw& draw = draws[j]; const Draw& draw = draws[j];
mesh.setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0, draw.fVertexCnt - 1, meshes[j].setPrimitiveType(GrPrimitiveType::kTriangles);
GrPrimitiveRestart::kNo); meshes[j].setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0,
mesh.setVertexData(vertexBuffer, firstVertex); draw.fVertexCnt - 1, GrPrimitiveRestart::kNo);
target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, mesh); meshes[j].setVertexData(vertexBuffer, firstVertex);
firstIndex += draw.fIndexCnt; firstIndex += draw.fIndexCnt;
firstVertex += draw.fVertexCnt; firstVertex += draw.fVertexCnt;
} }
target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, meshes,
draws.count());
} }
} }

View File

@ -265,10 +265,9 @@ private:
SkASSERT(vertexStride == gp->debugOnly_vertexStride()); SkASSERT(vertexStride == gp->debugOnly_vertexStride());
sk_sp<const GrBuffer> indexBuffer = get_index_buffer(target->resourceProvider()); sk_sp<const GrBuffer> indexBuffer = get_index_buffer(target->resourceProvider());
PatternHelper helper(GrPrimitiveType::kTriangles); PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
void* vertices = kVertsPerAAFillRect, kIndicesPerAAFillRect, fRectCnt);
helper.init(target, vertexStride, indexBuffer.get(), kVertsPerAAFillRect, void* vertices = helper.vertices();
kIndicesPerAAFillRect, fRectCnt);
if (!vertices || !indexBuffer) { if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -975,10 +975,10 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
add_line(&lines[2*i], toSrc, this->coverage(), &verts); add_line(&lines[2*i], toSrc, this->coverage(), &verts);
} }
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexedPatterned(linesIndexBuffer.get(), kIdxsPerLineSeg, kLineSegNumVertices, mesh->setIndexedPatterned(linesIndexBuffer.get(), kIdxsPerLineSeg, kLineSegNumVertices,
lineCount, kLineSegsNumInIdxBuffer); lineCount, kLineSegsNumInIdxBuffer);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
target->draw(std::move(lineGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(lineGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }
@ -1030,19 +1030,19 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
} }
if (quadCount > 0) { if (quadCount > 0) {
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices, mesh->setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
quadCount, kQuadsNumInIdxBuffer); quadCount, kQuadsNumInIdxBuffer);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
target->draw(std::move(quadGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(quadGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
firstVertex += quadCount * kQuadNumVertices; firstVertex += quadCount * kQuadNumVertices;
} }
if (conicCount > 0) { if (conicCount > 0) {
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices, mesh->setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
conicCount, kQuadsNumInIdxBuffer); conicCount, kQuadsNumInIdxBuffer);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
target->draw(std::move(conicGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(conicGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }
} }

View File

@ -217,7 +217,6 @@ private:
return; return;
} }
const GrBuffer* vertexBuffer; const GrBuffer* vertexBuffer;
GrMesh mesh(GrPrimitiveType::kTriangles);
int firstVertex; int firstVertex;
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
&firstVertex); &firstVertex);
@ -235,9 +234,10 @@ private:
return; return;
} }
memcpy(idxs, indices, indexCount * sizeof(uint16_t)); memcpy(idxs, indices, indexCount * sizeof(uint16_t));
mesh.setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1, GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
GrPrimitiveRestart::kNo); mesh->setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1,
mesh.setVertexData(vertexBuffer, firstVertex); GrPrimitiveRestart::kNo);
mesh->setVertexData(vertexBuffer, firstVertex);
target->draw(std::move(gp), pipeline, fixedDynamicState, mesh); target->draw(std::move(gp), pipeline, fixedDynamicState, mesh);
} }

View File

@ -282,11 +282,11 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) {
int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt; int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
int instanceCount = fRects.count(); int instanceCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer = GetIndexBuffer(target->resourceProvider(), this->miterStroke()); sk_sp<const GrBuffer> indexBuffer =
PatternHelper helper(GrPrimitiveType::kTriangles); GetIndexBuffer(target->resourceProvider(), this->miterStroke());
void* vertices = PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
helper.init(target, vertexStride, indexBuffer.get(), verticesPerInstance, indicesPerInstance, instanceCount);
verticesPerInstance, indicesPerInstance, instanceCount); void* vertices = helper.vertices();
if (!vertices || !indexBuffer) { if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -425,12 +425,12 @@ void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) co
samplerState); samplerState);
} }
} }
GrMesh mesh(GrPrimitiveType::kTriangles);
int maxGlyphsPerDraw = int maxGlyphsPerDraw =
static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6); static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph, GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
flushInfo->fGlyphsToFlush, maxGlyphsPerDraw); mesh->setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph,
mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset); flushInfo->fGlyphsToFlush, maxGlyphsPerDraw);
mesh->setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline, flushInfo->fFixedDynamicState, target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline, flushInfo->fFixedDynamicState,
mesh); mesh);
flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush; flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;

View File

@ -625,7 +625,6 @@ private:
return; return;
} }
QuadHelper helper;
size_t vertexStride; size_t vertexStride;
if (fullDash) { if (fullDash) {
vertexStride = vertexStride =
@ -634,7 +633,8 @@ private:
vertexStride = sizeof(SkPoint); vertexStride = sizeof(SkPoint);
} }
SkASSERT(vertexStride == gp->debugOnly_vertexStride()); SkASSERT(vertexStride == gp->debugOnly_vertexStride());
void* vertices = helper.init(target, vertexStride, totalRectCount); QuadHelper helper(target, vertexStride, totalRectCount);
void* vertices = helper.vertices();
if (!vertices) { if (!vertices) {
return; return;
} }

View File

@ -67,7 +67,7 @@ public:
PathGeoBuilder(GrPrimitiveType primitiveType, GrMeshDrawOp::Target* target, PathGeoBuilder(GrPrimitiveType primitiveType, GrMeshDrawOp::Target* target,
sk_sp<const GrGeometryProcessor> geometryProcessor, const GrPipeline* pipeline, sk_sp<const GrGeometryProcessor> geometryProcessor, const GrPipeline* pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState) const GrPipeline::FixedDynamicState* fixedDynamicState)
: fMesh(primitiveType) : fPrimitiveType(primitiveType)
, fTarget(target) , fTarget(target)
, fVertexStride(sizeof(SkPoint)) , fVertexStride(sizeof(SkPoint))
, fGeometryProcessor(std::move(geometryProcessor)) , fGeometryProcessor(std::move(geometryProcessor))
@ -200,15 +200,15 @@ private:
* TODO: Cache some of these for better performance, rather than re-computing? * TODO: Cache some of these for better performance, rather than re-computing?
*/ */
bool isIndexed() const { bool isIndexed() const {
return GrPrimitiveType::kLines == fMesh.primitiveType() || return GrPrimitiveType::kLines == fPrimitiveType ||
GrPrimitiveType::kTriangles == fMesh.primitiveType(); GrPrimitiveType::kTriangles == fPrimitiveType;
} }
bool isHairline() const { bool isHairline() const {
return GrPrimitiveType::kLines == fMesh.primitiveType() || return GrPrimitiveType::kLines == fPrimitiveType ||
GrPrimitiveType::kLineStrip == fMesh.primitiveType(); GrPrimitiveType::kLineStrip == fPrimitiveType;
} }
int indexScale() const { int indexScale() const {
switch (fMesh.primitiveType()) { switch (fPrimitiveType) {
case GrPrimitiveType::kLines: case GrPrimitiveType::kLines:
return 2; return 2;
case GrPrimitiveType::kTriangles: case GrPrimitiveType::kTriangles:
@ -271,14 +271,15 @@ private:
SkASSERT(indexCount <= fIndicesInChunk); SkASSERT(indexCount <= fIndicesInChunk);
if (this->isIndexed() ? SkToBool(indexCount) : SkToBool(vertexCount)) { if (this->isIndexed() ? SkToBool(indexCount) : SkToBool(vertexCount)) {
GrMesh* mesh = fTarget->allocMesh(fPrimitiveType);
if (!this->isIndexed()) { if (!this->isIndexed()) {
fMesh.setNonIndexedNonInstanced(vertexCount); mesh->setNonIndexedNonInstanced(vertexCount);
} else { } else {
fMesh.setIndexed(fIndexBuffer, indexCount, fFirstIndex, 0, vertexCount - 1, mesh->setIndexed(fIndexBuffer, indexCount, fFirstIndex, 0, vertexCount - 1,
GrPrimitiveRestart::kNo); GrPrimitiveRestart::kNo);
} }
fMesh.setVertexData(fVertexBuffer, fFirstVertex); mesh->setVertexData(fVertexBuffer, fFirstVertex);
fTarget->draw(fGeometryProcessor, fPipeline, fFixedDynamicState, fMesh); fTarget->draw(fGeometryProcessor, fPipeline, fFixedDynamicState, mesh);
} }
fTarget->putBackIndices((size_t)(fIndicesInChunk - indexCount)); fTarget->putBackIndices((size_t)(fIndicesInChunk - indexCount));
@ -311,7 +312,7 @@ private:
} }
} }
GrMesh fMesh; GrPrimitiveType fPrimitiveType;
GrMeshDrawOp::Target* fTarget; GrMeshDrawOp::Target* fTarget;
size_t fVertexStride; size_t fVertexStride;
sk_sp<const GrGeometryProcessor> fGeometryProcessor; sk_sp<const GrGeometryProcessor> fGeometryProcessor;

View File

@ -130,9 +130,9 @@ void GrDrawAtlasOp::onPrepareDraws(Target* target) {
sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0); sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0);
SkASSERT(vertexStride == gp->debugOnly_vertexStride()); SkASSERT(vertexStride == gp->debugOnly_vertexStride());
QuadHelper helper;
int numQuads = this->quadCount(); int numQuads = this->quadCount();
void* verts = helper.init(target, vertexStride, numQuads); QuadHelper helper(target, vertexStride, numQuads);
void* verts = helper.vertices();
if (!verts) { if (!verts) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -470,15 +470,14 @@ void GrDrawVerticesOp::drawVertices(Target* target,
int firstVertex, int firstVertex,
const GrBuffer* indexBuffer, const GrBuffer* indexBuffer,
int firstIndex) { int firstIndex) {
GrMesh mesh(this->primitiveType()); GrMesh* mesh = target->allocMesh(this->primitiveType());
if (this->isIndexed()) { if (this->isIndexed()) {
mesh.setIndexed(indexBuffer, fIndexCount, mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1,
firstIndex, 0, fVertexCount - 1, GrPrimitiveRestart::kNo);
GrPrimitiveRestart::kNo);
} else { } else {
mesh.setNonIndexedNonInstanced(fVertexCount); mesh->setNonIndexedNonInstanced(fVertexCount);
} }
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }

View File

@ -223,9 +223,9 @@ private:
} }
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer(); sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles); PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStide, indexBuffer.get(),
void* vertices = helper.init(target, kVertexStide, indexBuffer.get(), kVertsPerRect, kVertsPerRect, kIndicesPerRect, numRects);
kIndicesPerRect, numRects); void* vertices = helper.vertices();
if (!vertices || !indexBuffer) { if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -14,50 +14,61 @@ GrMeshDrawOp::GrMeshDrawOp(uint32_t classID) : INHERITED(classID) {}
void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); } void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); }
void* GrMeshDrawOp::PatternHelper::init(Target* target, size_t vertexStride, void GrMeshDrawOp::onExecute(GrOpFlushState* state) {
const GrBuffer* indexBuffer, int verticesPerRepetition, state->executeDrawsAndUploadsForMeshDrawOp(this->uniqueID(), this->bounds());
int indicesPerRepetition, int repeatCount) { }
//////////////////////////////////////////////////////////////////////////////
GrMeshDrawOp::PatternHelper::PatternHelper(Target* target, GrPrimitiveType primitiveType,
size_t vertexStride, const GrBuffer* indexBuffer,
int verticesPerRepetition, int indicesPerRepetition,
int repeatCount) {
this->init(target, primitiveType, vertexStride, indexBuffer, verticesPerRepetition,
indicesPerRepetition, repeatCount);
}
void GrMeshDrawOp::PatternHelper::init(Target* target, GrPrimitiveType primitiveType,
size_t vertexStride, const GrBuffer* indexBuffer,
int verticesPerRepetition, int indicesPerRepetition,
int repeatCount) {
SkASSERT(target); SkASSERT(target);
if (!indexBuffer) { if (!indexBuffer) {
return nullptr; return;
} }
const GrBuffer* vertexBuffer; const GrBuffer* vertexBuffer;
int firstVertex; int firstVertex;
int vertexCount = verticesPerRepetition * repeatCount; int vertexCount = verticesPerRepetition * repeatCount;
void* vertices = fVertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); if (!fVertices) {
if (!vertices) { SkDebugf("Vertices could not be allocated for patterned rendering.");
SkDebugf("Vertices could not be allocated for instanced rendering."); return;
return nullptr;
} }
SkASSERT(vertexBuffer); SkASSERT(vertexBuffer);
size_t ibSize = indexBuffer->gpuMemorySize(); size_t ibSize = indexBuffer->gpuMemorySize();
int maxRepetitions = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerRepetition)); int maxRepetitions = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerRepetition));
fMesh = target->allocMesh(primitiveType);
fMesh.setIndexedPatterned(indexBuffer, indicesPerRepetition, verticesPerRepetition, fMesh->setIndexedPatterned(indexBuffer, indicesPerRepetition, verticesPerRepetition,
repeatCount, maxRepetitions); repeatCount, maxRepetitions);
fMesh.setVertexData(vertexBuffer, firstVertex); fMesh->setVertexData(vertexBuffer, firstVertex);
return vertices;
} }
void GrMeshDrawOp::PatternHelper::recordDraw( void GrMeshDrawOp::PatternHelper::recordDraw(
Target* target, sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline, Target* target, sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState) { const GrPipeline::FixedDynamicState* fixedDynamicState) const {
target->draw(std::move(gp), pipeline, fixedDynamicState, fMesh); target->draw(std::move(gp), pipeline, fixedDynamicState, fMesh);
} }
void* GrMeshDrawOp::QuadHelper::init(Target* target, size_t vertexStride, int quadsToDraw) { //////////////////////////////////////////////////////////////////////////////
GrMeshDrawOp::QuadHelper::QuadHelper(Target* target, size_t vertexStride, int quadsToDraw) {
sk_sp<const GrBuffer> quadIndexBuffer = target->resourceProvider()->refQuadIndexBuffer(); sk_sp<const GrBuffer> quadIndexBuffer = target->resourceProvider()->refQuadIndexBuffer();
if (!quadIndexBuffer) { if (!quadIndexBuffer) {
SkDebugf("Could not get quad index buffer."); SkDebugf("Could not get quad index buffer.");
return nullptr; return;
} }
return this->INHERITED::init(target, vertexStride, quadIndexBuffer.get(), kVerticesPerQuad, this->init(target, GrPrimitiveType::kTriangles, vertexStride, quadIndexBuffer.get(),
kIndicesPerQuad, quadsToDraw); kVerticesPerQuad, kIndicesPerQuad, quadsToDraw);
}
void GrMeshDrawOp::onExecute(GrOpFlushState* state) {
state->executeDrawsAndUploadsForMeshDrawOp(this->uniqueID(), this->bounds());
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View File

@ -33,18 +33,23 @@ protected:
space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */ space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
class PatternHelper { class PatternHelper {
public: public:
PatternHelper(GrPrimitiveType primitiveType) : fMesh(primitiveType) {} PatternHelper(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
/** Returns the allocated storage for the vertices. The caller should populate the vertices int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
before calling recordDraws(). */
void* init(Target*, size_t vertexStride, const GrBuffer*, int verticesPerRepetition,
int indicesPerRepetition, int repeatCount);
/** Call after init() to issue draws to the GrMeshDrawOp::Target.*/ /** Called to issue draws to the GrMeshDrawOp::Target.*/
void recordDraw(Target*, sk_sp<const GrGeometryProcessor>, const GrPipeline*, void recordDraw(Target*, sk_sp<const GrGeometryProcessor>, const GrPipeline*,
const GrPipeline::FixedDynamicState*); const GrPipeline::FixedDynamicState*) const;
void* vertices() const { return fVertices; }
protected:
PatternHelper() = default;
void init(Target*, GrPrimitiveType, size_t vertexStride, const GrBuffer*,
int verticesPerRepetition, int indicesPerRepetition, int repeatCount);
private: private:
GrMesh fMesh; void* fVertices = nullptr;
GrMesh* fMesh = nullptr;
}; };
static const int kVerticesPerQuad = 4; static const int kVerticesPerQuad = 4;
@ -53,13 +58,11 @@ protected:
/** A specialization of InstanceHelper for quad rendering. */ /** A specialization of InstanceHelper for quad rendering. */
class QuadHelper : private PatternHelper { class QuadHelper : private PatternHelper {
public: public:
QuadHelper() : INHERITED(GrPrimitiveType::kTriangles) {} QuadHelper() = delete;
/** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
and on success a pointer to the vertex data that the caller should populate before
calling recordDraws(). */
void* init(Target*, size_t vertexStride, int quadsToDraw);
using PatternHelper::recordDraw; using PatternHelper::recordDraw;
using PatternHelper::vertices;
private: private:
typedef PatternHelper INHERITED; typedef PatternHelper INHERITED;
@ -77,8 +80,19 @@ public:
virtual ~Target() {} virtual ~Target() {}
/** Adds a draw of a mesh. */ /** Adds a draw of a mesh. */
virtual void draw(sk_sp<const GrGeometryProcessor>, const GrPipeline*, virtual void draw(sk_sp<const GrGeometryProcessor>,
const GrPipeline::FixedDynamicState*, const GrMesh&) = 0; const GrPipeline*,
const GrPipeline::FixedDynamicState*,
const GrMesh[],
int meshCount) = 0;
/** Helper for drawing a single GrMesh. */
void draw(sk_sp<const GrGeometryProcessor> gp,
const GrPipeline* pipeline,
const GrPipeline::FixedDynamicState* fixedDynamicState,
const GrMesh* mesh) {
this->draw(std::move(gp), pipeline, fixedDynamicState, mesh, 1);
}
/** /**
* Makes space for vertex data. The returned pointer is the location where vertex data * Makes space for vertex data. The returned pointer is the location where vertex data
@ -131,6 +145,12 @@ public:
return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...); return this->pipelineArena()->make<GrPipeline>(std::forward<Args>(args)...);
} }
GrMesh* allocMesh(GrPrimitiveType primitiveType) {
return this->pipelineArena()->make<GrMesh>(primitiveType);
}
GrMesh* allocMeshes(int n) { return this->pipelineArena()->makeArray<GrMesh>(n); }
GrPipeline::FixedDynamicState* allocFixedDynamicState(const SkIRect& rect, GrPipeline::FixedDynamicState* allocFixedDynamicState(const SkIRect& rect,
int numPrimitiveProcessorTextures = 0) { int numPrimitiveProcessorTextures = 0) {
auto result = this->pipelineArena()->make<GrPipeline::FixedDynamicState>(rect); auto result = this->pipelineArena()->make<GrPipeline::FixedDynamicState>(rect);

View File

@ -192,9 +192,9 @@ private:
int rectCount = fRects.count(); int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer(); sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles); PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStride, indexBuffer.get(),
void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerRect, kVertsPerRect, kIndicesPerRect, rectCount);
kIndicesPerRect, rectCount); void* vertices = helper.vertices();
if (!vertices || !indexBuffer) { if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;
@ -325,9 +325,9 @@ private:
int rectCount = fRects.count(); int rectCount = fRects.count();
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer(); sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles); PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect, kVertsPerRect, kIndicesPerRect, rectCount);
kIndicesPerRect, rectCount); void* vertices = helper.vertices();
if (!vertices || !indexBuffer) { if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -188,9 +188,9 @@ private:
vertex[4].set(fRect.fLeft, fRect.fTop); vertex[4].set(fRect.fLeft, fRect.fTop);
} }
GrMesh mesh(primType); GrMesh* mesh = target->allocMesh(primType);
mesh.setNonIndexedNonInstanced(vertexCount); mesh->setNonIndexedNonInstanced(vertexCount);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }

View File

@ -1470,10 +1470,10 @@ private:
vertices += circle_type_to_vert_count(circle.fStroked) * vertexStride; vertices += circle_type_to_vert_count(circle.fStroked) * vertexStride;
} }
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo); GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }
@ -1786,10 +1786,10 @@ private:
vertices += circle_type_to_vert_count(true) * kVertexStride; vertices += circle_type_to_vert_count(true) * kVertexStride;
} }
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo); GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }
@ -1984,10 +1984,9 @@ private:
// Setup geometry processor // Setup geometry processor
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix)); sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
QuadHelper helper;
SkASSERT(sizeof(EllipseVertex) == gp->debugOnly_vertexStride()); SkASSERT(sizeof(EllipseVertex) == gp->debugOnly_vertexStride());
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( QuadHelper helper(target, sizeof(EllipseVertex), fEllipses.count());
helper.init(target, sizeof(EllipseVertex), fEllipses.count())); EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(helper.vertices());
if (!verts) { if (!verts) {
return; return;
} }
@ -2219,9 +2218,8 @@ private:
new DIEllipseGeometryProcessor(this->viewMatrix(), this->style())); new DIEllipseGeometryProcessor(this->viewMatrix(), this->style()));
SkASSERT(sizeof(DIEllipseVertex) == gp->debugOnly_vertexStride()); SkASSERT(sizeof(DIEllipseVertex) == gp->debugOnly_vertexStride());
QuadHelper helper; QuadHelper helper(target, sizeof(DIEllipseVertex), fEllipses.count());
DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>( DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(helper.vertices());
helper.init(target, sizeof(DIEllipseVertex), fEllipses.count()));
if (!verts) { if (!verts) {
return; return;
} }
@ -2725,10 +2723,10 @@ private:
currStartVertex += rrect_type_to_vert_count(rrect.fType); currStartVertex += rrect_type_to_vert_count(rrect.fType);
} }
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo); GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }
@ -2927,10 +2925,10 @@ private:
sk_sp<const GrBuffer> indexBuffer = get_rrect_index_buffer( sk_sp<const GrBuffer> indexBuffer = get_rrect_index_buffer(
fStroked ? kStroke_RRectType : kFill_RRectType, target->resourceProvider()); fStroked ? kStroke_RRectType : kFill_RRectType, target->resourceProvider());
PatternHelper helper(GrPrimitiveType::kTriangles); PatternHelper helper(target, GrPrimitiveType::kTriangles, sizeof(EllipseVertex),
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( indexBuffer.get(), kVertsPerStandardRRect, indicesPerInstance,
helper.init(target, sizeof(EllipseVertex), indexBuffer.get(), fRRects.count());
kVertsPerStandardRRect, indicesPerInstance, fRRects.count())); EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(helper.vertices());
if (!verts || !indexBuffer) { if (!verts || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -129,9 +129,9 @@ private:
return; return;
} }
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer(); sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
PatternHelper helper(GrPrimitiveType::kTriangles); PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStride, indexBuffer.get(),
void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerInstance, kVertsPerInstance, kIndicesPerInstance, numRects);
kIndicesPerInstance, numRects); void* vertices = helper.vertices();
if (!vertices || !indexBuffer) { if (!vertices || !indexBuffer) {
SkDebugf("Could not allocate vertices\n"); SkDebugf("Could not allocate vertices\n");
return; return;

View File

@ -627,10 +627,10 @@ private:
auto pipe = target->makePipeline(kPipelineFlags, GrProcessorSet::MakeEmptySet(), auto pipe = target->makePipeline(kPipelineFlags, GrProcessorSet::MakeEmptySet(),
target->detachAppliedClip()); target->detachAppliedClip());
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1, mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
GrPrimitiveRestart::kNo); GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }

View File

@ -833,13 +833,13 @@ private:
} }
if (flushInfo->fInstancesToFlush) { if (flushInfo->fInstancesToFlush) {
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
int maxInstancesPerDraw = int maxInstancesPerDraw =
static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6); static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerQuad, mesh->setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerQuad,
kVerticesPerQuad, flushInfo->fInstancesToFlush, kVerticesPerQuad, flushInfo->fInstancesToFlush,
maxInstancesPerDraw); maxInstancesPerDraw);
mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset); mesh->setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline, target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline,
flushInfo->fFixedDynamicState, mesh); flushInfo->fFixedDynamicState, mesh);
flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush; flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;

View File

@ -358,9 +358,10 @@ private:
void drawVertices(Target* target, sk_sp<const GrGeometryProcessor> gp, const GrBuffer* vb, void drawVertices(Target* target, sk_sp<const GrGeometryProcessor> gp, const GrBuffer* vb,
int firstVertex, int count) { int firstVertex, int count) {
GrMesh mesh(TESSELLATOR_WIREFRAME ? GrPrimitiveType::kLines : GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(TESSELLATOR_WIREFRAME ? GrPrimitiveType::kLines
mesh.setNonIndexedNonInstanced(count); : GrPrimitiveType::kTriangles);
mesh.setVertexData(vb, firstVertex); mesh->setNonIndexedNonInstanced(count);
mesh->setVertexData(vb, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
} }

View File

@ -858,19 +858,19 @@ __attribute__((no_sanitize("float-cast-overflow")))
GrPrimitiveType primitiveType = GrPrimitiveType primitiveType =
fDraws.count() > 1 ? GrPrimitiveType::kTriangles : GrPrimitiveType::kTriangleStrip; fDraws.count() > 1 ? GrPrimitiveType::kTriangles : GrPrimitiveType::kTriangleStrip;
GrMesh mesh(primitiveType); GrMesh* mesh = target->allocMesh(primitiveType);
if (fDraws.count() > 1) { if (fDraws.count() > 1) {
sk_sp<const GrBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer(); sk_sp<const GrBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer();
if (!ibuffer) { if (!ibuffer) {
SkDebugf("Could not allocate quad indices\n"); SkDebugf("Could not allocate quad indices\n");
return; return;
} }
mesh.setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(), mesh->setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(),
GrResourceProvider::QuadCountOfQuadBuffer()); GrResourceProvider::QuadCountOfQuadBuffer());
} else { } else {
mesh.setNonIndexedNonInstanced(4); mesh->setNonIndexedNonInstanced(4);
} }
mesh.setVertexData(vbuffer, vstart); mesh->setVertexData(vbuffer, vstart);
target->draw(std::move(gp), pipeline, fixedDynamicState, mesh); target->draw(std::move(gp), pipeline, fixedDynamicState, mesh);
} }

View File

@ -159,9 +159,9 @@ private:
} }
} }
GrMesh mesh(GrPrimitiveType::kTriangles); GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
mesh.setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo); mesh->setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo);
mesh.setVertexData(vertexBuffer, firstVertex); mesh->setVertexData(vertexBuffer, firstVertex);
auto pipe = fHelper.makePipeline(target); auto pipe = fHelper.makePipeline(target);
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh); target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);

View File

@ -105,10 +105,10 @@ private:
typedef GrGeometryProcessor INHERITED; typedef GrGeometryProcessor INHERITED;
}; };
sk_sp<GrGeometryProcessor> gp(new GP(fNumAttribs)); sk_sp<GrGeometryProcessor> gp(new GP(fNumAttribs));
QuadHelper helper;
size_t vertexStride = fNumAttribs * GrVertexAttribTypeSize(kFloat2_GrVertexAttribType); size_t vertexStride = fNumAttribs * GrVertexAttribTypeSize(kFloat2_GrVertexAttribType);
SkASSERT(vertexStride == gp->debugOnly_vertexStride()); SkASSERT(vertexStride == gp->debugOnly_vertexStride());
SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.init(target, vertexStride, 1)); QuadHelper helper(target, vertexStride, 1);
SkPoint* vertices = reinterpret_cast<SkPoint*>(helper.vertices());
SkPointPriv::SetRectTriStrip(vertices, 0.f, 0.f, 1.f, 1.f, vertexStride); SkPointPriv::SetRectTriStrip(vertices, 0.f, 0.f, 1.f, 1.f, vertexStride);
auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(), auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
target->detachAppliedClip()); target->detachAppliedClip());