1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2013 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #include "bench/Benchmark.h" 9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h" 10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h" 15*c8dee2aaSAndroid Build Coastguard Worker 16*c8dee2aaSAndroid Build Coastguard Worker enum Flags { 17*c8dee2aaSAndroid Build Coastguard Worker kBig_Flag = 1 << 0, 18*c8dee2aaSAndroid Build Coastguard Worker kAA_Flag = 1 << 1 19*c8dee2aaSAndroid Build Coastguard Worker }; 20*c8dee2aaSAndroid Build Coastguard Worker 21*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS00 Flags(0) 22*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS01 Flags(kBig_Flag) 23*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS10 Flags(kAA_Flag) 24*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS11 Flags(kBig_Flag | kAA_Flag) 25*c8dee2aaSAndroid Build Coastguard Worker 26*c8dee2aaSAndroid Build Coastguard Worker static const int points[] = { 27*c8dee2aaSAndroid Build Coastguard Worker 10, 10, 15, 5, 20, 20, 28*c8dee2aaSAndroid Build Coastguard Worker 30, 5, 25, 20, 15, 12, 29*c8dee2aaSAndroid Build Coastguard Worker 21, 21, 30, 30, 12, 4, 30*c8dee2aaSAndroid Build Coastguard Worker 32, 28, 20, 18, 12, 10 31*c8dee2aaSAndroid Build Coastguard Worker }; 32*c8dee2aaSAndroid Build Coastguard Worker 33*c8dee2aaSAndroid Build Coastguard Worker static const int kMaxPathSize = 10; 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker class HairlinePathBench : public Benchmark { 36*c8dee2aaSAndroid Build Coastguard Worker public: HairlinePathBench(Flags flags)37*c8dee2aaSAndroid Build Coastguard Worker HairlinePathBench(Flags flags) : fFlags(flags) { 38*c8dee2aaSAndroid Build Coastguard Worker fPaint.setStyle(SkPaint::kStroke_Style); 39*c8dee2aaSAndroid Build Coastguard Worker fPaint.setStrokeWidth(SkIntToScalar(0)); 40*c8dee2aaSAndroid Build Coastguard Worker } 41*c8dee2aaSAndroid Build Coastguard Worker 42*c8dee2aaSAndroid Build Coastguard Worker virtual void appendName(SkString*) = 0; 43*c8dee2aaSAndroid Build Coastguard Worker virtual void makePath(SkPath*) = 0; 44*c8dee2aaSAndroid Build Coastguard Worker 45*c8dee2aaSAndroid Build Coastguard Worker protected: onGetName()46*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override { 47*c8dee2aaSAndroid Build Coastguard Worker fName.printf("path_hairline_%s_%s_", 48*c8dee2aaSAndroid Build Coastguard Worker fFlags & kBig_Flag ? "big" : "small", 49*c8dee2aaSAndroid Build Coastguard Worker fFlags & kAA_Flag ? "AA" : "noAA"); 50*c8dee2aaSAndroid Build Coastguard Worker this->appendName(&fName); 51*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str(); 52*c8dee2aaSAndroid Build Coastguard Worker } 53*c8dee2aaSAndroid Build Coastguard Worker onDraw(int loops,SkCanvas * canvas)54*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override { 55*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint(fPaint); 56*c8dee2aaSAndroid Build Coastguard Worker this->setupPaint(&paint); 57*c8dee2aaSAndroid Build Coastguard Worker 58*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(fFlags & kAA_Flag ? true : false); 59*c8dee2aaSAndroid Build Coastguard Worker 60*c8dee2aaSAndroid Build Coastguard Worker SkPath path; 61*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&path); 62*c8dee2aaSAndroid Build Coastguard Worker if (fFlags & kBig_Flag) { 63*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix m = SkMatrix::Scale(3, 3); 64*c8dee2aaSAndroid Build Coastguard Worker path.transform(m); 65*c8dee2aaSAndroid Build Coastguard Worker } 66*c8dee2aaSAndroid Build Coastguard Worker 67*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; i++) { 68*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < 100; ++j) { 69*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint); 70*c8dee2aaSAndroid Build Coastguard Worker } 71*c8dee2aaSAndroid Build Coastguard Worker } 72*c8dee2aaSAndroid Build Coastguard Worker } 73*c8dee2aaSAndroid Build Coastguard Worker 74*c8dee2aaSAndroid Build Coastguard Worker private: 75*c8dee2aaSAndroid Build Coastguard Worker SkPaint fPaint; 76*c8dee2aaSAndroid Build Coastguard Worker SkString fName; 77*c8dee2aaSAndroid Build Coastguard Worker Flags fFlags; 78*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark; 79*c8dee2aaSAndroid Build Coastguard Worker }; 80*c8dee2aaSAndroid Build Coastguard Worker 81*c8dee2aaSAndroid Build Coastguard Worker class LinePathBench : public HairlinePathBench { 82*c8dee2aaSAndroid Build Coastguard Worker public: LinePathBench(Flags flags)83*c8dee2aaSAndroid Build Coastguard Worker LinePathBench(Flags flags) : INHERITED(flags) {} 84*c8dee2aaSAndroid Build Coastguard Worker appendName(SkString * name)85*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override { 86*c8dee2aaSAndroid Build Coastguard Worker name->append("line"); 87*c8dee2aaSAndroid Build Coastguard Worker } makePath(SkPath * path)88*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override { 89*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand; 90*c8dee2aaSAndroid Build Coastguard Worker int size = std::size(points); 91*c8dee2aaSAndroid Build Coastguard Worker int hSize = size / 2; 92*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kMaxPathSize; ++i) { 93*c8dee2aaSAndroid Build Coastguard Worker int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 94*c8dee2aaSAndroid Build Coastguard Worker int yTrans = 0; 95*c8dee2aaSAndroid Build Coastguard Worker if (i > kMaxPathSize/2 - 1) { 96*c8dee2aaSAndroid Build Coastguard Worker yTrans = 40; 97*c8dee2aaSAndroid Build Coastguard Worker } 98*c8dee2aaSAndroid Build Coastguard Worker int base1 = 2 * rand.nextULessThan(hSize); 99*c8dee2aaSAndroid Build Coastguard Worker int base2 = 2 * rand.nextULessThan(hSize); 100*c8dee2aaSAndroid Build Coastguard Worker int base3 = 2 * rand.nextULessThan(hSize); 101*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(SkIntToScalar(points[base1] + xTrans), 102*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base1+1] + yTrans)); 103*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(SkIntToScalar(points[base2] + xTrans), 104*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base2+1] + yTrans)); 105*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(SkIntToScalar(points[base3] + xTrans), 106*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3+1] + yTrans)); 107*c8dee2aaSAndroid Build Coastguard Worker } 108*c8dee2aaSAndroid Build Coastguard Worker } 109*c8dee2aaSAndroid Build Coastguard Worker private: 110*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = HairlinePathBench; 111*c8dee2aaSAndroid Build Coastguard Worker }; 112*c8dee2aaSAndroid Build Coastguard Worker 113*c8dee2aaSAndroid Build Coastguard Worker class QuadPathBench : public HairlinePathBench { 114*c8dee2aaSAndroid Build Coastguard Worker public: QuadPathBench(Flags flags)115*c8dee2aaSAndroid Build Coastguard Worker QuadPathBench(Flags flags) : INHERITED(flags) {} 116*c8dee2aaSAndroid Build Coastguard Worker appendName(SkString * name)117*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override { 118*c8dee2aaSAndroid Build Coastguard Worker name->append("quad"); 119*c8dee2aaSAndroid Build Coastguard Worker } makePath(SkPath * path)120*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override { 121*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand; 122*c8dee2aaSAndroid Build Coastguard Worker int size = std::size(points); 123*c8dee2aaSAndroid Build Coastguard Worker int hSize = size / 2; 124*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kMaxPathSize; ++i) { 125*c8dee2aaSAndroid Build Coastguard Worker int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 126*c8dee2aaSAndroid Build Coastguard Worker int yTrans = 0; 127*c8dee2aaSAndroid Build Coastguard Worker if (i > kMaxPathSize/2 - 1) { 128*c8dee2aaSAndroid Build Coastguard Worker yTrans = 40; 129*c8dee2aaSAndroid Build Coastguard Worker } 130*c8dee2aaSAndroid Build Coastguard Worker int base1 = 2 * rand.nextULessThan(hSize); 131*c8dee2aaSAndroid Build Coastguard Worker int base2 = 2 * rand.nextULessThan(hSize); 132*c8dee2aaSAndroid Build Coastguard Worker int base3 = 2 * rand.nextULessThan(hSize); 133*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(SkIntToScalar(points[base1] + xTrans), 134*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base1+1] + yTrans)); 135*c8dee2aaSAndroid Build Coastguard Worker path->quadTo(SkIntToScalar(points[base2] + xTrans), 136*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base2+1] + yTrans), 137*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3] + xTrans), 138*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3+1] + yTrans)); 139*c8dee2aaSAndroid Build Coastguard Worker } 140*c8dee2aaSAndroid Build Coastguard Worker } 141*c8dee2aaSAndroid Build Coastguard Worker private: 142*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = HairlinePathBench; 143*c8dee2aaSAndroid Build Coastguard Worker }; 144*c8dee2aaSAndroid Build Coastguard Worker 145*c8dee2aaSAndroid Build Coastguard Worker class ConicPathBench : public HairlinePathBench { 146*c8dee2aaSAndroid Build Coastguard Worker public: ConicPathBench(Flags flags)147*c8dee2aaSAndroid Build Coastguard Worker ConicPathBench(Flags flags) : INHERITED(flags) {} 148*c8dee2aaSAndroid Build Coastguard Worker appendName(SkString * name)149*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override { 150*c8dee2aaSAndroid Build Coastguard Worker name->append("conic"); 151*c8dee2aaSAndroid Build Coastguard Worker } makePath(SkPath * path)152*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override { 153*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand; 154*c8dee2aaSAndroid Build Coastguard Worker SkRandom randWeight; 155*c8dee2aaSAndroid Build Coastguard Worker int size = std::size(points); 156*c8dee2aaSAndroid Build Coastguard Worker int hSize = size / 2; 157*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kMaxPathSize; ++i) { 158*c8dee2aaSAndroid Build Coastguard Worker int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 159*c8dee2aaSAndroid Build Coastguard Worker int yTrans = 0; 160*c8dee2aaSAndroid Build Coastguard Worker if (i > kMaxPathSize/2 - 1) { 161*c8dee2aaSAndroid Build Coastguard Worker yTrans = 40; 162*c8dee2aaSAndroid Build Coastguard Worker } 163*c8dee2aaSAndroid Build Coastguard Worker int base1 = 2 * rand.nextULessThan(hSize); 164*c8dee2aaSAndroid Build Coastguard Worker int base2 = 2 * rand.nextULessThan(hSize); 165*c8dee2aaSAndroid Build Coastguard Worker int base3 = 2 * rand.nextULessThan(hSize); 166*c8dee2aaSAndroid Build Coastguard Worker float weight = randWeight.nextRangeF(0.0f, 2.0f); 167*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(SkIntToScalar(points[base1] + xTrans), 168*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base1+1] + yTrans)); 169*c8dee2aaSAndroid Build Coastguard Worker path->conicTo(SkIntToScalar(points[base2] + xTrans), 170*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base2+1] + yTrans), 171*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3] + xTrans), 172*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3+1] + yTrans), 173*c8dee2aaSAndroid Build Coastguard Worker weight); 174*c8dee2aaSAndroid Build Coastguard Worker } 175*c8dee2aaSAndroid Build Coastguard Worker } 176*c8dee2aaSAndroid Build Coastguard Worker 177*c8dee2aaSAndroid Build Coastguard Worker private: 178*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = HairlinePathBench; 179*c8dee2aaSAndroid Build Coastguard Worker }; 180*c8dee2aaSAndroid Build Coastguard Worker 181*c8dee2aaSAndroid Build Coastguard Worker class CubicPathBench : public HairlinePathBench { 182*c8dee2aaSAndroid Build Coastguard Worker public: CubicPathBench(Flags flags)183*c8dee2aaSAndroid Build Coastguard Worker CubicPathBench(Flags flags) : INHERITED(flags) {} 184*c8dee2aaSAndroid Build Coastguard Worker appendName(SkString * name)185*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override { 186*c8dee2aaSAndroid Build Coastguard Worker name->append("cubic"); 187*c8dee2aaSAndroid Build Coastguard Worker } makePath(SkPath * path)188*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override { 189*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand; 190*c8dee2aaSAndroid Build Coastguard Worker int size = std::size(points); 191*c8dee2aaSAndroid Build Coastguard Worker int hSize = size / 2; 192*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kMaxPathSize; ++i) { 193*c8dee2aaSAndroid Build Coastguard Worker int xTrans = 10 + 40 * (i%(kMaxPathSize/2)); 194*c8dee2aaSAndroid Build Coastguard Worker int yTrans = 0; 195*c8dee2aaSAndroid Build Coastguard Worker if (i > kMaxPathSize/2 - 1) { 196*c8dee2aaSAndroid Build Coastguard Worker yTrans = 40; 197*c8dee2aaSAndroid Build Coastguard Worker } 198*c8dee2aaSAndroid Build Coastguard Worker int base1 = 2 * rand.nextULessThan(hSize); 199*c8dee2aaSAndroid Build Coastguard Worker int base2 = 2 * rand.nextULessThan(hSize); 200*c8dee2aaSAndroid Build Coastguard Worker int base3 = 2 * rand.nextULessThan(hSize); 201*c8dee2aaSAndroid Build Coastguard Worker int base4 = 2 * rand.nextULessThan(hSize); 202*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(SkIntToScalar(points[base1] + xTrans), 203*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base1+1] + yTrans)); 204*c8dee2aaSAndroid Build Coastguard Worker path->cubicTo(SkIntToScalar(points[base2] + xTrans), 205*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base2+1] + yTrans), 206*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3] + xTrans), 207*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base3+1] + yTrans), 208*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base4] + xTrans), 209*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(points[base4+1] + yTrans)); 210*c8dee2aaSAndroid Build Coastguard Worker } 211*c8dee2aaSAndroid Build Coastguard Worker } 212*c8dee2aaSAndroid Build Coastguard Worker private: 213*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = HairlinePathBench; 214*c8dee2aaSAndroid Build Coastguard Worker }; 215*c8dee2aaSAndroid Build Coastguard Worker 216*c8dee2aaSAndroid Build Coastguard Worker // FLAG00 - no AA, small 217*c8dee2aaSAndroid Build Coastguard Worker // FLAG01 - no AA, small 218*c8dee2aaSAndroid Build Coastguard Worker // FLAG10 - AA, big 219*c8dee2aaSAndroid Build Coastguard Worker // FLAG11 - AA, big 220*c8dee2aaSAndroid Build Coastguard Worker 221*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LinePathBench(FLAGS00); ) 222*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LinePathBench(FLAGS01); ) 223*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LinePathBench(FLAGS10); ) 224*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LinePathBench(FLAGS11); ) 225*c8dee2aaSAndroid Build Coastguard Worker 226*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new QuadPathBench(FLAGS00); ) 227*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new QuadPathBench(FLAGS01); ) 228*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new QuadPathBench(FLAGS10); ) 229*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new QuadPathBench(FLAGS11); ) 230*c8dee2aaSAndroid Build Coastguard Worker 231*c8dee2aaSAndroid Build Coastguard Worker // Don't have default path renderer for conics yet on GPU, so must use AA 232*c8dee2aaSAndroid Build Coastguard Worker // DEF_BENCH( return new ConicPathBench(FLAGS00); ) 233*c8dee2aaSAndroid Build Coastguard Worker // DEF_BENCH( return new ConicPathBench(FLAGS01); ) 234*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicPathBench(FLAGS10); ) 235*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicPathBench(FLAGS11); ) 236*c8dee2aaSAndroid Build Coastguard Worker 237*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CubicPathBench(FLAGS00); ) 238*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CubicPathBench(FLAGS01); ) 239*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CubicPathBench(FLAGS10); ) 240*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CubicPathBench(FLAGS11); ) 241