| /* | |
| * Copyright 2011 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "bench/Benchmark.h" | |
| #include "include/core/SkBitmap.h" | |
| #include "include/core/SkCanvas.h" | |
| #include "include/core/SkPaint.h" | |
| #include "include/core/SkPath.h" | |
| #include "include/core/SkShader.h" | |
| #include "include/core/SkString.h" | |
| #include "src/core/SkColorPriv.h" | |
| #include "src/core/SkPathPriv.h" | |
| #include "src/core/SkRandom.h" | |
| #include <array> | |
| enum class PathIterType { | |
| kOldIter, | |
| kNewIter, | |
| kPriv, | |
| kEdge, | |
| kPathIter, | |
| }; | |
| static constexpr auto gPathIterNames = std::to_array<const char*>({ | |
| "olditer", | |
| "newiter", | |
| "priv", | |
| "edge", | |
| "pathiter", | |
| }); | |
| static int rand_pts(SkRandom& rand, SkPoint pts[4]) { | |
| int n = rand.nextU() & 3; | |
| n += 1; | |
| for (int i = 0; i < n; ++i) { | |
| pts[i].fX = rand.nextSScalar1(); | |
| pts[i].fY = rand.nextSScalar1(); | |
| } | |
| return n; | |
| } | |
| class PathIterBench : public Benchmark { | |
| SkString fName; | |
| SkPath fPath; | |
| PathIterType fType; | |
| int fVerbInc = 0; | |
| SkScalar fXInc = 0, fYInc = 0; | |
| public: | |
| PathIterBench(PathIterType t) : fType(t) { | |
| fName.printf("pathiter_%s", gPathIterNames[static_cast<unsigned>(t)]); | |
| SkPathBuilder builder; | |
| builder.moveTo({0, 0}); | |
| SkRandom rand; | |
| for (int i = 0; i < 1000; ++i) { | |
| SkPoint pts[4]; | |
| int n = rand_pts(rand, pts); | |
| switch (n) { | |
| case 2: | |
| builder.lineTo(pts[1]); | |
| break; | |
| case 3: | |
| builder.quadTo(pts[1], pts[2]); | |
| break; | |
| case 4: | |
| builder.cubicTo(pts[1], pts[2], pts[3]); | |
| break; | |
| } | |
| } | |
| fPath = builder.detach(); | |
| } | |
| bool isSuitableFor(Backend backend) override { | |
| return backend == Backend::kNonRendering; | |
| } | |
| protected: | |
| const char* onGetName() override { | |
| return fName.c_str(); | |
| } | |
| void onDraw(int loops, SkCanvas*) override { | |
| // Need to do *something* with the results, so the compile doesn't elide | |
| // away the code we want to time. | |
| auto handle = [this](int verb, const SkPoint pts[]) { | |
| fVerbInc += verb; | |
| fXInc += pts[0].fX; | |
| fYInc += pts[0].fY; | |
| }; | |
| switch (fType) { | |
| case PathIterType::kNewIter: | |
| for (int i = 0; i < loops; ++i) { | |
| SkPath::Iter iter(fPath, false); | |
| while (auto rec = iter.next()) { | |
| handle((int)rec->fVerb, rec->fPoints.data()); | |
| } | |
| } | |
| break; | |
| case PathIterType::kOldIter: | |
| for (int i = 0; i < loops; ++i) { | |
| SkPath::Iter iter(fPath, false); | |
| for (;;) { | |
| SkPoint pts[4]; | |
| auto verb = iter.next(pts); | |
| if (verb == SkPath::kDone_Verb) { | |
| break; | |
| } | |
| handle((int)verb, pts); | |
| } | |
| } | |
| break; | |
| case PathIterType::kPriv: | |
| for (int i = 0; i < loops; ++i) { | |
| for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) { | |
| handle((SkPath::Verb)verb, pts); | |
| } | |
| } | |
| break; | |
| case PathIterType::kEdge: | |
| for (int i = 0; i < loops; ++i) { | |
| SkPathEdgeIter iter(fPath); | |
| while (auto r = iter.next()) { | |
| handle((int)r.fEdge, r.fPts); | |
| } | |
| } | |
| break; | |
| case PathIterType::kPathIter: | |
| for (int i = 0; i < loops; ++i) { | |
| auto iter = fPath.iter(); | |
| while (auto r = iter.next()) { | |
| handle((int)r->fVerb, r->fPoints.data()); | |
| } | |
| } | |
| break; | |
| } | |
| } | |
| private: | |
| using INHERITED = Benchmark; | |
| }; | |
| /////////////////////////////////////////////////////////////////////////////// | |
| DEF_BENCH( return new PathIterBench(PathIterType::kNewIter); ) | |
| DEF_BENCH( return new PathIterBench(PathIterType::kOldIter); ) | |
| DEF_BENCH( return new PathIterBench(PathIterType::kPriv); ) | |
| DEF_BENCH( return new PathIterBench(PathIterType::kPathIter); ) | |
| DEF_BENCH( return new PathIterBench(PathIterType::kEdge); ) |