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/SkPaint.h" 11cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 12cb93a386Sopenharmony_ci#include "include/core/SkString.h" 13cb93a386Sopenharmony_ci#include "include/core/SkStrokeRec.h" 14cb93a386Sopenharmony_ci#include "include/effects/SkDashPathEffect.h" 15cb93a386Sopenharmony_ci#include "include/private/SkTDArray.h" 16cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci/* 20cb93a386Sopenharmony_ci * Cases to consider: 21cb93a386Sopenharmony_ci * 22cb93a386Sopenharmony_ci * 1. antialiasing on/off (esp. width <= 1) 23cb93a386Sopenharmony_ci * 2. strokewidth == 0, 1, 2 24cb93a386Sopenharmony_ci * 3. hline, vline, diagonal, rect, oval 25cb93a386Sopenharmony_ci * 4. dots [1,1] ([N,N] where N=strokeWidth?) or arbitrary (e.g. [2,1] or [1,2,3,2]) 26cb93a386Sopenharmony_ci */ 27cb93a386Sopenharmony_cistatic void path_hline(SkPath* path) { 28cb93a386Sopenharmony_ci path->moveTo(SkIntToScalar(10), SkIntToScalar(10)); 29cb93a386Sopenharmony_ci path->lineTo(SkIntToScalar(600), SkIntToScalar(10)); 30cb93a386Sopenharmony_ci} 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ciclass DashBench : public Benchmark { 33cb93a386Sopenharmony_ciprotected: 34cb93a386Sopenharmony_ci SkString fName; 35cb93a386Sopenharmony_ci SkTDArray<SkScalar> fIntervals; 36cb93a386Sopenharmony_ci int fWidth; 37cb93a386Sopenharmony_ci SkPoint fPts[2]; 38cb93a386Sopenharmony_ci bool fDoClip; 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_cipublic: 41cb93a386Sopenharmony_ci DashBench(const SkScalar intervals[], int count, int width, 42cb93a386Sopenharmony_ci bool doClip = false) { 43cb93a386Sopenharmony_ci fIntervals.append(count, intervals); 44cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 45cb93a386Sopenharmony_ci fIntervals[i] *= width; 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci fWidth = width; 48cb93a386Sopenharmony_ci fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip"); 49cb93a386Sopenharmony_ci fDoClip = doClip; 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_ci fPts[0].set(SkIntToScalar(10), SkIntToScalar(10)); 52cb93a386Sopenharmony_ci fPts[1].set(SkIntToScalar(600), SkIntToScalar(10)); 53cb93a386Sopenharmony_ci } 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci virtual void makePath(SkPath* path) { 56cb93a386Sopenharmony_ci path_hline(path); 57cb93a386Sopenharmony_ci } 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ciprotected: 60cb93a386Sopenharmony_ci const char* onGetName() override { 61cb93a386Sopenharmony_ci return fName.c_str(); 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 65cb93a386Sopenharmony_ci SkPaint paint; 66cb93a386Sopenharmony_ci this->setupPaint(&paint); 67cb93a386Sopenharmony_ci paint.setStyle(SkPaint::kStroke_Style); 68cb93a386Sopenharmony_ci paint.setStrokeWidth(SkIntToScalar(fWidth)); 69cb93a386Sopenharmony_ci paint.setAntiAlias(false); 70cb93a386Sopenharmony_ci 71cb93a386Sopenharmony_ci SkPath path; 72cb93a386Sopenharmony_ci this->makePath(&path); 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci paint.setPathEffect(SkDashPathEffect::Make(fIntervals.begin(), fIntervals.count(), 0)); 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci if (fDoClip) { 77cb93a386Sopenharmony_ci SkRect r = path.getBounds(); 78cb93a386Sopenharmony_ci r.inset(-SkIntToScalar(20), -SkIntToScalar(20)); 79cb93a386Sopenharmony_ci // now move it so we don't intersect 80cb93a386Sopenharmony_ci r.offset(0, r.height() * 3 / 2); 81cb93a386Sopenharmony_ci canvas->clipRect(r); 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_ci this->handlePath(canvas, path, paint, loops); 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci virtual void handlePath(SkCanvas* canvas, const SkPath& path, 88cb93a386Sopenharmony_ci const SkPaint& paint, int N) { 89cb93a386Sopenharmony_ci for (int i = 0; i < N; ++i) { 90cb93a386Sopenharmony_ci// canvas->drawPoints(SkCanvas::kLines_PointMode, 2, fPts, paint); 91cb93a386Sopenharmony_ci canvas->drawPath(path, paint); 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ciprivate: 96cb93a386Sopenharmony_ci using INHERITED = Benchmark; 97cb93a386Sopenharmony_ci}; 98cb93a386Sopenharmony_ci 99cb93a386Sopenharmony_ciclass RectDashBench : public DashBench { 100cb93a386Sopenharmony_cipublic: 101cb93a386Sopenharmony_ci RectDashBench(const SkScalar intervals[], int count, int width) 102cb93a386Sopenharmony_ci : INHERITED(intervals, count, width) { 103cb93a386Sopenharmony_ci fName.append("_rect"); 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ciprotected: 107cb93a386Sopenharmony_ci void handlePath(SkCanvas* canvas, const SkPath& path, const SkPaint& paint, int N) override { 108cb93a386Sopenharmony_ci SkPoint pts[2]; 109cb93a386Sopenharmony_ci if (!path.isLine(pts) || pts[0].fY != pts[1].fY) { 110cb93a386Sopenharmony_ci this->INHERITED::handlePath(canvas, path, paint, N); 111cb93a386Sopenharmony_ci } else { 112cb93a386Sopenharmony_ci SkRect rect; 113cb93a386Sopenharmony_ci rect.fLeft = pts[0].fX; 114cb93a386Sopenharmony_ci rect.fTop = pts[0].fY - paint.getStrokeWidth() / 2; 115cb93a386Sopenharmony_ci rect.fRight = rect.fLeft + SkIntToScalar(fWidth); 116cb93a386Sopenharmony_ci rect.fBottom = rect.fTop + paint.getStrokeWidth(); 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci SkPaint p(paint); 119cb93a386Sopenharmony_ci p.setStyle(SkPaint::kFill_Style); 120cb93a386Sopenharmony_ci p.setPathEffect(nullptr); 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci int count = SkScalarRoundToInt((pts[1].fX - pts[0].fX) / (2*fWidth)); 123cb93a386Sopenharmony_ci SkScalar dx = SkIntToScalar(2 * fWidth); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci for (int i = 0; i < N*10; ++i) { 126cb93a386Sopenharmony_ci SkRect r = rect; 127cb93a386Sopenharmony_ci for (int j = 0; j < count; ++j) { 128cb93a386Sopenharmony_ci canvas->drawRect(r, p); 129cb93a386Sopenharmony_ci r.offset(dx, 0); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ciprivate: 136cb93a386Sopenharmony_ci using INHERITED = DashBench; 137cb93a386Sopenharmony_ci}; 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_cistatic void make_unit_star(SkPath* path, int n) { 140cb93a386Sopenharmony_ci SkScalar rad = -SK_ScalarPI / 2; 141cb93a386Sopenharmony_ci const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n; 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci path->moveTo(0, -SK_Scalar1); 144cb93a386Sopenharmony_ci for (int i = 1; i < n; i++) { 145cb93a386Sopenharmony_ci rad += drad; 146cb93a386Sopenharmony_ci path->lineTo(SkScalarCos(rad), SkScalarSin(rad)); 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci path->close(); 149cb93a386Sopenharmony_ci} 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_cistatic void make_poly(SkPath* path) { 152cb93a386Sopenharmony_ci make_unit_star(path, 9); 153cb93a386Sopenharmony_ci const SkMatrix matrix = SkMatrix::Scale(100, 100); 154cb93a386Sopenharmony_ci path->transform(matrix); 155cb93a386Sopenharmony_ci} 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_cistatic void make_quad(SkPath* path) { 158cb93a386Sopenharmony_ci SkScalar x0 = SkIntToScalar(10); 159cb93a386Sopenharmony_ci SkScalar y0 = SkIntToScalar(10); 160cb93a386Sopenharmony_ci path->moveTo(x0, y0); 161cb93a386Sopenharmony_ci path->quadTo(x0, y0 + 400 * SK_Scalar1, 162cb93a386Sopenharmony_ci x0 + 600 * SK_Scalar1, y0 + 400 * SK_Scalar1); 163cb93a386Sopenharmony_ci} 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_cistatic void make_cubic(SkPath* path) { 166cb93a386Sopenharmony_ci SkScalar x0 = SkIntToScalar(10); 167cb93a386Sopenharmony_ci SkScalar y0 = SkIntToScalar(10); 168cb93a386Sopenharmony_ci path->moveTo(x0, y0); 169cb93a386Sopenharmony_ci path->cubicTo(x0, y0 + 400 * SK_Scalar1, 170cb93a386Sopenharmony_ci x0 + 600 * SK_Scalar1, y0 + 400 * SK_Scalar1, 171cb93a386Sopenharmony_ci x0 + 600 * SK_Scalar1, y0); 172cb93a386Sopenharmony_ci} 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ciclass MakeDashBench : public Benchmark { 175cb93a386Sopenharmony_ci SkString fName; 176cb93a386Sopenharmony_ci SkPath fPath; 177cb93a386Sopenharmony_ci sk_sp<SkPathEffect> fPE; 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_cipublic: 180cb93a386Sopenharmony_ci MakeDashBench(void (*proc)(SkPath*), const char name[]) { 181cb93a386Sopenharmony_ci fName.printf("makedash_%s", name); 182cb93a386Sopenharmony_ci proc(&fPath); 183cb93a386Sopenharmony_ci 184cb93a386Sopenharmony_ci SkScalar vals[] = { SkIntToScalar(4), SkIntToScalar(4) }; 185cb93a386Sopenharmony_ci fPE = SkDashPathEffect::Make(vals, 2, 0); 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ciprotected: 189cb93a386Sopenharmony_ci const char* onGetName() override { 190cb93a386Sopenharmony_ci return fName.c_str(); 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas*) override { 194cb93a386Sopenharmony_ci SkPath dst; 195cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 196cb93a386Sopenharmony_ci SkStrokeRec rec(SkStrokeRec::kHairline_InitStyle); 197cb93a386Sopenharmony_ci 198cb93a386Sopenharmony_ci fPE->filterPath(&dst, fPath, &rec, nullptr); 199cb93a386Sopenharmony_ci dst.rewind(); 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci } 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ciprivate: 204cb93a386Sopenharmony_ci using INHERITED = Benchmark; 205cb93a386Sopenharmony_ci}; 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_ci/* 208cb93a386Sopenharmony_ci * We try to special case square dashes (intervals are equal to strokewidth). 209cb93a386Sopenharmony_ci */ 210cb93a386Sopenharmony_ciclass DashLineBench : public Benchmark { 211cb93a386Sopenharmony_ci SkString fName; 212cb93a386Sopenharmony_ci SkScalar fStrokeWidth; 213cb93a386Sopenharmony_ci bool fIsRound; 214cb93a386Sopenharmony_ci sk_sp<SkPathEffect> fPE; 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_cipublic: 217cb93a386Sopenharmony_ci DashLineBench(SkScalar width, bool isRound) { 218cb93a386Sopenharmony_ci fName.printf("dashline_%g_%s", SkScalarToFloat(width), isRound ? "circle" : "square"); 219cb93a386Sopenharmony_ci fStrokeWidth = width; 220cb93a386Sopenharmony_ci fIsRound = isRound; 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_ci SkScalar vals[] = { SK_Scalar1, SK_Scalar1 }; 223cb93a386Sopenharmony_ci fPE = SkDashPathEffect::Make(vals, 2, 0); 224cb93a386Sopenharmony_ci } 225cb93a386Sopenharmony_ci 226cb93a386Sopenharmony_ciprotected: 227cb93a386Sopenharmony_ci const char* onGetName() override { 228cb93a386Sopenharmony_ci return fName.c_str(); 229cb93a386Sopenharmony_ci } 230cb93a386Sopenharmony_ci 231cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 232cb93a386Sopenharmony_ci SkPaint paint; 233cb93a386Sopenharmony_ci this->setupPaint(&paint); 234cb93a386Sopenharmony_ci paint.setStrokeWidth(fStrokeWidth); 235cb93a386Sopenharmony_ci paint.setStrokeCap(fIsRound ? SkPaint::kRound_Cap : SkPaint::kSquare_Cap); 236cb93a386Sopenharmony_ci paint.setPathEffect(fPE); 237cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 238cb93a386Sopenharmony_ci canvas->drawLine(10 * SK_Scalar1, 10 * SK_Scalar1, 239cb93a386Sopenharmony_ci 640 * SK_Scalar1, 10 * SK_Scalar1, paint); 240cb93a386Sopenharmony_ci } 241cb93a386Sopenharmony_ci } 242cb93a386Sopenharmony_ci 243cb93a386Sopenharmony_ciprivate: 244cb93a386Sopenharmony_ci using INHERITED = Benchmark; 245cb93a386Sopenharmony_ci}; 246cb93a386Sopenharmony_ci 247cb93a386Sopenharmony_ciclass DrawPointsDashingBench : public Benchmark { 248cb93a386Sopenharmony_ci SkString fName; 249cb93a386Sopenharmony_ci int fStrokeWidth; 250cb93a386Sopenharmony_ci bool fDoAA; 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_ci sk_sp<SkPathEffect> fPathEffect; 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_cipublic: 255cb93a386Sopenharmony_ci DrawPointsDashingBench(int dashLength, int strokeWidth, bool doAA) 256cb93a386Sopenharmony_ci { 257cb93a386Sopenharmony_ci fName.printf("drawpointsdash_%d_%d%s", dashLength, strokeWidth, doAA ? "_aa" : "_bw"); 258cb93a386Sopenharmony_ci fStrokeWidth = strokeWidth; 259cb93a386Sopenharmony_ci fDoAA = doAA; 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci SkScalar vals[] = { SkIntToScalar(dashLength), SkIntToScalar(dashLength) }; 262cb93a386Sopenharmony_ci fPathEffect = SkDashPathEffect::Make(vals, 2, SK_Scalar1); 263cb93a386Sopenharmony_ci } 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ciprotected: 266cb93a386Sopenharmony_ci const char* onGetName() override { 267cb93a386Sopenharmony_ci return fName.c_str(); 268cb93a386Sopenharmony_ci } 269cb93a386Sopenharmony_ci 270cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 271cb93a386Sopenharmony_ci SkPaint p; 272cb93a386Sopenharmony_ci this->setupPaint(&p); 273cb93a386Sopenharmony_ci p.setColor(SK_ColorBLACK); 274cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 275cb93a386Sopenharmony_ci p.setStrokeWidth(SkIntToScalar(fStrokeWidth)); 276cb93a386Sopenharmony_ci p.setPathEffect(fPathEffect); 277cb93a386Sopenharmony_ci p.setAntiAlias(fDoAA); 278cb93a386Sopenharmony_ci 279cb93a386Sopenharmony_ci SkPoint pts[2] = { 280cb93a386Sopenharmony_ci { SkIntToScalar(10), 0 }, 281cb93a386Sopenharmony_ci { SkIntToScalar(640), 0 } 282cb93a386Sopenharmony_ci }; 283cb93a386Sopenharmony_ci 284cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 285cb93a386Sopenharmony_ci pts[0].fY = pts[1].fY = SkIntToScalar(i % 480); 286cb93a386Sopenharmony_ci canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p); 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci } 289cb93a386Sopenharmony_ci 290cb93a386Sopenharmony_ciprivate: 291cb93a386Sopenharmony_ci using INHERITED = Benchmark; 292cb93a386Sopenharmony_ci}; 293cb93a386Sopenharmony_ci 294cb93a386Sopenharmony_ci// Want to test how we handle dashing when 99% of the dash is clipped out 295cb93a386Sopenharmony_ciclass GiantDashBench : public Benchmark { 296cb93a386Sopenharmony_ci SkString fName; 297cb93a386Sopenharmony_ci SkScalar fStrokeWidth; 298cb93a386Sopenharmony_ci SkPoint fPts[2]; 299cb93a386Sopenharmony_ci sk_sp<SkPathEffect> fPathEffect; 300cb93a386Sopenharmony_ci 301cb93a386Sopenharmony_cipublic: 302cb93a386Sopenharmony_ci enum LineType { 303cb93a386Sopenharmony_ci kHori_LineType, 304cb93a386Sopenharmony_ci kVert_LineType, 305cb93a386Sopenharmony_ci kDiag_LineType, 306cb93a386Sopenharmony_ci kLineTypeCount 307cb93a386Sopenharmony_ci }; 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci static const char* LineTypeName(LineType lt) { 310cb93a386Sopenharmony_ci static const char* gNames[] = { "hori", "vert", "diag" }; 311cb93a386Sopenharmony_ci static_assert(kLineTypeCount == SK_ARRAY_COUNT(gNames), "names_wrong_size"); 312cb93a386Sopenharmony_ci return gNames[lt]; 313cb93a386Sopenharmony_ci } 314cb93a386Sopenharmony_ci 315cb93a386Sopenharmony_ci GiantDashBench(LineType lt, SkScalar width) { 316cb93a386Sopenharmony_ci fName.printf("giantdashline_%s_%g", LineTypeName(lt), width); 317cb93a386Sopenharmony_ci fStrokeWidth = width; 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci // deliberately pick intervals that won't be caught by asPoints(), so 320cb93a386Sopenharmony_ci // we can test the filterPath code-path. 321cb93a386Sopenharmony_ci const SkScalar intervals[] = { 20, 10, 10, 10 }; 322cb93a386Sopenharmony_ci fPathEffect = SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 0); 323cb93a386Sopenharmony_ci 324cb93a386Sopenharmony_ci SkScalar cx = 640 / 2; // center X 325cb93a386Sopenharmony_ci SkScalar cy = 480 / 2; // center Y 326cb93a386Sopenharmony_ci SkMatrix matrix; 327cb93a386Sopenharmony_ci 328cb93a386Sopenharmony_ci switch (lt) { 329cb93a386Sopenharmony_ci case kHori_LineType: 330cb93a386Sopenharmony_ci matrix.setIdentity(); 331cb93a386Sopenharmony_ci break; 332cb93a386Sopenharmony_ci case kVert_LineType: 333cb93a386Sopenharmony_ci matrix.setRotate(90, cx, cy); 334cb93a386Sopenharmony_ci break; 335cb93a386Sopenharmony_ci case kDiag_LineType: 336cb93a386Sopenharmony_ci matrix.setRotate(45, cx, cy); 337cb93a386Sopenharmony_ci break; 338cb93a386Sopenharmony_ci case kLineTypeCount: 339cb93a386Sopenharmony_ci // Not a real enum value. 340cb93a386Sopenharmony_ci break; 341cb93a386Sopenharmony_ci } 342cb93a386Sopenharmony_ci 343cb93a386Sopenharmony_ci const SkScalar overshoot = 100*1000; 344cb93a386Sopenharmony_ci const SkPoint pts[2] = { 345cb93a386Sopenharmony_ci { -overshoot, cy }, { 640 + overshoot, cy } 346cb93a386Sopenharmony_ci }; 347cb93a386Sopenharmony_ci matrix.mapPoints(fPts, pts, 2); 348cb93a386Sopenharmony_ci } 349cb93a386Sopenharmony_ci 350cb93a386Sopenharmony_ciprotected: 351cb93a386Sopenharmony_ci const char* onGetName() override { 352cb93a386Sopenharmony_ci return fName.c_str(); 353cb93a386Sopenharmony_ci } 354cb93a386Sopenharmony_ci 355cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 356cb93a386Sopenharmony_ci SkPaint p; 357cb93a386Sopenharmony_ci this->setupPaint(&p); 358cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 359cb93a386Sopenharmony_ci p.setStrokeWidth(fStrokeWidth); 360cb93a386Sopenharmony_ci p.setPathEffect(fPathEffect); 361cb93a386Sopenharmony_ci 362cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 363cb93a386Sopenharmony_ci canvas->drawPoints(SkCanvas::kLines_PointMode, 2, fPts, p); 364cb93a386Sopenharmony_ci } 365cb93a386Sopenharmony_ci } 366cb93a386Sopenharmony_ci 367cb93a386Sopenharmony_ciprivate: 368cb93a386Sopenharmony_ci using INHERITED = Benchmark; 369cb93a386Sopenharmony_ci}; 370cb93a386Sopenharmony_ci 371cb93a386Sopenharmony_ci// Want to test how we draw a dashed grid (like what is used in spreadsheets) of many 372cb93a386Sopenharmony_ci// small dashed lines switching back and forth between horizontal and vertical 373cb93a386Sopenharmony_ciclass DashGridBench : public Benchmark { 374cb93a386Sopenharmony_ci SkString fName; 375cb93a386Sopenharmony_ci int fStrokeWidth; 376cb93a386Sopenharmony_ci bool fDoAA; 377cb93a386Sopenharmony_ci 378cb93a386Sopenharmony_ci sk_sp<SkPathEffect> fPathEffect; 379cb93a386Sopenharmony_ci 380cb93a386Sopenharmony_cipublic: 381cb93a386Sopenharmony_ci DashGridBench(int dashLength, int strokeWidth, bool doAA) { 382cb93a386Sopenharmony_ci fName.printf("dashgrid_%d_%d%s", dashLength, strokeWidth, doAA ? "_aa" : "_bw"); 383cb93a386Sopenharmony_ci fStrokeWidth = strokeWidth; 384cb93a386Sopenharmony_ci fDoAA = doAA; 385cb93a386Sopenharmony_ci 386cb93a386Sopenharmony_ci SkScalar vals[] = { SkIntToScalar(dashLength), SkIntToScalar(dashLength) }; 387cb93a386Sopenharmony_ci fPathEffect = SkDashPathEffect::Make(vals, 2, SK_Scalar1); 388cb93a386Sopenharmony_ci } 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ciprotected: 391cb93a386Sopenharmony_ci const char* onGetName() override { 392cb93a386Sopenharmony_ci return fName.c_str(); 393cb93a386Sopenharmony_ci } 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 396cb93a386Sopenharmony_ci SkPaint p; 397cb93a386Sopenharmony_ci this->setupPaint(&p); 398cb93a386Sopenharmony_ci p.setColor(SK_ColorBLACK); 399cb93a386Sopenharmony_ci p.setStyle(SkPaint::kStroke_Style); 400cb93a386Sopenharmony_ci p.setStrokeWidth(SkIntToScalar(fStrokeWidth)); 401cb93a386Sopenharmony_ci p.setPathEffect(fPathEffect); 402cb93a386Sopenharmony_ci p.setAntiAlias(fDoAA); 403cb93a386Sopenharmony_ci 404cb93a386Sopenharmony_ci SkPoint pts[4] = { 405cb93a386Sopenharmony_ci { SkIntToScalar(0), 20.5f }, 406cb93a386Sopenharmony_ci { SkIntToScalar(20), 20.5f }, 407cb93a386Sopenharmony_ci { 20.5f, SkIntToScalar(0) }, 408cb93a386Sopenharmony_ci { 20.5f, SkIntToScalar(20) } 409cb93a386Sopenharmony_ci }; 410cb93a386Sopenharmony_ci 411cb93a386Sopenharmony_ci for (int i = 0; i < loops; ++i) { 412cb93a386Sopenharmony_ci for (int j = 0; j < 10; ++j) { 413cb93a386Sopenharmony_ci for (int k = 0; k < 10; ++k) { 414cb93a386Sopenharmony_ci // Horizontal line 415cb93a386Sopenharmony_ci SkPoint horPts[2]; 416cb93a386Sopenharmony_ci horPts[0].fX = pts[0].fX + k * 22.f; 417cb93a386Sopenharmony_ci horPts[0].fY = pts[0].fY + j * 22.f; 418cb93a386Sopenharmony_ci horPts[1].fX = pts[1].fX + k * 22.f; 419cb93a386Sopenharmony_ci horPts[1].fY = pts[1].fY + j * 22.f; 420cb93a386Sopenharmony_ci canvas->drawPoints(SkCanvas::kLines_PointMode, 2, horPts, p); 421cb93a386Sopenharmony_ci 422cb93a386Sopenharmony_ci // Vertical line 423cb93a386Sopenharmony_ci SkPoint vertPts[2]; 424cb93a386Sopenharmony_ci vertPts[0].fX = pts[2].fX + k * 22.f; 425cb93a386Sopenharmony_ci vertPts[0].fY = pts[2].fY + j * 22.f; 426cb93a386Sopenharmony_ci vertPts[1].fX = pts[3].fX + k * 22.f; 427cb93a386Sopenharmony_ci vertPts[1].fY = pts[3].fY + j * 22.f; 428cb93a386Sopenharmony_ci canvas->drawPoints(SkCanvas::kLines_PointMode, 2, vertPts, p); 429cb93a386Sopenharmony_ci } 430cb93a386Sopenharmony_ci } 431cb93a386Sopenharmony_ci } 432cb93a386Sopenharmony_ci } 433cb93a386Sopenharmony_ci 434cb93a386Sopenharmony_ciprivate: 435cb93a386Sopenharmony_ci using INHERITED = Benchmark; 436cb93a386Sopenharmony_ci}; 437cb93a386Sopenharmony_ci 438cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////// 439cb93a386Sopenharmony_ci 440cb93a386Sopenharmony_cistatic const SkScalar gDots[] = { SK_Scalar1, SK_Scalar1 }; 441cb93a386Sopenharmony_ci 442cb93a386Sopenharmony_ci#define PARAM(array) array, SK_ARRAY_COUNT(array) 443cb93a386Sopenharmony_ci 444cb93a386Sopenharmony_ciDEF_BENCH( return new DashBench(PARAM(gDots), 0); ) 445cb93a386Sopenharmony_ciDEF_BENCH( return new DashBench(PARAM(gDots), 1); ) 446cb93a386Sopenharmony_ciDEF_BENCH( return new DashBench(PARAM(gDots), 1, true); ) 447cb93a386Sopenharmony_ciDEF_BENCH( return new DashBench(PARAM(gDots), 4); ) 448cb93a386Sopenharmony_ciDEF_BENCH( return new MakeDashBench(make_poly, "poly"); ) 449cb93a386Sopenharmony_ciDEF_BENCH( return new MakeDashBench(make_quad, "quad"); ) 450cb93a386Sopenharmony_ciDEF_BENCH( return new MakeDashBench(make_cubic, "cubic"); ) 451cb93a386Sopenharmony_ciDEF_BENCH( return new DashLineBench(0, false); ) 452cb93a386Sopenharmony_ciDEF_BENCH( return new DashLineBench(SK_Scalar1, false); ) 453cb93a386Sopenharmony_ciDEF_BENCH( return new DashLineBench(2 * SK_Scalar1, false); ) 454cb93a386Sopenharmony_ciDEF_BENCH( return new DashLineBench(0, true); ) 455cb93a386Sopenharmony_ciDEF_BENCH( return new DashLineBench(SK_Scalar1, true); ) 456cb93a386Sopenharmony_ciDEF_BENCH( return new DashLineBench(2 * SK_Scalar1, true); ) 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_ciDEF_BENCH( return new DrawPointsDashingBench(1, 1, false); ) 459cb93a386Sopenharmony_ciDEF_BENCH( return new DrawPointsDashingBench(1, 1, true); ) 460cb93a386Sopenharmony_ciDEF_BENCH( return new DrawPointsDashingBench(3, 1, false); ) 461cb93a386Sopenharmony_ciDEF_BENCH( return new DrawPointsDashingBench(3, 1, true); ) 462cb93a386Sopenharmony_ciDEF_BENCH( return new DrawPointsDashingBench(5, 5, false); ) 463cb93a386Sopenharmony_ciDEF_BENCH( return new DrawPointsDashingBench(5, 5, true); ) 464cb93a386Sopenharmony_ci 465cb93a386Sopenharmony_ci/* Disable the GiantDashBench for Android devices until we can better control 466cb93a386Sopenharmony_ci * the memory usage. (https://code.google.com/p/skia/issues/detail?id=1430) 467cb93a386Sopenharmony_ci */ 468cb93a386Sopenharmony_ci#ifndef SK_BUILD_FOR_ANDROID 469cb93a386Sopenharmony_ciDEF_BENCH( return new GiantDashBench(GiantDashBench::kHori_LineType, 0); ) 470cb93a386Sopenharmony_ciDEF_BENCH( return new GiantDashBench(GiantDashBench::kVert_LineType, 0); ) 471cb93a386Sopenharmony_ciDEF_BENCH( return new GiantDashBench(GiantDashBench::kDiag_LineType, 0); ) 472cb93a386Sopenharmony_ci 473cb93a386Sopenharmony_ci// pass 2 to explicitly avoid any 1-is-the-same-as-hairline special casing 474cb93a386Sopenharmony_ci 475cb93a386Sopenharmony_ci// hori_2 is just too slow to enable at the moment 476cb93a386Sopenharmony_ciDEF_BENCH( return new GiantDashBench(GiantDashBench::kHori_LineType, 2); ) 477cb93a386Sopenharmony_ciDEF_BENCH( return new GiantDashBench(GiantDashBench::kVert_LineType, 2); ) 478cb93a386Sopenharmony_ciDEF_BENCH( return new GiantDashBench(GiantDashBench::kDiag_LineType, 2); ) 479cb93a386Sopenharmony_ci 480cb93a386Sopenharmony_ciDEF_BENCH( return new DashGridBench(1, 1, true); ) 481cb93a386Sopenharmony_ciDEF_BENCH( return new DashGridBench(1, 1, false); ) 482cb93a386Sopenharmony_ciDEF_BENCH( return new DashGridBench(3, 1, true); ) 483cb93a386Sopenharmony_ciDEF_BENCH( return new DashGridBench(3, 1, false); ) 484cb93a386Sopenharmony_ci#endif 485