blob: a968d51db55511223964d320b0798c9a9b615d47 [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) {
77 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
78 canvas->drawPicture(picture);
79 }
80
81 return pics;
82 }
83
84 int fMaxLevel;
85 int fMaxPictureLevel;
86
87private:
kkinnunenb33402b2014-11-18 04:50:50 -080088 int countPics() const {
89 // Solve: pics from sierpinsky
90 // f(m) = 1 + 3*f(m - 1)
91 // f(0) = 0
92 // via "recursive function to closed form" tricks
93 // f(m) = 1/2 (3^m - 1)
mtkleind0256a22015-01-09 08:33:36 -080094 int pics = 1;
95 for (int i = 0; i < fMaxPictureLevel; i++) {
96 pics *= 3;
97 }
98 pics--;
99 pics /= 2;
100 return pics;
kkinnunenb33402b2014-11-18 04:50:50 -0800101 }
102
fmalita44162672014-09-15 16:46:16 -0700103 SkString fName;
104 SkPaint fPaint;
105
106 typedef Benchmark INHERITED;
107};
108
109class PictureNestingRecording : public PictureNesting {
110public:
111 PictureNestingRecording(int maxLevel, int maxPictureLevel)
112 : INHERITED("recording", maxLevel, maxPictureLevel) {
113 }
114
115protected:
mtkleinf0599002015-07-13 06:18:39 -0700116 bool isSuitableFor(Backend backend) override {
mtkleine1daac92014-09-16 10:12:42 -0700117 return backend == kNonRendering_Backend;
118 }
119
mtkleina1ebeb22015-10-01 09:43:39 -0700120 void onDraw(int loops, SkCanvas*) override {
fmalita44162672014-09-15 16:46:16 -0700121 SkIPoint canvasSize = onGetSize();
122 SkPictureRecorder recorder;
123
124 for (int i = 0; i < loops; i++) {
125 SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
126 SkIntToScalar(canvasSize.y()));
127 this->doDraw(c);
128 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
129 }
130 }
131
132private:
133 typedef PictureNesting INHERITED;
134};
135
136class PictureNestingPlayback : public PictureNesting {
137public:
138 PictureNestingPlayback(int maxLevel, int maxPictureLevel)
139 : INHERITED("playback", maxLevel, maxPictureLevel) {
kkinnunenb33402b2014-11-18 04:50:50 -0800140 }
141protected:
joshualitt8a6697a2015-09-30 12:11:07 -0700142 void onDelayedSetup() override {
143 this->INHERITED::onDelayedSetup();
fmalita44162672014-09-15 16:46:16 -0700144
145 SkIPoint canvasSize = onGetSize();
146 SkPictureRecorder recorder;
147 SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
148 SkIntToScalar(canvasSize.y()));
149
150 this->doDraw(c);
151 fPicture.reset(recorder.endRecording());
152 }
153
mtkleina1ebeb22015-10-01 09:43:39 -0700154 void onDraw(int loops, SkCanvas* canvas) override {
fmalita44162672014-09-15 16:46:16 -0700155 for (int i = 0; i < loops; i++) {
156 canvas->drawPicture(fPicture);
157 }
158 }
159
160private:
161 SkAutoTUnref<SkPicture> fPicture;
162
163 typedef PictureNesting INHERITED;
164};
165
166DEF_BENCH( return new PictureNestingRecording(8, 0); )
167DEF_BENCH( return new PictureNestingRecording(8, 1); )
168DEF_BENCH( return new PictureNestingRecording(8, 2); )
169DEF_BENCH( return new PictureNestingRecording(8, 3); )
170DEF_BENCH( return new PictureNestingRecording(8, 4); )
171DEF_BENCH( return new PictureNestingRecording(8, 5); )
172DEF_BENCH( return new PictureNestingRecording(8, 6); )
173DEF_BENCH( return new PictureNestingRecording(8, 7); )
174DEF_BENCH( return new PictureNestingRecording(8, 8); )
175
176DEF_BENCH( return new PictureNestingPlayback(8, 0); )
177DEF_BENCH( return new PictureNestingPlayback(8, 1); )
178DEF_BENCH( return new PictureNestingPlayback(8, 2); )
179DEF_BENCH( return new PictureNestingPlayback(8, 3); )
180DEF_BENCH( return new PictureNestingPlayback(8, 4); )
181DEF_BENCH( return new PictureNestingPlayback(8, 5); )
182DEF_BENCH( return new PictureNestingPlayback(8, 6); )
183DEF_BENCH( return new PictureNestingPlayback(8, 7); )
184DEF_BENCH( return new PictureNestingPlayback(8, 8); )