blob: abe89368f95e7a76f6bbe1bb1fdc7840b643402b [file] [log] [blame]
fmalita44162672014-09-15 16:46:16 -07001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Benchmark.h"
9#include "SkCanvas.h"
10#include "SkColor.h"
11#include "SkNullCanvas.h"
12#include "SkPaint.h"
13#include "SkPicture.h"
14#include "SkPictureRecorder.h"
15#include "SkString.h"
16
17class PictureNesting : public Benchmark {
18public:
19 PictureNesting(const char* name, int maxLevel, int maxPictureLevel)
20 : fMaxLevel(maxLevel)
21 , fMaxPictureLevel(maxPictureLevel) {
kkinnunenb33402b2014-11-18 04:50:50 -080022 fName.printf("picture_nesting_%s_%d", name, this->countPics());
fmalita44162672014-09-15 16:46:16 -070023 fPaint.setColor(SK_ColorRED);
24 fPaint.setAntiAlias(true);
25 fPaint.setStyle(SkPaint::kStroke_Style);
fmalita44162672014-09-15 16:46:16 -070026 }
27
28protected:
mtklein36352bf2015-03-25 18:17:31 -070029 const char* onGetName() override {
fmalita44162672014-09-15 16:46:16 -070030 return fName.c_str();
31 }
32
33 void doDraw(SkCanvas* canvas) {
34 SkIPoint canvasSize = onGetSize();
35 canvas->save();
36 canvas->scale(SkIntToScalar(canvasSize.x()), SkIntToScalar(canvasSize.y()));
37
kkinnunenb33402b2014-11-18 04:50:50 -080038 SkDEBUGCODE(int pics = ) this->sierpinsky(canvas, 0, fPaint);
39 SkASSERT(pics == this->countPics());
fmalita44162672014-09-15 16:46:16 -070040
41 canvas->restore();
42 }
43
44 int sierpinsky(SkCanvas* canvas, int lvl, const SkPaint& paint) {
45 if (++lvl > fMaxLevel) {
46 return 0;
47 }
48
49 int pics = 0;
50 bool recordPicture = lvl <= fMaxPictureLevel;
51 SkPictureRecorder recorder;
52 SkCanvas* c = canvas;
53
54 if (recordPicture) {
55 c = recorder.beginRecording(1, 1);
56 pics++;
57 }
58
59 c->drawLine(0.5, 0, 0, 1, paint);
60 c->drawLine(0.5, 0, 1, 1, paint);
61 c->drawLine(0, 1, 1, 1, paint);
62
63 c->save();
64 c->scale(0.5, 0.5);
65
66 c->translate(0, 1);
67 pics += this->sierpinsky(c, lvl, paint);
68
69 c->translate(1, 0);
70 pics += this->sierpinsky(c, lvl, paint);
71
72 c->translate(-0.5, -1);
73 pics += this->sierpinsky(c, lvl, paint);
74 c->restore();
75
76 if (recordPicture) {
reedca2622b2016-03-18 07:25:55 -070077 canvas->drawPicture(recorder.finishRecordingAsPicture());
fmalita44162672014-09-15 16:46:16 -070078 }
79
80 return pics;
81 }
82
83 int fMaxLevel;
84 int fMaxPictureLevel;
85
86private:
kkinnunenb33402b2014-11-18 04:50:50 -080087 int countPics() const {
88 // Solve: pics from sierpinsky
89 // f(m) = 1 + 3*f(m - 1)
90 // f(0) = 0
91 // via "recursive function to closed form" tricks
92 // f(m) = 1/2 (3^m - 1)
mtkleind0256a22015-01-09 08:33:36 -080093 int pics = 1;
94 for (int i = 0; i < fMaxPictureLevel; i++) {
95 pics *= 3;
96 }
97 pics--;
98 pics /= 2;
99 return pics;
kkinnunenb33402b2014-11-18 04:50:50 -0800100 }
101
fmalita44162672014-09-15 16:46:16 -0700102 SkString fName;
103 SkPaint fPaint;
104
105 typedef Benchmark INHERITED;
106};
107
108class PictureNestingRecording : public PictureNesting {
109public:
110 PictureNestingRecording(int maxLevel, int maxPictureLevel)
111 : INHERITED("recording", maxLevel, maxPictureLevel) {
112 }
113
114protected:
mtkleinf0599002015-07-13 06:18:39 -0700115 bool isSuitableFor(Backend backend) override {
mtkleine1daac92014-09-16 10:12:42 -0700116 return backend == kNonRendering_Backend;
117 }
118
mtkleina1ebeb22015-10-01 09:43:39 -0700119 void onDraw(int loops, SkCanvas*) override {
fmalita44162672014-09-15 16:46:16 -0700120 SkIPoint canvasSize = onGetSize();
121 SkPictureRecorder recorder;
122
123 for (int i = 0; i < loops; i++) {
124 SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
125 SkIntToScalar(canvasSize.y()));
126 this->doDraw(c);
reedca2622b2016-03-18 07:25:55 -0700127 (void)recorder.finishRecordingAsPicture();
fmalita44162672014-09-15 16:46:16 -0700128 }
129 }
130
131private:
132 typedef PictureNesting INHERITED;
133};
134
135class PictureNestingPlayback : public PictureNesting {
136public:
137 PictureNestingPlayback(int maxLevel, int maxPictureLevel)
138 : INHERITED("playback", maxLevel, maxPictureLevel) {
kkinnunenb33402b2014-11-18 04:50:50 -0800139 }
140protected:
joshualitt8a6697a2015-09-30 12:11:07 -0700141 void onDelayedSetup() override {
142 this->INHERITED::onDelayedSetup();
fmalita44162672014-09-15 16:46:16 -0700143
144 SkIPoint canvasSize = onGetSize();
145 SkPictureRecorder recorder;
146 SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
147 SkIntToScalar(canvasSize.y()));
148
149 this->doDraw(c);
reedca2622b2016-03-18 07:25:55 -0700150 fPicture = recorder.finishRecordingAsPicture();
fmalita44162672014-09-15 16:46:16 -0700151 }
152
mtkleina1ebeb22015-10-01 09:43:39 -0700153 void onDraw(int loops, SkCanvas* canvas) override {
fmalita44162672014-09-15 16:46:16 -0700154 for (int i = 0; i < loops; i++) {
155 canvas->drawPicture(fPicture);
156 }
157 }
158
159private:
reedca2622b2016-03-18 07:25:55 -0700160 sk_sp<SkPicture> fPicture;
fmalita44162672014-09-15 16:46:16 -0700161
162 typedef PictureNesting INHERITED;
163};
164
165DEF_BENCH( return new PictureNestingRecording(8, 0); )
166DEF_BENCH( return new PictureNestingRecording(8, 1); )
167DEF_BENCH( return new PictureNestingRecording(8, 2); )
168DEF_BENCH( return new PictureNestingRecording(8, 3); )
169DEF_BENCH( return new PictureNestingRecording(8, 4); )
170DEF_BENCH( return new PictureNestingRecording(8, 5); )
171DEF_BENCH( return new PictureNestingRecording(8, 6); )
172DEF_BENCH( return new PictureNestingRecording(8, 7); )
173DEF_BENCH( return new PictureNestingRecording(8, 8); )
174
175DEF_BENCH( return new PictureNestingPlayback(8, 0); )
176DEF_BENCH( return new PictureNestingPlayback(8, 1); )
177DEF_BENCH( return new PictureNestingPlayback(8, 2); )
178DEF_BENCH( return new PictureNestingPlayback(8, 3); )
179DEF_BENCH( return new PictureNestingPlayback(8, 4); )
180DEF_BENCH( return new PictureNestingPlayback(8, 5); )
181DEF_BENCH( return new PictureNestingPlayback(8, 6); )
182DEF_BENCH( return new PictureNestingPlayback(8, 7); )
183DEF_BENCH( return new PictureNestingPlayback(8, 8); )