diff --git a/bench/TessellatePathBench.cpp b/bench/TessellatePathBench.cpp index 12c3ce4250..d22fe2b00e 100644 --- a/bench/TessellatePathBench.cpp +++ b/bench/TessellatePathBench.cpp @@ -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* sampledProxyArray()) - UNIMPL(const GrCaps& caps() const) UNIMPL(GrDeferredUploadTarget* deferredUploadTarget()) #undef UNIMPL private: + sk_sp 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; diff --git a/src/gpu/tessellate/GrTessellatePathOp.cpp b/src/gpu/tessellate/GrTessellatePathOp.cpp index cb1bf37584..1889ad2502 100644 --- a/src/gpu/tessellate/GrTessellatePathOp.cpp +++ b/src/gpu/tessellate/GrTessellatePathOp.cpp @@ -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 { diff --git a/src/gpu/tessellate/GrTessellatePathOp.h b/src/gpu/tessellate/GrTessellatePathOp.h index 89c9f7fe15..cb216a8007 100644 --- a/src/gpu/tessellate/GrTessellatePathOp.h +++ b/src/gpu/tessellate/GrTessellatePathOp.h @@ -160,6 +160,7 @@ private: sk_sp fIndirectDrawBuffer; size_t fIndirectDrawOffset; int fIndirectDrawCount; + sk_sp fIndirectIndexBuffer; friend class GrOpMemoryPool; // For ctor.