DashBench.cpp revision 4ad22753504828342e47627b12210c2c47e7290a
1 2/* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8#include "SkBenchmark.h" 9#include "SkBitmap.h" 10#include "SkCanvas.h" 11#include "SkDashPathEffect.h" 12#include "SkPaint.h" 13#include "SkPath.h" 14#include "SkRandom.h" 15#include "SkString.h" 16#include "SkTDArray.h" 17 18 19/* 20 * Cases to consider: 21 * 22 * 1. antialiasing on/off (esp. width <= 1) 23 * 2. strokewidth == 0, 1, 2 24 * 3. hline, vline, diagonal, rect, oval 25 * 4. dots [1,1] ([N,N] where N=strokeWidth?) or arbitrary (e.g. [2,1] or [1,2,3,2]) 26 */ 27static void path_hline(SkPath* path) { 28 path->moveTo(SkIntToScalar(10), SkIntToScalar(10)); 29 path->lineTo(SkIntToScalar(600), SkIntToScalar(10)); 30} 31 32class DashBench : public SkBenchmark { 33protected: 34 SkString fName; 35 SkTDArray<SkScalar> fIntervals; 36 int fWidth; 37 bool fDoClip; 38 39 enum { 40 N = SkBENCHLOOP(100) 41 }; 42public: 43 DashBench(void* param, const SkScalar intervals[], int count, int width, 44 bool doClip = false) : INHERITED(param) { 45 fIntervals.append(count, intervals); 46 for (int i = 0; i < count; ++i) { 47 fIntervals[i] *= width; 48 } 49 fWidth = width; 50 fName.printf("dash_%d_%s", width, doClip ? "clipped" : "noclip"); 51 fDoClip = doClip; 52 } 53 54 virtual void makePath(SkPath* path) { 55 path_hline(path); 56 } 57 58protected: 59 virtual const char* onGetName() SK_OVERRIDE { 60 return fName.c_str(); 61 } 62 63 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 64 SkPaint paint; 65 this->setupPaint(&paint); 66 paint.setStyle(SkPaint::kStroke_Style); 67 paint.setStrokeWidth(SkIntToScalar(fWidth)); 68 paint.setAntiAlias(false); 69 70 SkPath path; 71 this->makePath(&path); 72 73 paint.setPathEffect(new SkDashPathEffect(fIntervals.begin(), 74 fIntervals.count(), 0))->unref(); 75 76 if (fDoClip) { 77 SkRect r = path.getBounds(); 78 r.inset(-SkIntToScalar(20), -SkIntToScalar(20)); 79 // now move it so we don't intersect 80 r.offset(0, r.height() * 3 / 2); 81 canvas->clipRect(r); 82 } 83 84 this->handlePath(canvas, path, paint, N); 85 } 86 87 virtual void handlePath(SkCanvas* canvas, const SkPath& path, 88 const SkPaint& paint, int N) { 89 for (int i = 0; i < N; ++i) { 90 canvas->drawPath(path, paint); 91 } 92 } 93 94private: 95 typedef SkBenchmark INHERITED; 96}; 97 98class RectDashBench : public DashBench { 99public: 100 RectDashBench(void* param, const SkScalar intervals[], int count, int width, bool doClip = false) 101 : INHERITED(param, intervals, count, width) { 102 fName.append("_rect"); 103 } 104 105protected: 106 virtual void handlePath(SkCanvas* canvas, const SkPath& path, 107 const SkPaint& paint, int N) SK_OVERRIDE { 108 SkPoint pts[2]; 109 if (!path.isLine(pts) || pts[0].fY != pts[1].fY) { 110 this->INHERITED::handlePath(canvas, path, paint, N); 111 } else { 112 SkRect rect; 113 rect.fLeft = pts[0].fX; 114 rect.fTop = pts[0].fY - paint.getStrokeWidth() / 2; 115 rect.fRight = rect.fLeft + SkIntToScalar(fWidth); 116 rect.fBottom = rect.fTop + paint.getStrokeWidth(); 117 118 SkPaint p(paint); 119 p.setStyle(SkPaint::kFill_Style); 120 p.setPathEffect(NULL); 121 122 int count = SkScalarRoundToInt((pts[1].fX - pts[0].fX) / (2*fWidth)); 123 SkScalar dx = SkIntToScalar(2 * fWidth); 124 125 for (int i = 0; i < N*10; ++i) { 126 SkRect r = rect; 127 for (int j = 0; j < count; ++j) { 128 canvas->drawRect(r, p); 129 r.offset(dx, 0); 130 } 131 } 132 } 133 } 134 135private: 136 typedef DashBench INHERITED; 137}; 138 139/////////////////////////////////////////////////////////////////////////////// 140 141static const SkScalar gDots[] = { SK_Scalar1, SK_Scalar1 }; 142 143#define PARAM(array) array, SK_ARRAY_COUNT(array) 144 145static SkBenchmark* gF0(void* p) { return new DashBench(p, PARAM(gDots), 0); } 146static SkBenchmark* gF1(void* p) { return new DashBench(p, PARAM(gDots), 1); } 147static SkBenchmark* gF2(void* p) { return new DashBench(p, PARAM(gDots), 1, true); } 148static SkBenchmark* gF3(void* p) { return new DashBench(p, PARAM(gDots), 4); } 149static SkBenchmark* gF4(void* p) { return new RectDashBench(p, PARAM(gDots), 4); } 150 151static BenchRegistry gR0(gF0); 152static BenchRegistry gR1(gF1); 153static BenchRegistry gR2(gF2); 154static BenchRegistry gR3(gF3); 155static BenchRegistry gR4(gF4); 156