blob: 7a6cb228a4ebe3852781736495de6c17bb612b89 [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 Dalton50516f32021-07-18 22:26:27 -0600205 GrMiddleOutPolygonTriangulator::WritePathInnerFan(&vertexWriter, 0, 0, fPath);
Chris Daltonb5391d92020-05-24 14:55:54 -0600206}
Chris Daltone2067642020-09-23 11:07:20 -0600207
Chris Dalton981e4a72021-02-22 12:13:49 -0700208using PathStrokeList = GrStrokeTessellator::PathStrokeList;
Chris Dalton13adb4a2021-05-26 10:21:56 -0600209using MakeTessellatorFn = std::unique_ptr<GrStrokeTessellator>(*)(ShaderFlags, const GrShaderCaps&,
210 const SkMatrix&, PathStrokeList*,
Chris Dalton0638df12021-05-14 15:57:39 -0600211 std::array<float, 2>, const
212 SkRect&);
Chris Dalton82007f52021-04-20 00:45:50 -0600213
Chris Dalton0638df12021-05-14 15:57:39 -0600214static std::unique_ptr<GrStrokeTessellator> make_hw_tessellator(
Chris Dalton13adb4a2021-05-26 10:21:56 -0600215 ShaderFlags shaderFlags, const GrShaderCaps& shaderCaps, const SkMatrix& viewMatrix,
216 PathStrokeList* pathStrokeList, std::array<float, 2> matrixMinMaxScales,
217 const SkRect& strokeCullBounds) {
Chris Dalton69043032021-07-01 11:17:53 -0600218 return std::make_unique<GrStrokeHardwareTessellator>(shaderCaps, shaderFlags, viewMatrix,
Chris Dalton13adb4a2021-05-26 10:21:56 -0600219 pathStrokeList, matrixMinMaxScales,
220 strokeCullBounds);
Chris Dalton82007f52021-04-20 00:45:50 -0600221}
222
223static std::unique_ptr<GrStrokeTessellator> make_fixed_count_tessellator(
Chris Daltonbb995e62021-07-01 10:58:55 -0600224 ShaderFlags shaderFlags, const GrShaderCaps& shaderCaps, const SkMatrix& viewMatrix,
Chris Dalton13adb4a2021-05-26 10:21:56 -0600225 PathStrokeList* pathStrokeList, std::array<float, 2> matrixMinMaxScales,
226 const SkRect& strokeCullBounds) {
Chris Dalton69043032021-07-01 11:17:53 -0600227 return std::make_unique<GrStrokeFixedCountTessellator>(shaderCaps, shaderFlags, viewMatrix,
228 pathStrokeList, matrixMinMaxScales,
229 strokeCullBounds);
Chris Dalton82007f52021-04-20 00:45:50 -0600230}
231
Chris Dalton981e4a72021-02-22 12:13:49 -0700232using MakePathStrokesFn = std::vector<PathStrokeList>(*)();
233
234static std::vector<PathStrokeList> make_simple_cubic_path() {
235 auto path = SkPath().moveTo(0, 0);
236 for (int i = 0; i < kNumCubicsInChalkboard/2; ++i) {
237 path.cubicTo(100, 0, 50, 100, 100, 100);
238 path.cubicTo(0, -100, 200, 100, 0, 0);
239 }
240 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
241 stroke.setStrokeStyle(8);
242 stroke.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kMiter_Join, 4);
243 return {{path, stroke, SK_PMColor4fWHITE}};
244}
245
246// Generates a list of paths that resemble the MotionMark benchmark.
247static std::vector<PathStrokeList> make_motionmark_paths() {
248 std::vector<PathStrokeList> pathStrokes;
249 SkRandom rand;
250 for (int i = 0; i < 8702; ++i) {
251 // The number of paths with a given number of verbs in the MotionMark bench gets cut in half
252 // every time the number of verbs increases by 1.
253 int numVerbs = 28 - SkNextLog2(rand.nextRangeU(0, (1 << 27) - 1));
254 SkPath path;
255 for (int j = 0; j < numVerbs; ++j) {
256 switch (rand.nextU() & 3) {
257 case 0:
258 case 1:
259 path.lineTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
260 break;
261 case 2:
262 if (rand.nextULessThan(10) == 0) {
263 // Cusp.
264 auto [x, y] = (path.isEmpty())
265 ? SkPoint{0,0}
266 : SkPathPriv::PointData(path)[path.countPoints() - 1];
267 path.quadTo(x + rand.nextRangeF(0, 150), y, x - rand.nextRangeF(0, 150), y);
268 } else {
269 path.quadTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
270 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
271 }
272 break;
273 case 3:
274 if (rand.nextULessThan(10) == 0) {
275 // Cusp.
276 float y = (path.isEmpty())
277 ? 0 : SkPathPriv::PointData(path)[path.countPoints() - 1].fY;
278 path.cubicTo(rand.nextRangeF(0, 150), y, rand.nextRangeF(0, 150), y,
279 rand.nextRangeF(0, 150), y);
280 } else {
281 path.cubicTo(rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
282 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150),
283 rand.nextRangeF(0, 150), rand.nextRangeF(0, 150));
284 }
285 break;
286 }
287 }
288 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
289 // The number of paths with a given stroke width in the MotionMark bench gets cut in half
290 // every time the stroke width increases by 1.
291 float strokeWidth = 21 - log2f(rand.nextRangeF(0, 1 << 20));
292 stroke.setStrokeStyle(strokeWidth);
293 stroke.setStrokeParams(SkPaint::kButt_Cap, SkPaint::kBevel_Join, 0);
294 pathStrokes.emplace_back(path, stroke, SK_PMColor4fWHITE);
295 }
296 return pathStrokes;
297}
298
Chris Dalton82007f52021-04-20 00:45:50 -0600299class TessPrepareBench : public Benchmark {
Chris Dalton2882e702020-11-02 12:43:06 -0700300public:
Chris Dalton82007f52021-04-20 00:45:50 -0600301 TessPrepareBench(MakePathStrokesFn makePathStrokesFn, MakeTessellatorFn makeTessellatorFn,
302 ShaderFlags shaderFlags, float matrixScale, const char* suffix)
303 : fMakePathStrokesFn(makePathStrokesFn)
304 , fMakeTessellatorFn(makeTessellatorFn)
Chris Daltonbb33be22021-02-24 16:30:34 -0700305 , fShaderFlags(shaderFlags)
Chris Dalton981e4a72021-02-22 12:13:49 -0700306 , fMatrixScale(matrixScale) {
Chris Dalton82007f52021-04-20 00:45:50 -0600307 fName.printf("tessellate_%s", suffix);
Chris Dalton2882e702020-11-02 12:43:06 -0700308 }
309
310private:
311 const char* onGetName() override { return fName.c_str(); }
Chris Daltone2067642020-09-23 11:07:20 -0600312 bool isSuitableFor(Backend backend) final { return backend == kNonRendering_Backend; }
313
314 void onDelayedSetup() override {
Chris Dalton90ad0fe2020-11-09 14:13:39 -0700315 fTarget = std::make_unique<GrMockOpTarget>(make_mock_context());
Chris Dalton0e543092020-11-03 14:09:16 -0700316 if (!fTarget->mockContext()) {
Chris Daltone2067642020-09-23 11:07:20 -0600317 SkDebugf("ERROR: could not create mock context.");
318 return;
319 }
Chris Dalton981e4a72021-02-22 12:13:49 -0700320
321 fPathStrokes = fMakePathStrokesFn();
322 for (size_t i = 0; i < fPathStrokes.size(); ++i) {
323 if (i + 1 < fPathStrokes.size()) {
324 fPathStrokes[i].fNext = &fPathStrokes[i + 1];
325 }
326 fTotalVerbCount += fPathStrokes[i].fPath.countVerbs();
Chris Daltone2067642020-09-23 11:07:20 -0600327 }
Chris Dalton82007f52021-04-20 00:45:50 -0600328
Chris Dalton13adb4a2021-05-26 10:21:56 -0600329 fTessellator = fMakeTessellatorFn(fShaderFlags, *fTarget->caps().shaderCaps(),
330 SkMatrix::Scale(fMatrixScale, fMatrixScale),
Chris Dalton0638df12021-05-14 15:57:39 -0600331 fPathStrokes.data(), {fMatrixScale, fMatrixScale},
Chris Dalton8447f132021-05-21 15:54:23 -0600332 SkRectPriv::MakeLargest());
Chris Daltone2067642020-09-23 11:07:20 -0600333 }
334
Chris Dalton981e4a72021-02-22 12:13:49 -0700335 void onDraw(int loops, SkCanvas*) final {
Chris Dalton981e4a72021-02-22 12:13:49 -0700336 for (int i = 0; i < loops; ++i) {
Chris Dalton82007f52021-04-20 00:45:50 -0600337 fTessellator->prepare(fTarget.get(), fTotalVerbCount);
Chris Dalton981e4a72021-02-22 12:13:49 -0700338 fTarget->resetAllocator();
339 }
340 }
341
Chris Dalton2882e702020-11-02 12:43:06 -0700342 SkString fName;
Chris Dalton981e4a72021-02-22 12:13:49 -0700343 MakePathStrokesFn fMakePathStrokesFn;
Chris Dalton82007f52021-04-20 00:45:50 -0600344 MakeTessellatorFn fMakeTessellatorFn;
Chris Daltonbb33be22021-02-24 16:30:34 -0700345 const ShaderFlags fShaderFlags;
Chris Dalton981e4a72021-02-22 12:13:49 -0700346 float fMatrixScale;
Chris Dalton90ad0fe2020-11-09 14:13:39 -0700347 std::unique_ptr<GrMockOpTarget> fTarget;
Chris Dalton981e4a72021-02-22 12:13:49 -0700348 std::vector<PathStrokeList> fPathStrokes;
Chris Dalton82007f52021-04-20 00:45:50 -0600349 std::unique_ptr<GrStrokeTessellator> fTessellator;
Chris Dalton981e4a72021-02-22 12:13:49 -0700350 SkArenaAlloc fPersistentArena{1024};
351 int fTotalVerbCount = 0;
Chris Daltone2067642020-09-23 11:07:20 -0600352};
353
Chris Dalton82007f52021-04-20 00:45:50 -0600354DEF_BENCH(return new TessPrepareBench(
355 make_simple_cubic_path, make_hw_tessellator, ShaderFlags::kNone, 1,
356 "GrStrokeHardwareTessellator");
Chris Daltonbb33be22021-02-24 16:30:34 -0700357)
358
Chris Dalton82007f52021-04-20 00:45:50 -0600359DEF_BENCH(return new TessPrepareBench(
360 make_simple_cubic_path, make_hw_tessellator, ShaderFlags::kNone, 5,
361 "GrStrokeHardwareTessellator_one_chop");
Chris Daltonbb33be22021-02-24 16:30:34 -0700362)
363
Chris Dalton82007f52021-04-20 00:45:50 -0600364DEF_BENCH(return new TessPrepareBench(
365 make_motionmark_paths, make_hw_tessellator, ShaderFlags::kDynamicStroke, 1,
366 "GrStrokeHardwareTessellator_motionmark");
367)
368
369DEF_BENCH(return new TessPrepareBench(
370 make_simple_cubic_path, make_fixed_count_tessellator, ShaderFlags::kNone, 1,
371 "GrStrokeFixedCountTessellator");
372)
373
374DEF_BENCH(return new TessPrepareBench(
375 make_simple_cubic_path, make_fixed_count_tessellator, ShaderFlags::kNone, 5,
376 "GrStrokeFixedCountTessellator_one_chop");
377)
378
379DEF_BENCH(return new TessPrepareBench(
380 make_motionmark_paths, make_fixed_count_tessellator, ShaderFlags::kDynamicStroke, 1,
381 "GrStrokeFixedCountTessellator_motionmark");
Chris Daltonbb33be22021-02-24 16:30:34 -0700382)