blob: 7cb634c0ec8401448261aa3618bf1c9d1033e6a0 [file] [log] [blame]
Chris Dalton7f0b8972020-04-23 15:52:24 -06001/*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "bench/Benchmark.h"
Robert Phillipsf0288102020-07-06 13:45:34 -04009#include "include/gpu/GrDirectContext.h"
Chris Daltonf6bf5162020-05-13 19:18:46 -060010#include "src/core/SkPathPriv.h"
Chris Dalton8447f132021-05-21 15:54:23 -060011#include "src/core/SkRectPriv.h"
Adlai Hollera0693042020-10-14 11:23:11 -040012#include "src/gpu/GrDirectContextPriv.h"
Michael Ludwig4e9d5e22021-05-11 10:00:12 -040013#include "src/gpu/geometry/GrWangsFormula.h"
Chris Dalton90ad0fe2020-11-09 14:13:39 -070014#include "src/gpu/mock/GrMockOpTarget.h"
Chris Daltonb5391d92020-05-24 14:55:54 -060015#include "src/gpu/tessellate/GrMiddleOutPolygonTriangulator.h"
Chris Daltond9bdc322021-06-01 19:22:05 -060016#include "src/gpu/tessellate/GrPathCurveTessellator.h"
Chris Daltond9bdc322021-06-01 19:22:05 -060017#include "src/gpu/tessellate/GrPathWedgeTessellator.h"
Chris Dalton82007f52021-04-20 00:45:50 -060018#include "src/gpu/tessellate/GrStrokeFixedCountTessellator.h"
Chris Dalton22241002021-02-04 09:47:40 -070019#include "src/gpu/tessellate/GrStrokeHardwareTessellator.h"
Chris Daltonf5132a02020-04-27 23:40:03 -060020#include "tools/ToolUtils.h"
Chris Daltonc2a17462020-12-09 16:46:22 -070021#include <vector>
Chris Dalton7f0b8972020-04-23 15:52:24 -060022
Chris Dalton3b412782021-06-01 13:40:03 -060023using ShaderFlags = GrStrokeTessellationShader::ShaderFlags;
Chris Dalton42582fc2021-02-18 11:29:49 -070024
Chris Dalton7f0b8972020-04-23 15:52:24 -060025// This is the number of cubics in desk_chalkboard.skp. (There are no quadratics in the chalkboard.)
26constexpr static int kNumCubicsInChalkboard = 47182;
27
Chris Dalton90ad0fe2020-11-09 14:13:39 -070028static sk_sp<GrDirectContext> make_mock_context() {
29 GrMockOptions mockOptions;
30 mockOptions.fDrawInstancedSupport = true;
31 mockOptions.fMaxTessellationSegments = 64;
32 mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag;
33 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fRenderability =
34 GrMockOptions::ConfigOptions::Renderability::kMSAA;
35 mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fTexturable = true;
36 mockOptions.fIntegerSupport = true;
37
38 GrContextOptions ctxOptions;
39 ctxOptions.fGpuPathRenderers = GpuPathRenderers::kTessellation;
Chris Dalton4ac9aad2021-02-24 17:41:44 -070040 ctxOptions.fEnableExperimentalHardwareTessellation = true;
Chris Dalton90ad0fe2020-11-09 14:13:39 -070041
42 return GrDirectContext::MakeMock(&mockOptions, ctxOptions);
43}
44
Chris Dalton8447f132021-05-21 15:54:23 -060045static SkPath make_cubic_path(int maxPow2) {
Chris Dalton7f0b8972020-04-23 15:52:24 -060046 SkRandom rand;
47 SkPath path;
48 for (int i = 0; i < kNumCubicsInChalkboard/2; ++i) {
Chris Dalton8447f132021-05-21 15:54:23 -060049 float x = std::ldexp(rand.nextF(), (i % maxPow2)) / 1e3f;
Chris Dalton7f0b8972020-04-23 15:52:24 -060050 path.cubicTo(111.625f*x, 308.188f*x, 764.62f*x, -435.688f*x, 742.63f*x, 85.187f*x);
51 path.cubicTo(764.62f*x, -435.688f*x, 111.625f*x, 308.188f*x, 0, 0);
52 }
53 return path;
54}
55
Tyler Denniston04f471a2021-02-04 13:07:03 -050056static SkPath make_conic_path() {
57 SkRandom rand;
58 SkPath path;
59 for (int i = 0; i < kNumCubicsInChalkboard / 40; ++i) {
60 for (int j = -10; j <= 10; j++) {
61 const float x = std::ldexp(rand.nextF(), (i % 18)) / 1e3f;
62 const float w = std::ldexp(1 + rand.nextF(), j);
63 path.conicTo(111.625f * x, 308.188f * x, 764.62f * x, -435.688f * x, w);
64 }
65 }
66 return path;
67}
68
Chris Dalton078f8752020-07-30 19:50:46 -060069// This serves as a base class for benchmarking individual methods on GrPathTessellateOp.
Chris Daltond7177432021-01-15 13:12:50 -070070class PathTessellateBenchmark : public Benchmark {
Chris Dalton7f0b8972020-04-23 15:52:24 -060071public:
Chris Daltond7177432021-01-15 13:12:50 -070072 PathTessellateBenchmark(const char* subName, const SkPath& p, const SkMatrix& m)
73 : fPath(p), fMatrix(m) {
Chris Dalton7f0b8972020-04-23 15:52:24 -060074 fName.printf("tessellate_%s", subName);
75 }
76
77 const char* onGetName() override { return fName.c_str(); }
78 bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; }
79
Chris Daltond7177432021-01-15 13:12:50 -070080protected:
Chris Dalton0e543092020-11-03 14:09:16 -070081 void onDelayedSetup() override {
Chris Dalton90ad0fe2020-11-09 14:13:39 -070082 fTarget = std::make_unique<GrMockOpTarget>(make_mock_context());
Chris Dalton0e543092020-11-03 14:09:16 -070083 }
84
Chris Dalton7f0b8972020-04-23 15:52:24 -060085 void onDraw(int loops, SkCanvas*) final {
Chris Dalton0e543092020-11-03 14:09:16 -070086 if (!fTarget->mockContext()) {
Chris Dalton1443c9d2020-05-27 09:43:34 -060087 SkDebugf("ERROR: could not create mock context.");
88 return;
89 }
Chris Dalton7f0b8972020-04-23 15:52:24 -060090 for (int i = 0; i < loops; ++i) {
Chris Daltond7177432021-01-15 13:12:50 -070091 this->runBench();
Chris Dalton0e543092020-11-03 14:09:16 -070092 fTarget->resetAllocator();
Chris Dalton7f0b8972020-04-23 15:52:24 -060093 }
94 }
95
Chris Daltond7177432021-01-15 13:12:50 -070096 virtual void runBench() = 0;
Chris Dalton7f0b8972020-04-23 15:52:24 -060097
Chris Dalton7f0b8972020-04-23 15:52:24 -060098 SkString fName;
Chris Daltond7177432021-01-15 13:12:50 -070099 std::unique_ptr<GrMockOpTarget> fTarget;
100 const SkPath fPath;
Chris Daltone1314a32021-01-29 13:22:33 -0700101 const SkMatrix fMatrix;
Chris Dalton7f0b8972020-04-23 15:52:24 -0600102};
103
Chris Daltond7177432021-01-15 13:12:50 -0700104#define DEF_PATH_TESS_BENCH(NAME, PATH, MATRIX) \
105 class PathTessellateBenchmark_##NAME : public PathTessellateBenchmark { \
Chris Daltonb5391d92020-05-24 14:55:54 -0600106 public: \
Chris Daltond7177432021-01-15 13:12:50 -0700107 PathTessellateBenchmark_##NAME() : PathTessellateBenchmark(#NAME, (PATH), (MATRIX)) {} \
108 void runBench() override; \
Chris Daltonb5391d92020-05-24 14:55:54 -0600109 }; \
Chris Daltond7177432021-01-15 13:12:50 -0700110 DEF_BENCH( return new PathTessellateBenchmark_##NAME(); ); \
111 void PathTessellateBenchmark_##NAME::runBench()
Chris Dalton7f0b8972020-04-23 15:52:24 -0600112
Chris Dalton8447f132021-05-21 15:54:23 -0600113DEF_PATH_TESS_BENCH(GrPathOuterCurveTessellator, make_cubic_path(8), SkMatrix::I()) {
Chris Dalton569c01b2021-05-25 10:11:46 -0600114 SkArenaAlloc arena(1024);
Chris Dalton198ac152021-06-09 13:49:43 -0600115 GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
116 GrSwizzle::RGBA());
Chris Daltond9bdc322021-06-01 19:22:05 -0600117 auto tess = GrPathCurveTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
Chris Dalton73915112021-06-09 16:28:11 -0600118 GrPathCurveTessellator::DrawInnerFan::kNo,
Chris Dalton26666bd2021-06-08 16:25:46 -0600119 fTarget->caps().minPathVerbsForHwTessellation(),
Chris Dalton198ac152021-06-09 13:49:43 -0600120 noVaryingsPipeline, fTarget->caps());
Chris Dalton569c01b2021-05-25 10:11:46 -0600121 tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), fPath, nullptr);
Chris Daltonb5391d92020-05-24 14:55:54 -0600122}
Chris Dalton7f0b8972020-04-23 15:52:24 -0600123
Chris Dalton8447f132021-05-21 15:54:23 -0600124DEF_PATH_TESS_BENCH(GrPathWedgeTessellator, make_cubic_path(8), SkMatrix::I()) {
Chris Dalton569c01b2021-05-25 10:11:46 -0600125 SkArenaAlloc arena(1024);
Chris Dalton198ac152021-06-09 13:49:43 -0600126 GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
127 GrSwizzle::RGBA());
Chris Daltond2b8ba32021-06-09 00:12:59 -0600128 auto tess = GrPathWedgeTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
129 fTarget->caps().minPathVerbsForHwTessellation(),
Chris Dalton198ac152021-06-09 13:49:43 -0600130 noVaryingsPipeline, fTarget->caps());
Chris Dalton569c01b2021-05-25 10:11:46 -0600131 tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), fPath, nullptr);
Chris Daltonb5391d92020-05-24 14:55:54 -0600132}
Chris Daltonf6bf5162020-05-13 19:18:46 -0600133
Chris Daltonb5391d92020-05-24 14:55:54 -0600134static void benchmark_wangs_formula_cubic_log2(const SkMatrix& matrix, const SkPath& path) {
135 int sum = 0;
136 GrVectorXform xform(matrix);
137 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
138 if (verb == SkPathVerb::kCubic) {
139 sum += GrWangsFormula::cubic_log2(4, pts, xform);
Chris Daltonf6bf5162020-05-13 19:18:46 -0600140 }
141 }
Chris Daltonb5391d92020-05-24 14:55:54 -0600142 // Don't let the compiler optimize away GrWangsFormula::cubic_log2.
143 if (sum <= 0) {
144 SK_ABORT("sum should be > 0.");
145 }
146}
Chris Daltonf6bf5162020-05-13 19:18:46 -0600147
Chris Dalton8447f132021-05-21 15:54:23 -0600148DEF_PATH_TESS_BENCH(wangs_formula_cubic_log2, make_cubic_path(18), SkMatrix::I()) {
Chris Daltond7177432021-01-15 13:12:50 -0700149 benchmark_wangs_formula_cubic_log2(fMatrix, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600150}
151
Chris Dalton8447f132021-05-21 15:54:23 -0600152DEF_PATH_TESS_BENCH(wangs_formula_cubic_log2_scale, make_cubic_path(18),
Chris Daltond7177432021-01-15 13:12:50 -0700153 SkMatrix::Scale(1.1f, 0.9f)) {
154 benchmark_wangs_formula_cubic_log2(fMatrix, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600155}
156
Chris Dalton8447f132021-05-21 15:54:23 -0600157DEF_PATH_TESS_BENCH(wangs_formula_cubic_log2_affine, make_cubic_path(18),
Chris Daltond7177432021-01-15 13:12:50 -0700158 SkMatrix::MakeAll(.9f,0.9f,0, 1.1f,1.1f,0, 0,0,1)) {
159 benchmark_wangs_formula_cubic_log2(fMatrix, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600160}
161
Tyler Denniston04f471a2021-02-04 13:07:03 -0500162static void benchmark_wangs_formula_conic(const SkMatrix& matrix, const SkPath& path) {
Tyler Denniston04f471a2021-02-04 13:07:03 -0500163 int sum = 0;
164 GrVectorXform xform(matrix);
165 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
166 if (verb == SkPathVerb::kConic) {
Chris Daltone6f45312021-06-02 12:00:01 -0600167 sum += GrWangsFormula::conic(4, pts, *w, xform);
Tyler Denniston04f471a2021-02-04 13:07:03 -0500168 }
169 }
170 // Don't let the compiler optimize away GrWangsFormula::conic.
171 if (sum <= 0) {
172 SK_ABORT("sum should be > 0.");
173 }
174}
175
176static void benchmark_wangs_formula_conic_log2(const SkMatrix& matrix, const SkPath& path) {
Tyler Denniston04f471a2021-02-04 13:07:03 -0500177 int sum = 0;
178 GrVectorXform xform(matrix);
179 for (auto [verb, pts, w] : SkPathPriv::Iterate(path)) {
180 if (verb == SkPathVerb::kConic) {
Chris Daltone6f45312021-06-02 12:00:01 -0600181 sum += GrWangsFormula::conic_log2(4, pts, *w, xform);
Tyler Denniston04f471a2021-02-04 13:07:03 -0500182 }
183 }
184 // Don't let the compiler optimize away GrWangsFormula::conic.
185 if (sum <= 0) {
186 SK_ABORT("sum should be > 0.");
187 }
188}
189
190DEF_PATH_TESS_BENCH(wangs_formula_conic, make_conic_path(), SkMatrix::I()) {
191 benchmark_wangs_formula_conic(fMatrix, fPath);
192}
193
194DEF_PATH_TESS_BENCH(wangs_formula_conic_log2, make_conic_path(), SkMatrix::I()) {
195 benchmark_wangs_formula_conic_log2(fMatrix, fPath);
196}
197
Chris Daltone2067642020-09-23 11:07:20 -0600198DEF_PATH_TESS_BENCH(middle_out_triangulation,
199 ToolUtils::make_star(SkRect::MakeWH(500, 500), kNumCubicsInChalkboard),
Chris Daltond7177432021-01-15 13:12:50 -0700200 SkMatrix::I()) {
Chris Dalton8ed7a8d2021-03-31 10:40:29 -0600201 sk_sp<const GrBuffer> buffer;
Chris Daltonb5391d92020-05-24 14:55:54 -0600202 int baseVertex;
Chris Dalton8731a712021-05-14 14:48:54 -0600203 GrVertexWriter vertexWriter = static_cast<SkPoint*>(fTarget->makeVertexSpace(
Chris Dalton8ed7a8d2021-03-31 10:40:29 -0600204 sizeof(SkPoint), kNumCubicsInChalkboard, &buffer, &baseVertex));
Chris Dalton40c906f2021-07-26 11:27:05 -0600205 int numTrianglesWritten;
206 GrMiddleOutPolygonTriangulator::WritePathInnerFan(std::move(vertexWriter), 0, 0, fPath,
207 &numTrianglesWritten);
Chris Daltonb5391d92020-05-24 14:55:54 -0600208}
Chris Daltone2067642020-09-23 11:07:20 -0600209
Chris Dalton981e4a72021-02-22 12:13:49 -0700210using PathStrokeList = GrStrokeTessellator::PathStrokeList;
Chris Dalton13adb4a2021-05-26 10:21:56 -0600211using MakeTessellatorFn = std::unique_ptr<GrStrokeTessellator>(*)(ShaderFlags, const GrShaderCaps&,
212 const SkMatrix&, PathStrokeList*,
Chris Dalton0638df12021-05-14 15:57:39 -0600213 std::array<float, 2>, const
214 SkRect&);
Chris Dalton82007f52021-04-20 00:45:50 -0600215
Chris Dalton0638df12021-05-14 15:57:39 -0600216static std::unique_ptr<GrStrokeTessellator> make_hw_tessellator(
Chris Dalton13adb4a2021-05-26 10:21:56 -0600217 ShaderFlags shaderFlags, const GrShaderCaps& shaderCaps, const SkMatrix& viewMatrix,
218 PathStrokeList* pathStrokeList, std::array<float, 2> matrixMinMaxScales,
219 const SkRect& strokeCullBounds) {
Chris Dalton69043032021-07-01 11:17:53 -0600220 return std::make_unique<GrStrokeHardwareTessellator>(shaderCaps, shaderFlags, viewMatrix,
Chris Dalton13adb4a2021-05-26 10:21:56 -0600221 pathStrokeList, matrixMinMaxScales,
222 strokeCullBounds);
Chris Dalton82007f52021-04-20 00:45:50 -0600223}
224
225static std::unique_ptr<GrStrokeTessellator> make_fixed_count_tessellator(
Chris Daltonbb995e62021-07-01 10:58:55 -0600226 ShaderFlags shaderFlags, const GrShaderCaps& shaderCaps, const SkMatrix& viewMatrix,
Chris Dalton13adb4a2021-05-26 10:21:56 -0600227 PathStrokeList* pathStrokeList, std::array<float, 2> matrixMinMaxScales,
228 const SkRect& strokeCullBounds) {
Chris Dalton69043032021-07-01 11:17:53 -0600229 return std::make_unique<GrStrokeFixedCountTessellator>(shaderCaps, shaderFlags, viewMatrix,
230 pathStrokeList, matrixMinMaxScales,
231 strokeCullBounds);
Chris Dalton82007f52021-04-20 00:45:50 -0600232}
233
Chris Dalton981e4a72021-02-22 12:13:49 -0700234using MakePathStrokesFn = std::vector<PathStrokeList>(*)();
235
236static std::vector<PathStrokeList> make_simple_cubic_path() {
237 auto path = SkPath().moveTo(0, 0);
238 for (int i = 0; i < kNumCubicsInChalkboard/2; ++i) {
239 path.cubicTo(100, 0, 50, 100, 100, 100);
240 path.cubicTo(0, -100, 200, 100, 0, 0);
241 }
242 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
243 stroke.setStrokeStyle(8);
244 stroke.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kMiter_Join, 4);
245 return {{path, stroke, SK_PMColor4fWHITE}};
246}
247
248// Generates a list of paths that resemble the MotionMark benchmark.
249static std::vector<PathStrokeList> make_motionmark_paths() {
250 std::vector<PathStrokeList> pathStrokes;
251 SkRandom rand;
252 for (int i = 0; i < 8702; ++i) {
253 // The number of paths with a given number of verbs in the MotionMark bench gets cut in half
254 // every time the number of verbs increases by 1.
255 int numVerbs = 28 - SkNextLog2(rand.nextRangeU(0, (1 << 27) - 1));
256 SkPath path;
257 for (int j = 0; j < numVerbs; ++j) {
258 switch (rand.nextU() & 3) {
259 case 0:
260 case 1:
261 path.lineTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
262 break;
263 case 2:
264 if (rand.nextULessThan(10) == 0) {
265 // Cusp.
266 auto [x, y] = (path.isEmpty())
267 ? SkPoint{0,0}
268 : SkPathPriv::PointData(path)[path.countPoints() - 1];
269 path.quadTo(x + rand.nextRangeF(0, 150), y, x - rand.nextRangeF(0, 150), y);
270 } else {
271 path.quadTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
272 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
273 }
274 break;
275 case 3:
276 if (rand.nextULessThan(10) == 0) {
277 // Cusp.
278 float y = (path.isEmpty())
279 ? 0 : SkPathPriv::PointData(path)[path.countPoints() - 1].fY;
280 path.cubicTo(rand.nextRangeF(0, 150), y, rand.nextRangeF(0, 150), y,
281 rand.nextRangeF(0, 150), y);
282 } else {
283 path.cubicTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
284 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
285 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
286 }
287 break;
288 }
289 }
290 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
291 // The number of paths with a given stroke width in the MotionMark bench gets cut in half
292 // every time the stroke width increases by 1.
293 float strokeWidth = 21 - log2f(rand.nextRangeF(0, 1 << 20));
294 stroke.setStrokeStyle(strokeWidth);
295 stroke.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kBevel_Join, 0);
296 pathStrokes.emplace_back(path, stroke, SK_PMColor4fWHITE);
297 }
298 return pathStrokes;
299}
300
Chris Dalton82007f52021-04-20 00:45:50 -0600301class TessPrepareBench : public Benchmark {
Chris Dalton2882e702020-11-02 12:43:06 -0700302public:
Chris Dalton82007f52021-04-20 00:45:50 -0600303 TessPrepareBench(MakePathStrokesFn makePathStrokesFn, MakeTessellatorFn makeTessellatorFn,
304 ShaderFlags shaderFlags, float matrixScale, const char* suffix)
305 : fMakePathStrokesFn(makePathStrokesFn)
306 , fMakeTessellatorFn(makeTessellatorFn)
Chris Daltonbb33be22021-02-24 16:30:34 -0700307 , fShaderFlags(shaderFlags)
Chris Dalton981e4a72021-02-22 12:13:49 -0700308 , fMatrixScale(matrixScale) {
Chris Dalton82007f52021-04-20 00:45:50 -0600309 fName.printf("tessellate_%s", suffix);
Chris Dalton2882e702020-11-02 12:43:06 -0700310 }
311
312private:
313 const char* onGetName() override { return fName.c_str(); }
Chris Daltone2067642020-09-23 11:07:20 -0600314 bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; }
315
316 void onDelayedSetup() override {
Chris Dalton90ad0fe2020-11-09 14:13:39 -0700317 fTarget = std::make_unique<GrMockOpTarget>(make_mock_context());
Chris Dalton0e543092020-11-03 14:09:16 -0700318 if (!fTarget->mockContext()) {
Chris Daltone2067642020-09-23 11:07:20 -0600319 SkDebugf("ERROR: could not create mock context.");
320 return;
321 }
Chris Dalton981e4a72021-02-22 12:13:49 -0700322
323 fPathStrokes = fMakePathStrokesFn();
324 for (size_t i = 0; i < fPathStrokes.size(); ++i) {
325 if (i + 1 < fPathStrokes.size()) {
326 fPathStrokes[i].fNext = &fPathStrokes[i + 1];
327 }
328 fTotalVerbCount += fPathStrokes[i].fPath.countVerbs();
Chris Daltone2067642020-09-23 11:07:20 -0600329 }
Chris Dalton82007f52021-04-20 00:45:50 -0600330
Chris Dalton13adb4a2021-05-26 10:21:56 -0600331 fTessellator = fMakeTessellatorFn(fShaderFlags, *fTarget->caps().shaderCaps(),
332 SkMatrix::Scale(fMatrixScale, fMatrixScale),
Chris Dalton0638df12021-05-14 15:57:39 -0600333 fPathStrokes.data(), {fMatrixScale, fMatrixScale},
Chris Dalton8447f132021-05-21 15:54:23 -0600334 SkRectPriv::MakeLargest());
Chris Daltone2067642020-09-23 11:07:20 -0600335 }
336
Chris Dalton981e4a72021-02-22 12:13:49 -0700337 void onDraw(int loops, SkCanvas*) final {
Chris Dalton981e4a72021-02-22 12:13:49 -0700338 for (int i = 0; i < loops; ++i) {
Chris Dalton82007f52021-04-20 00:45:50 -0600339 fTessellator->prepare(fTarget.get(), fTotalVerbCount);
Chris Dalton981e4a72021-02-22 12:13:49 -0700340 fTarget->resetAllocator();
341 }
342 }
343
Chris Dalton2882e702020-11-02 12:43:06 -0700344 SkString fName;
Chris Dalton981e4a72021-02-22 12:13:49 -0700345 MakePathStrokesFn fMakePathStrokesFn;
Chris Dalton82007f52021-04-20 00:45:50 -0600346 MakeTessellatorFn fMakeTessellatorFn;
Chris Daltonbb33be22021-02-24 16:30:34 -0700347 const ShaderFlags fShaderFlags;
Chris Dalton981e4a72021-02-22 12:13:49 -0700348 float fMatrixScale;
Chris Dalton90ad0fe2020-11-09 14:13:39 -0700349 std::unique_ptr<GrMockOpTarget> fTarget;
Chris Dalton981e4a72021-02-22 12:13:49 -0700350 std::vector<PathStrokeList> fPathStrokes;
Chris Dalton82007f52021-04-20 00:45:50 -0600351 std::unique_ptr<GrStrokeTessellator> fTessellator;
Chris Dalton981e4a72021-02-22 12:13:49 -0700352 SkArenaAlloc fPersistentArena{1024};
353 int fTotalVerbCount = 0;
Chris Daltone2067642020-09-23 11:07:20 -0600354};
355
Chris Dalton82007f52021-04-20 00:45:50 -0600356DEF_BENCH(return new TessPrepareBench(
357 make_simple_cubic_path, make_hw_tessellator, ShaderFlags::kNone, 1,
358 "GrStrokeHardwareTessellator");
Chris Daltonbb33be22021-02-24 16:30:34 -0700359)
360
Chris Dalton82007f52021-04-20 00:45:50 -0600361DEF_BENCH(return new TessPrepareBench(
362 make_simple_cubic_path, make_hw_tessellator, ShaderFlags::kNone, 5,
363 "GrStrokeHardwareTessellator_one_chop");
Chris Daltonbb33be22021-02-24 16:30:34 -0700364)
365
Chris Dalton82007f52021-04-20 00:45:50 -0600366DEF_BENCH(return new TessPrepareBench(
367 make_motionmark_paths, make_hw_tessellator, ShaderFlags::kDynamicStroke, 1,
368 "GrStrokeHardwareTessellator_motionmark");
369)
370
371DEF_BENCH(return new TessPrepareBench(
372 make_simple_cubic_path, make_fixed_count_tessellator, ShaderFlags::kNone, 1,
373 "GrStrokeFixedCountTessellator");
374)
375
376DEF_BENCH(return new TessPrepareBench(
377 make_simple_cubic_path, make_fixed_count_tessellator, ShaderFlags::kNone, 5,
378 "GrStrokeFixedCountTessellator_one_chop");
379)
380
381DEF_BENCH(return new TessPrepareBench(
382 make_motionmark_paths, make_fixed_count_tessellator, ShaderFlags::kDynamicStroke, 1,
383 "GrStrokeFixedCountTessellator_motionmark");
Chris Daltonbb33be22021-02-24 16:30:34 -0700384)