Create indirect index buffer for tessellation during onPrepare
Change-Id: I78d74976fa2252da2a40862c241a99b68d27fb40 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292259 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
This commit is contained in:
parent
66cfc1c637
commit
1443c9df58
@ -34,6 +34,26 @@ static SkPath make_cubic_path() {
|
||||
// pre-allocated CPU buffers, rather than allocating and mapping GPU buffers.
|
||||
class BenchmarkTarget : public GrMeshDrawOp::Target {
|
||||
public:
|
||||
BenchmarkTarget() {
|
||||
GrMockOptions mockOptions;
|
||||
mockOptions.fDrawInstancedSupport = true;
|
||||
mockOptions.fTessellationSupport = true;
|
||||
mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag;
|
||||
mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fRenderability =
|
||||
GrMockOptions::ConfigOptions::Renderability::kMSAA;
|
||||
mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fTexturable = true;
|
||||
mockOptions.fIntegerSupport = true;
|
||||
|
||||
GrContextOptions ctxOptions;
|
||||
ctxOptions.fGpuPathRenderers = GpuPathRenderers::kTessellation;
|
||||
|
||||
fMockContext = GrContext::MakeMock(&mockOptions, ctxOptions);
|
||||
}
|
||||
const GrContext* mockContext() const { return fMockContext.get(); }
|
||||
const GrCaps& caps() const override { return *fMockContext->priv().caps(); }
|
||||
GrResourceProvider* resourceProvider() const override {
|
||||
return fMockContext->priv().resourceProvider();
|
||||
}
|
||||
void resetAllocator() { fAllocator.reset(); }
|
||||
SkArenaAlloc* allocator() override { return &fAllocator; }
|
||||
void putBackVertices(int vertices, size_t vertexStride) override { /* no-op */ }
|
||||
@ -73,15 +93,14 @@ public:
|
||||
UNIMPL(const GrAppliedClip* appliedClip() const)
|
||||
UNIMPL(GrAppliedClip detachAppliedClip())
|
||||
UNIMPL(const GrXferProcessor::DstProxyView& dstProxyView() const)
|
||||
UNIMPL(GrResourceProvider* resourceProvider() const)
|
||||
UNIMPL(GrStrikeCache* strikeCache() const)
|
||||
UNIMPL(GrAtlasManager* atlasManager() const)
|
||||
UNIMPL(SkTArray<GrSurfaceProxy*, true>* sampledProxyArray())
|
||||
UNIMPL(const GrCaps& caps() const)
|
||||
UNIMPL(GrDeferredUploadTarget* deferredUploadTarget())
|
||||
#undef UNIMPL
|
||||
|
||||
private:
|
||||
sk_sp<GrContext> fMockContext;
|
||||
SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 8];
|
||||
GrDrawIndexedIndirectCommand fStaticDrawIndexedIndirectData[32];
|
||||
SkSTArenaAlloc<1024 * 1024> fAllocator;
|
||||
@ -110,6 +129,10 @@ public:
|
||||
|
||||
private:
|
||||
void onDraw(int loops, SkCanvas*) final {
|
||||
if (!fTarget.mockContext()) {
|
||||
SkDebugf("ERROR: could not create mock context.");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < loops; ++i) {
|
||||
fOp.fTriangleBuffer.reset();
|
||||
fOp.fDoStencilTriangleBuffer = false;
|
||||
|
@ -275,10 +275,17 @@ void GrTessellatePathOp::prepareIndirectOuterCubics(
|
||||
void GrTessellatePathOp::prepareIndirectOuterCubicsAndTriangles(
|
||||
GrMeshDrawOp::Target* target, const GrResolveLevelCounter& resolveLevelCounter,
|
||||
SkPoint* cubicData, int numTrianglesAtBeginningOfData) {
|
||||
SkASSERT(target->caps().drawInstancedSupport());
|
||||
SkASSERT(numTrianglesAtBeginningOfData + resolveLevelCounter.totalCubicInstanceCount() > 0);
|
||||
SkASSERT(!fStencilCubicsShader);
|
||||
SkASSERT(cubicData);
|
||||
|
||||
fIndirectIndexBuffer = GrMiddleOutCubicShader::FindOrMakeMiddleOutIndexBuffer(
|
||||
target->resourceProvider());
|
||||
if (!fIndirectIndexBuffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Here we treat fCubicBuffer as an instance buffer. It should have been prepared with the base
|
||||
// vertex on an instance boundary in order to accommodate this.
|
||||
SkASSERT(fBaseCubicVertex % 4 == 0);
|
||||
@ -378,6 +385,7 @@ void GrTessellatePathOp::prepareIndirectOuterCubicsAndTriangles(
|
||||
|
||||
void GrTessellatePathOp::prepareTessellatedOuterCubics(GrMeshDrawOp::Target* target,
|
||||
int numCountedCurves) {
|
||||
SkASSERT(target->caps().shaderCaps()->tessellationSupport());
|
||||
SkASSERT(numCountedCurves >= 0);
|
||||
SkASSERT(!fCubicBuffer);
|
||||
SkASSERT(!fStencilCubicsShader);
|
||||
@ -414,6 +422,7 @@ void GrTessellatePathOp::prepareTessellatedOuterCubics(GrMeshDrawOp::Target* tar
|
||||
}
|
||||
|
||||
void GrTessellatePathOp::prepareTessellatedCubicWedges(GrMeshDrawOp::Target* target) {
|
||||
SkASSERT(target->caps().shaderCaps()->tessellationSupport());
|
||||
SkASSERT(!fCubicBuffer);
|
||||
SkASSERT(!fStencilCubicsShader);
|
||||
|
||||
@ -531,9 +540,8 @@ void GrTessellatePathOp::drawStencilPass(GrOpFlushState* flushState) {
|
||||
fStencilCubicsShader);
|
||||
flushState->bindPipelineAndScissorClip(programInfo, this->bounds());
|
||||
if (fIndirectDrawBuffer) {
|
||||
auto indexBuffer = GrMiddleOutCubicShader::FindOrMakeMiddleOutIndexBuffer(
|
||||
flushState->resourceProvider());
|
||||
flushState->bindBuffers(indexBuffer.get(), fCubicBuffer.get(), nullptr);
|
||||
SkASSERT(fIndirectIndexBuffer);
|
||||
flushState->bindBuffers(fIndirectIndexBuffer.get(), fCubicBuffer.get(), nullptr);
|
||||
flushState->drawIndexedIndirect(fIndirectDrawBuffer.get(), fIndirectDrawOffset,
|
||||
fIndirectDrawCount);
|
||||
} else {
|
||||
|
@ -160,6 +160,7 @@ private:
|
||||
sk_sp<const GrBuffer> fIndirectDrawBuffer;
|
||||
size_t fIndirectDrawOffset;
|
||||
int fIndirectDrawCount;
|
||||
sk_sp<const GrBuffer> fIndirectIndexBuffer;
|
||||
|
||||
friend class GrOpMemoryPool; // For ctor.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user