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:
parent
c0b03d8dfc
commit
b948572c78
@ -199,9 +199,9 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangleStrip);
|
||||
mesh.setNonIndexedNonInstanced(kVertexCount);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangleStrip);
|
||||
mesh->setNonIndexedNonInstanced(kVertexCount);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
|
||||
target->detachAppliedClip());
|
||||
target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
|
@ -92,9 +92,9 @@ private:
|
||||
: INHERITED(std::move(gp), rect, color, ClassID()) {}
|
||||
|
||||
void onPrepareDraws(Target* target) override {
|
||||
QuadHelper helper;
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@ -284,9 +284,9 @@ private:
|
||||
};
|
||||
|
||||
void onPrepareDraws(Target* target) override {
|
||||
QuadHelper helper;
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
@ -506,9 +506,9 @@ private:
|
||||
};
|
||||
|
||||
void onPrepareDraws(Target* target) override {
|
||||
QuadHelper helper;
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -87,8 +87,8 @@ private:
|
||||
SkMatrix::I()));
|
||||
|
||||
SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint));
|
||||
QuadHelper helper;
|
||||
SkPoint* verts = reinterpret_cast<SkPoint*>(helper.init(target, sizeof(SkPoint), 1));
|
||||
QuadHelper helper(target, sizeof(SkPoint), 1);
|
||||
SkPoint* verts = reinterpret_cast<SkPoint*>(helper.vertices());
|
||||
if (!verts) {
|
||||
return;
|
||||
}
|
||||
|
@ -21,12 +21,12 @@ class GrPrimitiveProcessor;
|
||||
*/
|
||||
class GrMesh {
|
||||
public:
|
||||
GrMesh(GrPrimitiveType primitiveType)
|
||||
: fPrimitiveType(primitiveType)
|
||||
, fBaseVertex(0) {
|
||||
GrMesh(GrPrimitiveType primitiveType = GrPrimitiveType::kTriangles)
|
||||
: fPrimitiveType(primitiveType), fBaseVertex(0) {
|
||||
SkDEBUGCODE(fNonIndexNonInstanceData.fVertexCount = -1;)
|
||||
}
|
||||
|
||||
void setPrimitiveType(GrPrimitiveType type) { fPrimitiveType = type; }
|
||||
GrPrimitiveType primitiveType() const { return fPrimitiveType; }
|
||||
|
||||
bool isIndexed() const { return SkToBool(fIndexBuffer.get()); }
|
||||
|
@ -45,8 +45,7 @@ void GrOpFlushState::executeDrawsAndUploadsForMeshDrawOp(uint32_t opID, const Sk
|
||||
SkASSERT(fCurrDraw->fPipeline->proxy() == this->drawOpArgs().fProxy);
|
||||
this->rtCommandBuffer()->draw(*fCurrDraw->fGeometryProcessor, *fCurrDraw->fPipeline,
|
||||
fCurrDraw->fFixedDynamicState, fCurrDraw->fDynamicStateArrays,
|
||||
fMeshes.begin() + fCurrMesh, fCurrDraw->fMeshCnt, opBounds);
|
||||
fCurrMesh += fCurrDraw->fMeshCnt;
|
||||
fCurrDraw->fMeshes, fCurrDraw->fMeshCnt, opBounds);
|
||||
fTokenTracker->flushToken();
|
||||
++fCurrDraw;
|
||||
}
|
||||
@ -61,7 +60,6 @@ void GrOpFlushState::preExecuteDraws() {
|
||||
// Setup execution iterators.
|
||||
fCurrDraw = fDraws.begin();
|
||||
fCurrUpload = fInlineUploads.begin();
|
||||
fCurrMesh = 0;
|
||||
}
|
||||
|
||||
void GrOpFlushState::reset() {
|
||||
@ -73,8 +71,6 @@ void GrOpFlushState::reset() {
|
||||
fASAPUploads.reset();
|
||||
fInlineUploads.reset();
|
||||
fDraws.reset();
|
||||
fMeshes.reset();
|
||||
fCurrMesh = 0;
|
||||
fBaseDrawToken = GrDeferredUploadToken::AlreadyFlushedToken();
|
||||
}
|
||||
|
||||
@ -106,29 +102,12 @@ GrDeferredUploadToken GrOpFlushState::addASAPUpload(GrDeferredTextureUploadFn&&
|
||||
|
||||
void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline* pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState,
|
||||
const GrMesh& mesh) {
|
||||
const GrMesh meshes[], int meshCnt) {
|
||||
SkASSERT(fOpArgs);
|
||||
SkASSERT(fOpArgs->fOp);
|
||||
fMeshes.push_back(mesh);
|
||||
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);
|
||||
GrDeferredUploadToken token = fTokenTracker->issueDrawToken();
|
||||
|
||||
for (int i = 0; i < gp->numTextureSamplers(); ++i) {
|
||||
fixedDynamicState->fPrimitiveProcessorTextures[i]->addPendingRead();
|
||||
}
|
||||
@ -136,7 +115,8 @@ void GrOpFlushState::draw(sk_sp<const GrGeometryProcessor> gp, const GrPipeline*
|
||||
draw.fPipeline = pipeline;
|
||||
draw.fFixedDynamicState = fixedDynamicState;
|
||||
draw.fDynamicStateArrays = nullptr;
|
||||
draw.fMeshCnt = 1;
|
||||
draw.fMeshes = meshes;
|
||||
draw.fMeshCnt = meshCnt;
|
||||
draw.fOpID = fOpArgs->fOp->uniqueID();
|
||||
if (firstDraw) {
|
||||
fBaseDrawToken = token;
|
||||
|
@ -73,9 +73,11 @@ public:
|
||||
GrDeferredUploadToken addASAPUpload(GrDeferredTextureUploadFn&&) final;
|
||||
|
||||
/** Overrides of GrMeshDrawOp::Target. */
|
||||
|
||||
void draw(sk_sp<const GrGeometryProcessor>, const GrPipeline*,
|
||||
const GrPipeline::FixedDynamicState*, const GrMesh&) final;
|
||||
void draw(sk_sp<const GrGeometryProcessor>,
|
||||
const GrPipeline*,
|
||||
const GrPipeline::FixedDynamicState*,
|
||||
const GrMesh[],
|
||||
int meshCount) final;
|
||||
void* makeVertexSpace(size_t vertexSize, int vertexCount, const GrBuffer**,
|
||||
int* startVertex) final;
|
||||
uint16_t* makeIndexSpace(int indexCount, const GrBuffer**, int* startIndex) final;
|
||||
@ -123,12 +125,13 @@ private:
|
||||
fFixedDynamicState->fPrimitiveProcessorTextures[i]->completedRead();
|
||||
}
|
||||
}
|
||||
int fMeshCnt = 0;
|
||||
sk_sp<const GrGeometryProcessor> fGeometryProcessor;
|
||||
const GrPipeline* fPipeline;
|
||||
const GrPipeline* fPipeline = nullptr;
|
||||
const GrPipeline::FixedDynamicState* fFixedDynamicState;
|
||||
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.
|
||||
@ -142,9 +145,6 @@ private:
|
||||
SkArenaAllocList<GrDeferredTextureUploadFn> fASAPUploads;
|
||||
SkArenaAllocList<InlineUpload> fInlineUploads;
|
||||
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
|
||||
// in fDraws.
|
||||
@ -161,7 +161,6 @@ private:
|
||||
|
||||
// Variables that are used to track where we are in lists as ops are executed
|
||||
SkArenaAllocList<Draw>::Iter fCurrDraw;
|
||||
int fCurrMesh;
|
||||
SkArenaAllocList<InlineUpload>::Iter fCurrUpload;
|
||||
|
||||
// Used to track the proxies that need to be uninstantiated after we finish a flush
|
||||
|
@ -843,10 +843,10 @@ private:
|
||||
extract_lines_only_verts(tess, verts, vertexStride, args.fColor, idxs,
|
||||
fHelper.compatibleWithAlphaAsCoverage());
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, tess.numIndices(), firstIndex, 0, tess.numPts() - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(gp, pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
}
|
||||
@ -928,17 +928,18 @@ private:
|
||||
SkSTArray<kPreallocDrawCnt, Draw, true> draws;
|
||||
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) {
|
||||
const Draw& draw = draws[j];
|
||||
mesh.setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0, draw.fVertexCnt - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
meshes[j].setPrimitiveType(GrPrimitiveType::kTriangles);
|
||||
meshes[j].setIndexed(indexBuffer, draw.fIndexCnt, firstIndex, 0,
|
||||
draw.fVertexCnt - 1, GrPrimitiveRestart::kNo);
|
||||
meshes[j].setVertexData(vertexBuffer, firstVertex);
|
||||
firstIndex += draw.fIndexCnt;
|
||||
firstVertex += draw.fVertexCnt;
|
||||
}
|
||||
target->draw(quadProcessor, pipe.fPipeline, pipe.fFixedDynamicState, meshes,
|
||||
draws.count());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -265,10 +265,9 @@ private:
|
||||
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
|
||||
|
||||
sk_sp<const GrBuffer> indexBuffer = get_index_buffer(target->resourceProvider());
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
void* vertices =
|
||||
helper.init(target, vertexStride, indexBuffer.get(), kVertsPerAAFillRect,
|
||||
kIndicesPerAAFillRect, fRectCnt);
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
|
||||
kVertsPerAAFillRect, kIndicesPerAAFillRect, fRectCnt);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -975,10 +975,10 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
|
||||
add_line(&lines[2*i], toSrc, this->coverage(), &verts);
|
||||
}
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexedPatterned(linesIndexBuffer.get(), kIdxsPerLineSeg, kLineSegNumVertices,
|
||||
lineCount, kLineSegsNumInIdxBuffer);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexedPatterned(linesIndexBuffer.get(), kIdxsPerLineSeg, kLineSegNumVertices,
|
||||
lineCount, kLineSegsNumInIdxBuffer);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(std::move(lineGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
@ -1030,19 +1030,19 @@ void AAHairlineOp::onPrepareDraws(Target* target) {
|
||||
}
|
||||
|
||||
if (quadCount > 0) {
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
|
||||
quadCount, kQuadsNumInIdxBuffer);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
|
||||
quadCount, kQuadsNumInIdxBuffer);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(std::move(quadGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
firstVertex += quadCount * kQuadNumVertices;
|
||||
}
|
||||
|
||||
if (conicCount > 0) {
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
|
||||
conicCount, kQuadsNumInIdxBuffer);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexedPatterned(quadsIndexBuffer.get(), kIdxsPerQuad, kQuadNumVertices,
|
||||
conicCount, kQuadsNumInIdxBuffer);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(std::move(conicGP), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,6 @@ private:
|
||||
return;
|
||||
}
|
||||
const GrBuffer* vertexBuffer;
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
int firstVertex;
|
||||
void* verts = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer,
|
||||
&firstVertex);
|
||||
@ -235,9 +234,10 @@ private:
|
||||
return;
|
||||
}
|
||||
memcpy(idxs, indices, indexCount * sizeof(uint16_t));
|
||||
mesh.setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, indexCount, firstIndex, 0, vertexCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(std::move(gp), pipeline, fixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
|
@ -282,11 +282,11 @@ void AAStrokeRectOp::onPrepareDraws(Target* target) {
|
||||
int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt;
|
||||
int instanceCount = fRects.count();
|
||||
|
||||
sk_sp<const GrBuffer> indexBuffer = GetIndexBuffer(target->resourceProvider(), this->miterStroke());
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
void* vertices =
|
||||
helper.init(target, vertexStride, indexBuffer.get(),
|
||||
verticesPerInstance, indicesPerInstance, instanceCount);
|
||||
sk_sp<const GrBuffer> indexBuffer =
|
||||
GetIndexBuffer(target->resourceProvider(), this->miterStroke());
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
|
||||
verticesPerInstance, indicesPerInstance, instanceCount);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -425,12 +425,12 @@ void GrAtlasTextOp::flush(GrMeshDrawOp::Target* target, FlushInfo* flushInfo) co
|
||||
samplerState);
|
||||
}
|
||||
}
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
int maxGlyphsPerDraw =
|
||||
static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
|
||||
mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph,
|
||||
flushInfo->fGlyphsToFlush, maxGlyphsPerDraw);
|
||||
mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerGlyph, kVerticesPerGlyph,
|
||||
flushInfo->fGlyphsToFlush, maxGlyphsPerDraw);
|
||||
mesh->setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
|
||||
target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline, flushInfo->fFixedDynamicState,
|
||||
mesh);
|
||||
flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlush;
|
||||
|
@ -625,7 +625,6 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
QuadHelper helper;
|
||||
size_t vertexStride;
|
||||
if (fullDash) {
|
||||
vertexStride =
|
||||
@ -634,7 +633,8 @@ private:
|
||||
vertexStride = sizeof(SkPoint);
|
||||
}
|
||||
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
|
||||
void* vertices = helper.init(target, vertexStride, totalRectCount);
|
||||
QuadHelper helper(target, vertexStride, totalRectCount);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices) {
|
||||
return;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
PathGeoBuilder(GrPrimitiveType primitiveType, GrMeshDrawOp::Target* target,
|
||||
sk_sp<const GrGeometryProcessor> geometryProcessor, const GrPipeline* pipeline,
|
||||
const GrPipeline::FixedDynamicState* fixedDynamicState)
|
||||
: fMesh(primitiveType)
|
||||
: fPrimitiveType(primitiveType)
|
||||
, fTarget(target)
|
||||
, fVertexStride(sizeof(SkPoint))
|
||||
, fGeometryProcessor(std::move(geometryProcessor))
|
||||
@ -200,15 +200,15 @@ private:
|
||||
* TODO: Cache some of these for better performance, rather than re-computing?
|
||||
*/
|
||||
bool isIndexed() const {
|
||||
return GrPrimitiveType::kLines == fMesh.primitiveType() ||
|
||||
GrPrimitiveType::kTriangles == fMesh.primitiveType();
|
||||
return GrPrimitiveType::kLines == fPrimitiveType ||
|
||||
GrPrimitiveType::kTriangles == fPrimitiveType;
|
||||
}
|
||||
bool isHairline() const {
|
||||
return GrPrimitiveType::kLines == fMesh.primitiveType() ||
|
||||
GrPrimitiveType::kLineStrip == fMesh.primitiveType();
|
||||
return GrPrimitiveType::kLines == fPrimitiveType ||
|
||||
GrPrimitiveType::kLineStrip == fPrimitiveType;
|
||||
}
|
||||
int indexScale() const {
|
||||
switch (fMesh.primitiveType()) {
|
||||
switch (fPrimitiveType) {
|
||||
case GrPrimitiveType::kLines:
|
||||
return 2;
|
||||
case GrPrimitiveType::kTriangles:
|
||||
@ -271,14 +271,15 @@ private:
|
||||
SkASSERT(indexCount <= fIndicesInChunk);
|
||||
|
||||
if (this->isIndexed() ? SkToBool(indexCount) : SkToBool(vertexCount)) {
|
||||
GrMesh* mesh = fTarget->allocMesh(fPrimitiveType);
|
||||
if (!this->isIndexed()) {
|
||||
fMesh.setNonIndexedNonInstanced(vertexCount);
|
||||
mesh->setNonIndexedNonInstanced(vertexCount);
|
||||
} else {
|
||||
fMesh.setIndexed(fIndexBuffer, indexCount, fFirstIndex, 0, vertexCount - 1,
|
||||
mesh->setIndexed(fIndexBuffer, indexCount, fFirstIndex, 0, vertexCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
}
|
||||
fMesh.setVertexData(fVertexBuffer, fFirstVertex);
|
||||
fTarget->draw(fGeometryProcessor, fPipeline, fFixedDynamicState, fMesh);
|
||||
mesh->setVertexData(fVertexBuffer, fFirstVertex);
|
||||
fTarget->draw(fGeometryProcessor, fPipeline, fFixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
fTarget->putBackIndices((size_t)(fIndicesInChunk - indexCount));
|
||||
@ -311,7 +312,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
GrMesh fMesh;
|
||||
GrPrimitiveType fPrimitiveType;
|
||||
GrMeshDrawOp::Target* fTarget;
|
||||
size_t fVertexStride;
|
||||
sk_sp<const GrGeometryProcessor> fGeometryProcessor;
|
||||
|
@ -130,9 +130,9 @@ void GrDrawAtlasOp::onPrepareDraws(Target* target) {
|
||||
sizeof(SkPoint) + sizeof(SkPoint) + (this->hasColors() ? sizeof(GrColor) : 0);
|
||||
SkASSERT(vertexStride == gp->debugOnly_vertexStride());
|
||||
|
||||
QuadHelper helper;
|
||||
int numQuads = this->quadCount();
|
||||
void* verts = helper.init(target, vertexStride, numQuads);
|
||||
QuadHelper helper(target, vertexStride, numQuads);
|
||||
void* verts = helper.vertices();
|
||||
if (!verts) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -470,15 +470,14 @@ void GrDrawVerticesOp::drawVertices(Target* target,
|
||||
int firstVertex,
|
||||
const GrBuffer* indexBuffer,
|
||||
int firstIndex) {
|
||||
GrMesh mesh(this->primitiveType());
|
||||
GrMesh* mesh = target->allocMesh(this->primitiveType());
|
||||
if (this->isIndexed()) {
|
||||
mesh.setIndexed(indexBuffer, fIndexCount,
|
||||
firstIndex, 0, fVertexCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
} else {
|
||||
mesh.setNonIndexedNonInstanced(fVertexCount);
|
||||
mesh->setNonIndexedNonInstanced(fVertexCount);
|
||||
}
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
|
@ -223,9 +223,9 @@ private:
|
||||
}
|
||||
|
||||
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
void* vertices = helper.init(target, kVertexStide, indexBuffer.get(), kVertsPerRect,
|
||||
kIndicesPerRect, numRects);
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStide, indexBuffer.get(),
|
||||
kVertsPerRect, kIndicesPerRect, numRects);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -14,50 +14,61 @@ GrMeshDrawOp::GrMeshDrawOp(uint32_t classID) : INHERITED(classID) {}
|
||||
|
||||
void GrMeshDrawOp::onPrepare(GrOpFlushState* state) { this->onPrepareDraws(state); }
|
||||
|
||||
void* GrMeshDrawOp::PatternHelper::init(Target* target, size_t vertexStride,
|
||||
const GrBuffer* indexBuffer, int verticesPerRepetition,
|
||||
int indicesPerRepetition, int repeatCount) {
|
||||
void GrMeshDrawOp::onExecute(GrOpFlushState* state) {
|
||||
state->executeDrawsAndUploadsForMeshDrawOp(this->uniqueID(), this->bounds());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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);
|
||||
if (!indexBuffer) {
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
const GrBuffer* vertexBuffer;
|
||||
int firstVertex;
|
||||
int vertexCount = verticesPerRepetition * repeatCount;
|
||||
void* vertices =
|
||||
target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
|
||||
if (!vertices) {
|
||||
SkDebugf("Vertices could not be allocated for instanced rendering.");
|
||||
return nullptr;
|
||||
fVertices = target->makeVertexSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex);
|
||||
if (!fVertices) {
|
||||
SkDebugf("Vertices could not be allocated for patterned rendering.");
|
||||
return;
|
||||
}
|
||||
SkASSERT(vertexBuffer);
|
||||
size_t ibSize = indexBuffer->gpuMemorySize();
|
||||
int maxRepetitions = static_cast<int>(ibSize / (sizeof(uint16_t) * indicesPerRepetition));
|
||||
|
||||
fMesh.setIndexedPatterned(indexBuffer, indicesPerRepetition, verticesPerRepetition,
|
||||
repeatCount, maxRepetitions);
|
||||
fMesh.setVertexData(vertexBuffer, firstVertex);
|
||||
return vertices;
|
||||
fMesh = target->allocMesh(primitiveType);
|
||||
fMesh->setIndexedPatterned(indexBuffer, indicesPerRepetition, verticesPerRepetition,
|
||||
repeatCount, maxRepetitions);
|
||||
fMesh->setVertexData(vertexBuffer, firstVertex);
|
||||
}
|
||||
|
||||
void GrMeshDrawOp::PatternHelper::recordDraw(
|
||||
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);
|
||||
}
|
||||
|
||||
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();
|
||||
if (!quadIndexBuffer) {
|
||||
SkDebugf("Could not get quad index buffer.");
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
return this->INHERITED::init(target, vertexStride, quadIndexBuffer.get(), kVerticesPerQuad,
|
||||
kIndicesPerQuad, quadsToDraw);
|
||||
}
|
||||
|
||||
void GrMeshDrawOp::onExecute(GrOpFlushState* state) {
|
||||
state->executeDrawsAndUploadsForMeshDrawOp(this->uniqueID(), this->bounds());
|
||||
this->init(target, GrPrimitiveType::kTriangles, vertexStride, quadIndexBuffer.get(),
|
||||
kVerticesPerQuad, kIndicesPerQuad, quadsToDraw);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,18 +33,23 @@ protected:
|
||||
space for the vertices and flushes the draws to the GrMeshDrawOp::Target. */
|
||||
class PatternHelper {
|
||||
public:
|
||||
PatternHelper(GrPrimitiveType primitiveType) : fMesh(primitiveType) {}
|
||||
/** Returns the allocated storage for the vertices. The caller should populate the vertices
|
||||
before calling recordDraws(). */
|
||||
void* init(Target*, size_t vertexStride, const GrBuffer*, int verticesPerRepetition,
|
||||
int indicesPerRepetition, int repeatCount);
|
||||
PatternHelper(Target*, GrPrimitiveType, 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*,
|
||||
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:
|
||||
GrMesh fMesh;
|
||||
void* fVertices = nullptr;
|
||||
GrMesh* fMesh = nullptr;
|
||||
};
|
||||
|
||||
static const int kVerticesPerQuad = 4;
|
||||
@ -53,13 +58,11 @@ protected:
|
||||
/** A specialization of InstanceHelper for quad rendering. */
|
||||
class QuadHelper : private PatternHelper {
|
||||
public:
|
||||
QuadHelper() : INHERITED(GrPrimitiveType::kTriangles) {}
|
||||
/** Finds the cached quad index buffer and reserves vertex space. Returns nullptr on failure
|
||||
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);
|
||||
QuadHelper() = delete;
|
||||
QuadHelper(Target* target, size_t vertexStride, int quadsToDraw);
|
||||
|
||||
using PatternHelper::recordDraw;
|
||||
using PatternHelper::vertices;
|
||||
|
||||
private:
|
||||
typedef PatternHelper INHERITED;
|
||||
@ -77,8 +80,19 @@ public:
|
||||
virtual ~Target() {}
|
||||
|
||||
/** Adds a draw of a mesh. */
|
||||
virtual void draw(sk_sp<const GrGeometryProcessor>, const GrPipeline*,
|
||||
const GrPipeline::FixedDynamicState*, const GrMesh&) = 0;
|
||||
virtual void draw(sk_sp<const GrGeometryProcessor>,
|
||||
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
|
||||
@ -131,6 +145,12 @@ public:
|
||||
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,
|
||||
int numPrimitiveProcessorTextures = 0) {
|
||||
auto result = this->pipelineArena()->make<GrPipeline::FixedDynamicState>(rect);
|
||||
|
@ -192,9 +192,9 @@ private:
|
||||
int rectCount = fRects.count();
|
||||
|
||||
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerRect,
|
||||
kIndicesPerRect, rectCount);
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStride, indexBuffer.get(),
|
||||
kVertsPerRect, kIndicesPerRect, rectCount);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
@ -325,9 +325,9 @@ private:
|
||||
int rectCount = fRects.count();
|
||||
|
||||
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
void* vertices = helper.init(target, vertexStride, indexBuffer.get(), kVertsPerRect,
|
||||
kIndicesPerRect, rectCount);
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
|
||||
kVertsPerRect, kIndicesPerRect, rectCount);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -188,9 +188,9 @@ private:
|
||||
vertex[4].set(fRect.fLeft, fRect.fTop);
|
||||
}
|
||||
|
||||
GrMesh mesh(primType);
|
||||
mesh.setNonIndexedNonInstanced(vertexCount);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(primType);
|
||||
mesh->setNonIndexedNonInstanced(vertexCount);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
|
@ -1470,10 +1470,10 @@ private:
|
||||
vertices += circle_type_to_vert_count(circle.fStroked) * vertexStride;
|
||||
}
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
@ -1786,10 +1786,10 @@ private:
|
||||
vertices += circle_type_to_vert_count(true) * kVertexStride;
|
||||
}
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
@ -1984,10 +1984,9 @@ private:
|
||||
// Setup geometry processor
|
||||
sk_sp<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix));
|
||||
|
||||
QuadHelper helper;
|
||||
SkASSERT(sizeof(EllipseVertex) == gp->debugOnly_vertexStride());
|
||||
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
|
||||
helper.init(target, sizeof(EllipseVertex), fEllipses.count()));
|
||||
QuadHelper helper(target, sizeof(EllipseVertex), fEllipses.count());
|
||||
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(helper.vertices());
|
||||
if (!verts) {
|
||||
return;
|
||||
}
|
||||
@ -2219,9 +2218,8 @@ private:
|
||||
new DIEllipseGeometryProcessor(this->viewMatrix(), this->style()));
|
||||
|
||||
SkASSERT(sizeof(DIEllipseVertex) == gp->debugOnly_vertexStride());
|
||||
QuadHelper helper;
|
||||
DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(
|
||||
helper.init(target, sizeof(DIEllipseVertex), fEllipses.count()));
|
||||
QuadHelper helper(target, sizeof(DIEllipseVertex), fEllipses.count());
|
||||
DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(helper.vertices());
|
||||
if (!verts) {
|
||||
return;
|
||||
}
|
||||
@ -2725,10 +2723,10 @@ private:
|
||||
currStartVertex += rrect_type_to_vert_count(rrect.fType);
|
||||
}
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
@ -2927,10 +2925,10 @@ private:
|
||||
sk_sp<const GrBuffer> indexBuffer = get_rrect_index_buffer(
|
||||
fStroked ? kStroke_RRectType : kFill_RRectType, target->resourceProvider());
|
||||
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(
|
||||
helper.init(target, sizeof(EllipseVertex), indexBuffer.get(),
|
||||
kVertsPerStandardRRect, indicesPerInstance, fRRects.count()));
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, sizeof(EllipseVertex),
|
||||
indexBuffer.get(), kVertsPerStandardRRect, indicesPerInstance,
|
||||
fRRects.count());
|
||||
EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(helper.vertices());
|
||||
if (!verts || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -129,9 +129,9 @@ private:
|
||||
return;
|
||||
}
|
||||
sk_sp<const GrBuffer> indexBuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
PatternHelper helper(GrPrimitiveType::kTriangles);
|
||||
void* vertices = helper.init(target, kVertexStride, indexBuffer.get(), kVertsPerInstance,
|
||||
kIndicesPerInstance, numRects);
|
||||
PatternHelper helper(target, GrPrimitiveType::kTriangles, kVertexStride, indexBuffer.get(),
|
||||
kVertsPerInstance, kIndicesPerInstance, numRects);
|
||||
void* vertices = helper.vertices();
|
||||
if (!vertices || !indexBuffer) {
|
||||
SkDebugf("Could not allocate vertices\n");
|
||||
return;
|
||||
|
@ -627,10 +627,10 @@ private:
|
||||
auto pipe = target->makePipeline(kPipelineFlags, GrProcessorSet::MakeEmptySet(),
|
||||
target->detachAppliedClip());
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertCount - 1,
|
||||
GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
|
@ -833,13 +833,13 @@ private:
|
||||
}
|
||||
|
||||
if (flushInfo->fInstancesToFlush) {
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
int maxInstancesPerDraw =
|
||||
static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(uint16_t) / 6);
|
||||
mesh.setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerQuad,
|
||||
kVerticesPerQuad, flushInfo->fInstancesToFlush,
|
||||
maxInstancesPerDraw);
|
||||
mesh.setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
|
||||
mesh->setIndexedPatterned(flushInfo->fIndexBuffer.get(), kIndicesPerQuad,
|
||||
kVerticesPerQuad, flushInfo->fInstancesToFlush,
|
||||
maxInstancesPerDraw);
|
||||
mesh->setVertexData(flushInfo->fVertexBuffer.get(), flushInfo->fVertexOffset);
|
||||
target->draw(flushInfo->fGeometryProcessor, flushInfo->fPipeline,
|
||||
flushInfo->fFixedDynamicState, mesh);
|
||||
flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFlush;
|
||||
|
@ -358,9 +358,10 @@ private:
|
||||
|
||||
void drawVertices(Target* target, sk_sp<const GrGeometryProcessor> gp, const GrBuffer* vb,
|
||||
int firstVertex, int count) {
|
||||
GrMesh mesh(TESSELLATOR_WIREFRAME ? GrPrimitiveType::kLines : GrPrimitiveType::kTriangles);
|
||||
mesh.setNonIndexedNonInstanced(count);
|
||||
mesh.setVertexData(vb, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(TESSELLATOR_WIREFRAME ? GrPrimitiveType::kLines
|
||||
: GrPrimitiveType::kTriangles);
|
||||
mesh->setNonIndexedNonInstanced(count);
|
||||
mesh->setVertexData(vb, firstVertex);
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
}
|
||||
|
@ -858,19 +858,19 @@ __attribute__((no_sanitize("float-cast-overflow")))
|
||||
|
||||
GrPrimitiveType primitiveType =
|
||||
fDraws.count() > 1 ? GrPrimitiveType::kTriangles : GrPrimitiveType::kTriangleStrip;
|
||||
GrMesh mesh(primitiveType);
|
||||
GrMesh* mesh = target->allocMesh(primitiveType);
|
||||
if (fDraws.count() > 1) {
|
||||
sk_sp<const GrBuffer> ibuffer = target->resourceProvider()->refQuadIndexBuffer();
|
||||
if (!ibuffer) {
|
||||
SkDebugf("Could not allocate quad indices\n");
|
||||
return;
|
||||
}
|
||||
mesh.setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(),
|
||||
GrResourceProvider::QuadCountOfQuadBuffer());
|
||||
mesh->setIndexedPatterned(ibuffer.get(), 6, 4, fDraws.count(),
|
||||
GrResourceProvider::QuadCountOfQuadBuffer());
|
||||
} else {
|
||||
mesh.setNonIndexedNonInstanced(4);
|
||||
mesh->setNonIndexedNonInstanced(4);
|
||||
}
|
||||
mesh.setVertexData(vbuffer, vstart);
|
||||
mesh->setVertexData(vbuffer, vstart);
|
||||
target->draw(std::move(gp), pipeline, fixedDynamicState, mesh);
|
||||
}
|
||||
|
||||
|
@ -159,9 +159,9 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
GrMesh mesh(GrPrimitiveType::kTriangles);
|
||||
mesh.setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo);
|
||||
mesh.setVertexData(vertexBuffer, firstVertex);
|
||||
GrMesh* mesh = target->allocMesh(GrPrimitiveType::kTriangles);
|
||||
mesh->setIndexed(indexBuffer, 6, firstIndex, 0, 3, GrPrimitiveRestart::kNo);
|
||||
mesh->setVertexData(vertexBuffer, firstVertex);
|
||||
|
||||
auto pipe = fHelper.makePipeline(target);
|
||||
target->draw(std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
|
||||
|
@ -105,10 +105,10 @@ private:
|
||||
typedef GrGeometryProcessor INHERITED;
|
||||
};
|
||||
sk_sp<GrGeometryProcessor> gp(new GP(fNumAttribs));
|
||||
QuadHelper helper;
|
||||
size_t vertexStride = fNumAttribs * GrVertexAttribTypeSize(kFloat2_GrVertexAttribType);
|
||||
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);
|
||||
auto pipe = target->makePipeline(0, GrProcessorSet::MakeEmptySet(),
|
||||
target->detachAppliedClip());
|
||||
|
Loading…
Reference in New Issue
Block a user