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.
|
// pre-allocated CPU buffers, rather than allocating and mapping GPU buffers.
|
||||||
class BenchmarkTarget : public GrMeshDrawOp::Target {
|
class BenchmarkTarget : public GrMeshDrawOp::Target {
|
||||||
public:
|
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(); }
|
void resetAllocator() { fAllocator.reset(); }
|
||||||
SkArenaAlloc* allocator() override { return &fAllocator; }
|
SkArenaAlloc* allocator() override { return &fAllocator; }
|
||||||
void putBackVertices(int vertices, size_t vertexStride) override { /* no-op */ }
|
void putBackVertices(int vertices, size_t vertexStride) override { /* no-op */ }
|
||||||
@ -73,15 +93,14 @@ public:
|
|||||||
UNIMPL(const GrAppliedClip* appliedClip() const)
|
UNIMPL(const GrAppliedClip* appliedClip() const)
|
||||||
UNIMPL(GrAppliedClip detachAppliedClip())
|
UNIMPL(GrAppliedClip detachAppliedClip())
|
||||||
UNIMPL(const GrXferProcessor::DstProxyView& dstProxyView() const)
|
UNIMPL(const GrXferProcessor::DstProxyView& dstProxyView() const)
|
||||||
UNIMPL(GrResourceProvider* resourceProvider() const)
|
|
||||||
UNIMPL(GrStrikeCache* strikeCache() const)
|
UNIMPL(GrStrikeCache* strikeCache() const)
|
||||||
UNIMPL(GrAtlasManager* atlasManager() const)
|
UNIMPL(GrAtlasManager* atlasManager() const)
|
||||||
UNIMPL(SkTArray<GrSurfaceProxy*, true>* sampledProxyArray())
|
UNIMPL(SkTArray<GrSurfaceProxy*, true>* sampledProxyArray())
|
||||||
UNIMPL(const GrCaps& caps() const)
|
|
||||||
UNIMPL(GrDeferredUploadTarget* deferredUploadTarget())
|
UNIMPL(GrDeferredUploadTarget* deferredUploadTarget())
|
||||||
#undef UNIMPL
|
#undef UNIMPL
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
sk_sp<GrContext> fMockContext;
|
||||||
SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 8];
|
SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 8];
|
||||||
GrDrawIndexedIndirectCommand fStaticDrawIndexedIndirectData[32];
|
GrDrawIndexedIndirectCommand fStaticDrawIndexedIndirectData[32];
|
||||||
SkSTArenaAlloc<1024 * 1024> fAllocator;
|
SkSTArenaAlloc<1024 * 1024> fAllocator;
|
||||||
@ -110,6 +129,10 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void onDraw(int loops, SkCanvas*) final {
|
void onDraw(int loops, SkCanvas*) final {
|
||||||
|
if (!fTarget.mockContext()) {
|
||||||
|
SkDebugf("ERROR: could not create mock context.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
for (int i = 0; i < loops; ++i) {
|
for (int i = 0; i < loops; ++i) {
|
||||||
fOp.fTriangleBuffer.reset();
|
fOp.fTriangleBuffer.reset();
|
||||||
fOp.fDoStencilTriangleBuffer = false;
|
fOp.fDoStencilTriangleBuffer = false;
|
||||||
|
@ -275,10 +275,17 @@ void GrTessellatePathOp::prepareIndirectOuterCubics(
|
|||||||
void GrTessellatePathOp::prepareIndirectOuterCubicsAndTriangles(
|
void GrTessellatePathOp::prepareIndirectOuterCubicsAndTriangles(
|
||||||
GrMeshDrawOp::Target* target, const GrResolveLevelCounter& resolveLevelCounter,
|
GrMeshDrawOp::Target* target, const GrResolveLevelCounter& resolveLevelCounter,
|
||||||
SkPoint* cubicData, int numTrianglesAtBeginningOfData) {
|
SkPoint* cubicData, int numTrianglesAtBeginningOfData) {
|
||||||
|
SkASSERT(target->caps().drawInstancedSupport());
|
||||||
SkASSERT(numTrianglesAtBeginningOfData + resolveLevelCounter.totalCubicInstanceCount() > 0);
|
SkASSERT(numTrianglesAtBeginningOfData + resolveLevelCounter.totalCubicInstanceCount() > 0);
|
||||||
SkASSERT(!fStencilCubicsShader);
|
SkASSERT(!fStencilCubicsShader);
|
||||||
SkASSERT(cubicData);
|
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
|
// 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.
|
// vertex on an instance boundary in order to accommodate this.
|
||||||
SkASSERT(fBaseCubicVertex % 4 == 0);
|
SkASSERT(fBaseCubicVertex % 4 == 0);
|
||||||
@ -378,6 +385,7 @@ void GrTessellatePathOp::prepareIndirectOuterCubicsAndTriangles(
|
|||||||
|
|
||||||
void GrTessellatePathOp::prepareTessellatedOuterCubics(GrMeshDrawOp::Target* target,
|
void GrTessellatePathOp::prepareTessellatedOuterCubics(GrMeshDrawOp::Target* target,
|
||||||
int numCountedCurves) {
|
int numCountedCurves) {
|
||||||
|
SkASSERT(target->caps().shaderCaps()->tessellationSupport());
|
||||||
SkASSERT(numCountedCurves >= 0);
|
SkASSERT(numCountedCurves >= 0);
|
||||||
SkASSERT(!fCubicBuffer);
|
SkASSERT(!fCubicBuffer);
|
||||||
SkASSERT(!fStencilCubicsShader);
|
SkASSERT(!fStencilCubicsShader);
|
||||||
@ -414,6 +422,7 @@ void GrTessellatePathOp::prepareTessellatedOuterCubics(GrMeshDrawOp::Target* tar
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GrTessellatePathOp::prepareTessellatedCubicWedges(GrMeshDrawOp::Target* target) {
|
void GrTessellatePathOp::prepareTessellatedCubicWedges(GrMeshDrawOp::Target* target) {
|
||||||
|
SkASSERT(target->caps().shaderCaps()->tessellationSupport());
|
||||||
SkASSERT(!fCubicBuffer);
|
SkASSERT(!fCubicBuffer);
|
||||||
SkASSERT(!fStencilCubicsShader);
|
SkASSERT(!fStencilCubicsShader);
|
||||||
|
|
||||||
@ -531,9 +540,8 @@ void GrTessellatePathOp::drawStencilPass(GrOpFlushState* flushState) {
|
|||||||
fStencilCubicsShader);
|
fStencilCubicsShader);
|
||||||
flushState->bindPipelineAndScissorClip(programInfo, this->bounds());
|
flushState->bindPipelineAndScissorClip(programInfo, this->bounds());
|
||||||
if (fIndirectDrawBuffer) {
|
if (fIndirectDrawBuffer) {
|
||||||
auto indexBuffer = GrMiddleOutCubicShader::FindOrMakeMiddleOutIndexBuffer(
|
SkASSERT(fIndirectIndexBuffer);
|
||||||
flushState->resourceProvider());
|
flushState->bindBuffers(fIndirectIndexBuffer.get(), fCubicBuffer.get(), nullptr);
|
||||||
flushState->bindBuffers(indexBuffer.get(), fCubicBuffer.get(), nullptr);
|
|
||||||
flushState->drawIndexedIndirect(fIndirectDrawBuffer.get(), fIndirectDrawOffset,
|
flushState->drawIndexedIndirect(fIndirectDrawBuffer.get(), fIndirectDrawOffset,
|
||||||
fIndirectDrawCount);
|
fIndirectDrawCount);
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,6 +160,7 @@ private:
|
|||||||
sk_sp<const GrBuffer> fIndirectDrawBuffer;
|
sk_sp<const GrBuffer> fIndirectDrawBuffer;
|
||||||
size_t fIndirectDrawOffset;
|
size_t fIndirectDrawOffset;
|
||||||
int fIndirectDrawCount;
|
int fIndirectDrawCount;
|
||||||
|
sk_sp<const GrBuffer> fIndirectIndexBuffer;
|
||||||
|
|
||||||
friend class GrOpMemoryPool; // For ctor.
|
friend class GrOpMemoryPool; // For ctor.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user