1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2014 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/SkColor.h" 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPicture.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPictureRecorder.h" 14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h" 15*c8dee2aaSAndroid Build Coastguard Worker #include "include/utils/SkNullCanvas.h" 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker class PictureNesting : public Benchmark { 18*c8dee2aaSAndroid Build Coastguard Worker public: PictureNesting(const char * name,int maxLevel,int maxPictureLevel)19*c8dee2aaSAndroid Build Coastguard Worker PictureNesting(const char* name, int maxLevel, int maxPictureLevel) 20*c8dee2aaSAndroid Build Coastguard Worker : fMaxLevel(maxLevel) 21*c8dee2aaSAndroid Build Coastguard Worker , fMaxPictureLevel(maxPictureLevel) { 22*c8dee2aaSAndroid Build Coastguard Worker fName.printf("picture_nesting_%s_%d", name, this->countPics()); 23*c8dee2aaSAndroid Build Coastguard Worker fPaint.setColor(SK_ColorRED); 24*c8dee2aaSAndroid Build Coastguard Worker fPaint.setAntiAlias(true); 25*c8dee2aaSAndroid Build Coastguard Worker fPaint.setStyle(SkPaint::kStroke_Style); 26*c8dee2aaSAndroid Build Coastguard Worker } 27*c8dee2aaSAndroid Build Coastguard Worker 28*c8dee2aaSAndroid Build Coastguard Worker protected: onGetName()29*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override { 30*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str(); 31*c8dee2aaSAndroid Build Coastguard Worker } 32*c8dee2aaSAndroid Build Coastguard Worker doDraw(SkCanvas * canvas)33*c8dee2aaSAndroid Build Coastguard Worker void doDraw(SkCanvas* canvas) { 34*c8dee2aaSAndroid Build Coastguard Worker SkISize canvasSize = onGetSize(); 35*c8dee2aaSAndroid Build Coastguard Worker canvas->save(); 36*c8dee2aaSAndroid Build Coastguard Worker canvas->scale(SkIntToScalar(canvasSize.width()), SkIntToScalar(canvasSize.height())); 37*c8dee2aaSAndroid Build Coastguard Worker 38*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(int pics = ) this->sierpinsky(canvas, 0, fPaint); 39*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(pics == this->countPics()); 40*c8dee2aaSAndroid Build Coastguard Worker 41*c8dee2aaSAndroid Build Coastguard Worker canvas->restore(); 42*c8dee2aaSAndroid Build Coastguard Worker } 43*c8dee2aaSAndroid Build Coastguard Worker sierpinsky(SkCanvas * canvas,int lvl,const SkPaint & paint)44*c8dee2aaSAndroid Build Coastguard Worker int sierpinsky(SkCanvas* canvas, int lvl, const SkPaint& paint) { 45*c8dee2aaSAndroid Build Coastguard Worker if (++lvl > fMaxLevel) { 46*c8dee2aaSAndroid Build Coastguard Worker return 0; 47*c8dee2aaSAndroid Build Coastguard Worker } 48*c8dee2aaSAndroid Build Coastguard Worker 49*c8dee2aaSAndroid Build Coastguard Worker int pics = 0; 50*c8dee2aaSAndroid Build Coastguard Worker bool recordPicture = lvl <= fMaxPictureLevel; 51*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder; 52*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* c = canvas; 53*c8dee2aaSAndroid Build Coastguard Worker 54*c8dee2aaSAndroid Build Coastguard Worker if (recordPicture) { 55*c8dee2aaSAndroid Build Coastguard Worker c = recorder.beginRecording(1, 1); 56*c8dee2aaSAndroid Build Coastguard Worker pics++; 57*c8dee2aaSAndroid Build Coastguard Worker } 58*c8dee2aaSAndroid Build Coastguard Worker 59*c8dee2aaSAndroid Build Coastguard Worker c->drawLine(0.5, 0, 0, 1, paint); 60*c8dee2aaSAndroid Build Coastguard Worker c->drawLine(0.5, 0, 1, 1, paint); 61*c8dee2aaSAndroid Build Coastguard Worker c->drawLine(0, 1, 1, 1, paint); 62*c8dee2aaSAndroid Build Coastguard Worker 63*c8dee2aaSAndroid Build Coastguard Worker c->save(); 64*c8dee2aaSAndroid Build Coastguard Worker c->scale(0.5, 0.5); 65*c8dee2aaSAndroid Build Coastguard Worker 66*c8dee2aaSAndroid Build Coastguard Worker c->translate(0, 1); 67*c8dee2aaSAndroid Build Coastguard Worker pics += this->sierpinsky(c, lvl, paint); 68*c8dee2aaSAndroid Build Coastguard Worker 69*c8dee2aaSAndroid Build Coastguard Worker c->translate(1, 0); 70*c8dee2aaSAndroid Build Coastguard Worker pics += this->sierpinsky(c, lvl, paint); 71*c8dee2aaSAndroid Build Coastguard Worker 72*c8dee2aaSAndroid Build Coastguard Worker c->translate(-0.5, -1); 73*c8dee2aaSAndroid Build Coastguard Worker pics += this->sierpinsky(c, lvl, paint); 74*c8dee2aaSAndroid Build Coastguard Worker c->restore(); 75*c8dee2aaSAndroid Build Coastguard Worker 76*c8dee2aaSAndroid Build Coastguard Worker if (recordPicture) { 77*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPicture(recorder.finishRecordingAsPicture()); 78*c8dee2aaSAndroid Build Coastguard Worker } 79*c8dee2aaSAndroid Build Coastguard Worker 80*c8dee2aaSAndroid Build Coastguard Worker return pics; 81*c8dee2aaSAndroid Build Coastguard Worker } 82*c8dee2aaSAndroid Build Coastguard Worker 83*c8dee2aaSAndroid Build Coastguard Worker int fMaxLevel; 84*c8dee2aaSAndroid Build Coastguard Worker int fMaxPictureLevel; 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker private: countPics() const87*c8dee2aaSAndroid Build Coastguard Worker int countPics() const { 88*c8dee2aaSAndroid Build Coastguard Worker // Solve: pics from sierpinsky 89*c8dee2aaSAndroid Build Coastguard Worker // f(m) = 1 + 3*f(m - 1) 90*c8dee2aaSAndroid Build Coastguard Worker // f(0) = 0 91*c8dee2aaSAndroid Build Coastguard Worker // via "recursive function to closed form" tricks 92*c8dee2aaSAndroid Build Coastguard Worker // f(m) = 1/2 (3^m - 1) 93*c8dee2aaSAndroid Build Coastguard Worker int pics = 1; 94*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < fMaxPictureLevel; i++) { 95*c8dee2aaSAndroid Build Coastguard Worker pics *= 3; 96*c8dee2aaSAndroid Build Coastguard Worker } 97*c8dee2aaSAndroid Build Coastguard Worker pics--; 98*c8dee2aaSAndroid Build Coastguard Worker pics /= 2; 99*c8dee2aaSAndroid Build Coastguard Worker return pics; 100*c8dee2aaSAndroid Build Coastguard Worker } 101*c8dee2aaSAndroid Build Coastguard Worker 102*c8dee2aaSAndroid Build Coastguard Worker SkString fName; 103*c8dee2aaSAndroid Build Coastguard Worker SkPaint fPaint; 104*c8dee2aaSAndroid Build Coastguard Worker 105*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark; 106*c8dee2aaSAndroid Build Coastguard Worker }; 107*c8dee2aaSAndroid Build Coastguard Worker 108*c8dee2aaSAndroid Build Coastguard Worker class PictureNestingRecording : public PictureNesting { 109*c8dee2aaSAndroid Build Coastguard Worker public: PictureNestingRecording(int maxLevel,int maxPictureLevel)110*c8dee2aaSAndroid Build Coastguard Worker PictureNestingRecording(int maxLevel, int maxPictureLevel) 111*c8dee2aaSAndroid Build Coastguard Worker : INHERITED("recording", maxLevel, maxPictureLevel) { 112*c8dee2aaSAndroid Build Coastguard Worker } 113*c8dee2aaSAndroid Build Coastguard Worker 114*c8dee2aaSAndroid Build Coastguard Worker protected: isSuitableFor(Backend backend)115*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override { 116*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kNonRendering; 117*c8dee2aaSAndroid Build Coastguard Worker } 118*c8dee2aaSAndroid Build Coastguard Worker onDraw(int loops,SkCanvas *)119*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override { 120*c8dee2aaSAndroid Build Coastguard Worker SkISize canvasSize = onGetSize(); 121*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder; 122*c8dee2aaSAndroid Build Coastguard Worker 123*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; i++) { 124*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.width()), 125*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(canvasSize.height())); 126*c8dee2aaSAndroid Build Coastguard Worker this->doDraw(c); 127*c8dee2aaSAndroid Build Coastguard Worker (void)recorder.finishRecordingAsPicture(); 128*c8dee2aaSAndroid Build Coastguard Worker } 129*c8dee2aaSAndroid Build Coastguard Worker } 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard Worker private: 132*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PictureNesting; 133*c8dee2aaSAndroid Build Coastguard Worker }; 134*c8dee2aaSAndroid Build Coastguard Worker 135*c8dee2aaSAndroid Build Coastguard Worker class PictureNestingPlayback : public PictureNesting { 136*c8dee2aaSAndroid Build Coastguard Worker public: PictureNestingPlayback(int maxLevel,int maxPictureLevel)137*c8dee2aaSAndroid Build Coastguard Worker PictureNestingPlayback(int maxLevel, int maxPictureLevel) 138*c8dee2aaSAndroid Build Coastguard Worker : INHERITED("playback", maxLevel, maxPictureLevel) { 139*c8dee2aaSAndroid Build Coastguard Worker } 140*c8dee2aaSAndroid Build Coastguard Worker protected: onDelayedSetup()141*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override { 142*c8dee2aaSAndroid Build Coastguard Worker this->INHERITED::onDelayedSetup(); 143*c8dee2aaSAndroid Build Coastguard Worker 144*c8dee2aaSAndroid Build Coastguard Worker SkISize canvasSize = onGetSize(); 145*c8dee2aaSAndroid Build Coastguard Worker SkPictureRecorder recorder; 146*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.width()), 147*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(canvasSize.height())); 148*c8dee2aaSAndroid Build Coastguard Worker 149*c8dee2aaSAndroid Build Coastguard Worker this->doDraw(c); 150*c8dee2aaSAndroid Build Coastguard Worker fPicture = recorder.finishRecordingAsPicture(); 151*c8dee2aaSAndroid Build Coastguard Worker } 152*c8dee2aaSAndroid Build Coastguard Worker onDraw(int loops,SkCanvas * canvas)153*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override { 154*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; i++) { 155*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPicture(fPicture); 156*c8dee2aaSAndroid Build Coastguard Worker } 157*c8dee2aaSAndroid Build Coastguard Worker } 158*c8dee2aaSAndroid Build Coastguard Worker 159*c8dee2aaSAndroid Build Coastguard Worker private: 160*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkPicture> fPicture; 161*c8dee2aaSAndroid Build Coastguard Worker 162*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PictureNesting; 163*c8dee2aaSAndroid Build Coastguard Worker }; 164*c8dee2aaSAndroid Build Coastguard Worker 165*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 0); ) 166*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 1); ) 167*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 2); ) 168*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 3); ) 169*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 4); ) 170*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 5); ) 171*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 6); ) 172*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 7); ) 173*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingRecording(8, 8); ) 174*c8dee2aaSAndroid Build Coastguard Worker 175*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 0); ) 176*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 1); ) 177*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 2); ) 178*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 3); ) 179*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 4); ) 180*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 5); ) 181*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 6); ) 182*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 7); ) 183*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PictureNestingPlayback(8, 8); ) 184