1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci#include "bench/Benchmark.h" 8cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColorPriv.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 12cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 13cb93a386Sopenharmony_ci#include "include/core/SkShader.h" 14cb93a386Sopenharmony_ci#include "include/core/SkString.h" 15cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 16cb93a386Sopenharmony_ci#include "src/core/SkPathPriv.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_cienum class PathIterType { 19cb93a386Sopenharmony_ci kIter, 20cb93a386Sopenharmony_ci kRaw, 21cb93a386Sopenharmony_ci kEdge, 22cb93a386Sopenharmony_ci}; 23cb93a386Sopenharmony_ciconst char* gPathIterNames[] = { 24cb93a386Sopenharmony_ci "iter", "raw", "edge" 25cb93a386Sopenharmony_ci}; 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_cistatic int rand_pts(SkRandom& rand, SkPoint pts[4]) { 28cb93a386Sopenharmony_ci int n = rand.nextU() & 3; 29cb93a386Sopenharmony_ci n += 1; 30cb93a386Sopenharmony_ci 31cb93a386Sopenharmony_ci for (int i = 0; i < n; ++i) { 32cb93a386Sopenharmony_ci pts[i].fX = rand.nextSScalar1(); 33cb93a386Sopenharmony_ci pts[i].fY = rand.nextSScalar1(); 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci return n; 36cb93a386Sopenharmony_ci} 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ciclass PathIterBench : public Benchmark { 39cb93a386Sopenharmony_ci SkString fName; 40cb93a386Sopenharmony_ci SkPath fPath; 41cb93a386Sopenharmony_ci PathIterType fType; 42cb93a386Sopenharmony_ci 43cb93a386Sopenharmony_ci int fVerbInc = 0; 44cb93a386Sopenharmony_ci SkScalar fXInc = 0, fYInc = 0; 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_cipublic: 47cb93a386Sopenharmony_ci PathIterBench(PathIterType t) : fType(t) { 48cb93a386Sopenharmony_ci fName.printf("pathiter_%s", gPathIterNames[static_cast<unsigned>(t)]); 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci SkRandom rand; 51cb93a386Sopenharmony_ci for (int i = 0; i < 1000; ++i) { 52cb93a386Sopenharmony_ci SkPoint pts[4]; 53cb93a386Sopenharmony_ci int n = rand_pts(rand, pts); 54cb93a386Sopenharmony_ci switch (n) { 55cb93a386Sopenharmony_ci case 1: 56cb93a386Sopenharmony_ci fPath.moveTo(pts[0]); 57cb93a386Sopenharmony_ci break; 58cb93a386Sopenharmony_ci case 2: 59cb93a386Sopenharmony_ci fPath.lineTo(pts[1]); 60cb93a386Sopenharmony_ci break; 61cb93a386Sopenharmony_ci case 3: 62cb93a386Sopenharmony_ci fPath.quadTo(pts[1], pts[2]); 63cb93a386Sopenharmony_ci break; 64cb93a386Sopenharmony_ci case 4: 65cb93a386Sopenharmony_ci fPath.cubicTo(pts[1], pts[2], pts[3]); 66cb93a386Sopenharmony_ci break; 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci bool isSuitableFor(Backend backend) override { 72cb93a386Sopenharmony_ci return backend == kNonRendering_Backend; 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_ciprotected: 76cb93a386Sopenharmony_ci const char* onGetName() override { 77cb93a386Sopenharmony_ci return fName.c_str(); 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas*) override { 81cb93a386Sopenharmony_ci // Need to do *something* with the results, so the compile doesn't elide 82cb93a386Sopenharmony_ci // away the code we want to time. 83cb93a386Sopenharmony_ci auto handle = [this](int verb, const SkPoint pts[]) { 84cb93a386Sopenharmony_ci fVerbInc += verb; 85cb93a386Sopenharmony_ci fXInc += pts[0].fX; 86cb93a386Sopenharmony_ci fYInc += pts[0].fY; 87cb93a386Sopenharmony_ci }; 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci switch (fType) { 90cb93a386Sopenharmony_ci case PathIterType::kIter: 91cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 92cb93a386Sopenharmony_ci SkPath::Iter iter(fPath, true); 93cb93a386Sopenharmony_ci SkPath::Verb verb; 94cb93a386Sopenharmony_ci SkPoint pts[4]; 95cb93a386Sopenharmony_ci while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 96cb93a386Sopenharmony_ci handle(verb, pts); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci break; 100cb93a386Sopenharmony_ci case PathIterType::kRaw: 101cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 102cb93a386Sopenharmony_ci for (auto [verb, pts, w] : SkPathPriv::Iterate(fPath)) { 103cb93a386Sopenharmony_ci handle((SkPath::Verb)verb, pts); 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci break; 107cb93a386Sopenharmony_ci case PathIterType::kEdge: 108cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 109cb93a386Sopenharmony_ci SkPathEdgeIter iter(fPath); 110cb93a386Sopenharmony_ci while (auto r = iter.next()) { 111cb93a386Sopenharmony_ci handle((int)r.fEdge, r.fPts); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci } 114cb93a386Sopenharmony_ci break; 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ciprivate: 119cb93a386Sopenharmony_ci using INHERITED = Benchmark; 120cb93a386Sopenharmony_ci}; 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ciDEF_BENCH( return new PathIterBench(PathIterType::kIter); ) 125cb93a386Sopenharmony_ciDEF_BENCH( return new PathIterBench(PathIterType::kRaw); ) 126cb93a386Sopenharmony_ciDEF_BENCH( return new PathIterBench(PathIterType::kEdge); ) 127