summaryrefslogtreecommitdiff
path: root/chromium/third_party/skia/bench/TessellatePathBench.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/skia/bench/TessellatePathBench.cpp')
-rw-r--r--chromium/third_party/skia/bench/TessellatePathBench.cpp206
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));
-);
+}