diff options
Diffstat (limited to 'chromium/third_party/skia/bench/TessellatePathBench.cpp')
-rw-r--r-- | chromium/third_party/skia/bench/TessellatePathBench.cpp | 206 |
1 files changed, 122 insertions, 84 deletions
diff --git a/chromium/third_party/skia/bench/TessellatePathBench.cpp b/chromium/third_party/skia/bench/TessellatePathBench.cpp index dc0daf7d093..7788d9b2923 100644 --- a/chromium/third_party/skia/bench/TessellatePathBench.cpp +++ b/chromium/third_party/skia/bench/TessellatePathBench.cpp @@ -10,6 +10,8 @@ #include "src/core/SkPathPriv.h" #include "src/gpu/GrContextPriv.h" #include "src/gpu/GrOpFlushState.h" +#include "src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h" +#include "src/gpu/tessellate/GrResolveLevelCounter.h" #include "src/gpu/tessellate/GrTessellatePathOp.h" #include "src/gpu/tessellate/GrWangsFormula.h" #include "tools/ToolUtils.h" @@ -32,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.fMaxTessellationSegments = 64; + 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 */ } @@ -39,10 +61,10 @@ public: void* makeVertexSpace(size_t vertexSize, int vertexCount, sk_sp<const GrBuffer>*, int* startVertex) override { if (vertexSize * vertexCount > sizeof(fStaticVertexData)) { - SK_ABORT(SkStringPrintf( - "FATAL: wanted %zu bytes of static vertex data; only have %zu.\n", - vertexSize * vertexCount, SK_ARRAY_COUNT(fStaticVertexData)).c_str()); + SK_ABORT("FATAL: wanted %zu bytes of static vertex data; only have %zu.\n", + vertexSize * vertexCount, SK_ARRAY_COUNT(fStaticVertexData)); } + *startVertex = 0; return fStaticVertexData; } @@ -50,9 +72,8 @@ public: int drawCount, sk_sp<const GrBuffer>* buffer, size_t* offsetInBytes) override { int staticBufferCount = (int)SK_ARRAY_COUNT(fStaticDrawIndexedIndirectData); if (drawCount > staticBufferCount) { - SK_ABORT(SkStringPrintf( - "FATAL: wanted %i static drawIndexedIndirect elements; only have %i.\n", - drawCount, staticBufferCount).c_str()); + SK_ABORT("FATAL: wanted %i static drawIndexedIndirect elements; only have %i.\n", + drawCount, staticBufferCount); } return fStaticDrawIndexedIndirectData; } @@ -70,16 +91,15 @@ 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: - SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 5]; + sk_sp<GrContext> fMockContext; + SkPoint fStaticVertexData[(kNumCubicsInChalkboard + 2) * 8]; GrDrawIndexedIndirectCommand fStaticDrawIndexedIndirectData[32]; SkSTArenaAlloc<1024 * 1024> fAllocator; }; @@ -88,20 +108,29 @@ private: class GrTessellatePathOp::TestingOnly_Benchmark : public Benchmark { public: TestingOnly_Benchmark(const char* subName, SkPath path, const SkMatrix& m) - : fOp(m, path, GrPaint(), GrAAType::kMSAA) { + : fOp(m, path, GrPaint(), GrAAType::kMSAA, GrTessellationPathRenderer::OpFlags::kNone) { fName.printf("tessellate_%s", subName); } const char* onGetName() override { return fName.c_str(); } bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; } - class MiddleOutInnerTrianglesBench; - class OuterCubicsBench; - class CubicWedgesBench; - class WangsFormulaBench; + class prepareMiddleOutStencilGeometry; + class prepareMiddleOutStencilGeometry_indirect; + class prepareIndirectOuterCubics; + class prepareTessellatedOuterCubics; + class prepareTessellatedCubicWedges; + class wangs_formula_cubic_log2; + class wangs_formula_cubic_log2_scale; + class wangs_formula_cubic_log2_affine; + class middle_out_triangulation; 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; @@ -120,83 +149,92 @@ private: SkString fName; }; -class GrTessellatePathOp::TestingOnly_Benchmark::MiddleOutInnerTrianglesBench - : public GrTessellatePathOp::TestingOnly_Benchmark { -public: - MiddleOutInnerTrianglesBench() - : TestingOnly_Benchmark("prepareMiddleOutInnerTriangles", - ToolUtils::make_star(SkRect::MakeWH(100, 100), - kNumCubicsInChalkboard), - SkMatrix::I()) { - } - void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override { - int numBeziers; - op->prepareMiddleOutInnerTriangles(target, &numBeziers); - } -}; +#define DEF_TESS_BENCH(NAME, PATH, MATRIX, TARGET, OP) \ + class GrTessellatePathOp::TestingOnly_Benchmark::NAME \ + : public GrTessellatePathOp::TestingOnly_Benchmark { \ + public: \ + NAME() : TestingOnly_Benchmark(#NAME, (PATH), (MATRIX)) {} \ + void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override; \ + }; \ + DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::NAME(); ); \ + void GrTessellatePathOp::TestingOnly_Benchmark::NAME::runBench( \ + GrMeshDrawOp::Target* TARGET, GrTessellatePathOp* op) + +DEF_TESS_BENCH(prepareMiddleOutStencilGeometry, make_cubic_path(), SkMatrix::I(), target, op) { + op->prepareMiddleOutTrianglesAndCubics(target); +} -DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::MiddleOutInnerTrianglesBench(); ); +DEF_TESS_BENCH(prepareMiddleOutStencilGeometry_indirect, make_cubic_path(), SkMatrix::I(), target, + op) { + GrResolveLevelCounter resolveLevelCounter; + op->prepareMiddleOutTrianglesAndCubics(target, &resolveLevelCounter, true); +} -class GrTessellatePathOp::TestingOnly_Benchmark::OuterCubicsBench - : public GrTessellatePathOp::TestingOnly_Benchmark { -public: - OuterCubicsBench() - : TestingOnly_Benchmark("prepareOuterCubics", make_cubic_path(), SkMatrix::I()) { - } - void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override { - op->prepareOuterCubics(target, kNumCubicsInChalkboard, - CubicDataAlignment::kVertexBoundary); - } -}; +DEF_TESS_BENCH(prepareIndirectOuterCubics, make_cubic_path(), SkMatrix::I(), target, op) { + GrResolveLevelCounter resolveLevelCounter; + resolveLevelCounter.reset(op->fPath, SkMatrix::I(), 4); + op->prepareIndirectOuterCubics(target, resolveLevelCounter); +} -DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::OuterCubicsBench(); ); +DEF_TESS_BENCH(prepareTessellatedOuterCubics, make_cubic_path(), SkMatrix::I(), target, op) { + op->prepareTessellatedOuterCubics(target, kNumCubicsInChalkboard); +} -class GrTessellatePathOp::TestingOnly_Benchmark::CubicWedgesBench - : public GrTessellatePathOp::TestingOnly_Benchmark { -public: - CubicWedgesBench() - : TestingOnly_Benchmark("prepareCubicWedges", make_cubic_path(), SkMatrix::I()) { +DEF_TESS_BENCH(prepareTessellatedCubicWedges, make_cubic_path(), SkMatrix::I(), target, op) { + op->prepareTessellatedCubicWedges(target); +} + +static void benchmark_wangs_formula_cubic_log2(const SkMatrix& matrix, const SkPath& path) { + int sum = 0; + GrVectorXform xform(matrix); + for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) { + if (verb == SkPathVerb::kCubic) { + sum += GrWangsFormula::cubic_log2(4, pts, xform); + } } - void runBench(GrMeshDrawOp::Target* target, GrTessellatePathOp* op) override { - op->prepareCubicWedges(target); + // Don't let the compiler optimize away GrWangsFormula::cubic_log2. + if (sum <= 0) { + SK_ABORT("sum should be > 0."); } -}; +} -DEF_BENCH( return new GrTessellatePathOp::TestingOnly_Benchmark::CubicWedgesBench();); +DEF_TESS_BENCH(wangs_formula_cubic_log2, make_cubic_path(), SkMatrix::I(), target, op) { + benchmark_wangs_formula_cubic_log2(op->fViewMatrix, op->fPath); +} -class GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench - : public GrTessellatePathOp::TestingOnly_Benchmark { -public: - WangsFormulaBench(const char* suffix, const SkMatrix& matrix) - : TestingOnly_Benchmark(SkStringPrintf("wangs_formula_cubic_log2%s", suffix).c_str(), - make_cubic_path(), SkMatrix::I()) - , fMatrix(matrix) { - } - void runBench(GrMeshDrawOp::Target*, GrTessellatePathOp* op) override { - int sum = 0; - GrVectorXform xform(fMatrix); - for (auto [verb, pts, w] : SkPathPriv::Iterate(op->fPath)) { - if (verb == SkPathVerb::kCubic) { - sum += GrWangsFormula::cubic_log2(4, pts, xform); - } - } - // Don't let the compiler optimize away GrWangsFormula::cubic_log2. - if (sum <= 0) { - SK_ABORT("sum should be > 0."); +DEF_TESS_BENCH(wangs_formula_cubic_log2_scale, make_cubic_path(), SkMatrix::Scale(1.1f, 0.9f), + target, op) { + benchmark_wangs_formula_cubic_log2(op->fViewMatrix, op->fPath); +} + +DEF_TESS_BENCH(wangs_formula_cubic_log2_affine, make_cubic_path(), + SkMatrix::MakeAll(.9f,0.9f,0, 1.1f,1.1f,0, 0,0,1), target, op) { + benchmark_wangs_formula_cubic_log2(op->fViewMatrix, op->fPath); +} + +DEF_TESS_BENCH(middle_out_triangulation, + ToolUtils::make_star(SkRect::MakeWH(500, 500), kNumCubicsInChalkboard), + SkMatrix::I(), target, op) { + int baseVertex; + auto vertexData = static_cast<SkPoint*>(target->makeVertexSpace( + sizeof(SkPoint), kNumCubicsInChalkboard, nullptr, &baseVertex)); + GrMiddleOutPolygonTriangulator middleOut(vertexData, 3, kNumCubicsInChalkboard + 2); + for (auto [verb, pts, w] : SkPathPriv::Iterate(op->fPath)) { + switch (verb) { + case SkPathVerb::kMove: + middleOut.closeAndMove(pts[0]); + break; + case SkPathVerb::kLine: + middleOut.pushVertex(pts[1]); + break; + case SkPathVerb::kClose: + middleOut.close(); + break; + case SkPathVerb::kQuad: + case SkPathVerb::kConic: + case SkPathVerb::kCubic: + SkUNREACHABLE; } + middleOut.closeAndMove(pts[0]); } -private: - SkMatrix fMatrix; -}; - -DEF_BENCH( - return new GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench("", SkMatrix::I()); -); -DEF_BENCH( - return new GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench( - "_scale", SkMatrix::MakeScale(1.1f, 0.9f)); -); -DEF_BENCH( - return new GrTessellatePathOp::TestingOnly_Benchmark::WangsFormulaBench( - "_affine", SkMatrix::MakeAll(.9f,0.9f,0, 1.1f,1.1f,0, 0,0,1)); -); +} |