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);
|
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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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()); }
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
|
Loading…
Reference in New Issue
Block a user