blob: 7868f46c9fd60190cb64bb20971dabd91502366f [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
kkinnunenb33402b2014-11-18 04:50:50 -080017#include <math.h>
18
fmalita44162672014-09-15 16:46:16 -070019class PictureNesting : public Benchmark {
20public:
21 PictureNesting(const char* name, int maxLevel, int maxPictureLevel)
22 : fMaxLevel(maxLevel)
23 , fMaxPictureLevel(maxPictureLevel) {
kkinnunenb33402b2014-11-18 04:50:50 -080024 fName.printf("picture_nesting_%s_%d", name, this->countPics());
fmalita44162672014-09-15 16:46:16 -070025 fPaint.setColor(SK_ColorRED);
26 fPaint.setAntiAlias(true);
27 fPaint.setStyle(SkPaint::kStroke_Style);
fmalita44162672014-09-15 16:46:16 -070028 }
29
30protected:
31 virtual const char* onGetName() SK_OVERRIDE {
32 return fName.c_str();
33 }
34
35 void doDraw(SkCanvas* canvas) {
36 SkIPoint canvasSize = onGetSize();
37 canvas->save();
38 canvas->scale(SkIntToScalar(canvasSize.x()), SkIntToScalar(canvasSize.y()));
39
kkinnunenb33402b2014-11-18 04:50:50 -080040 SkDEBUGCODE(int pics = ) this->sierpinsky(canvas, 0, fPaint);
41 SkASSERT(pics == this->countPics());
fmalita44162672014-09-15 16:46:16 -070042
43 canvas->restore();
44 }
45
46 int sierpinsky(SkCanvas* canvas, int lvl, const SkPaint& paint) {
47 if (++lvl > fMaxLevel) {
48 return 0;
49 }
50
51 int pics = 0;
52 bool recordPicture = lvl <= fMaxPictureLevel;
53 SkPictureRecorder recorder;
54 SkCanvas* c = canvas;
55
56 if (recordPicture) {
57 c = recorder.beginRecording(1, 1);
58 pics++;
59 }
60
61 c->drawLine(0.5, 0, 0, 1, paint);
62 c->drawLine(0.5, 0, 1, 1, paint);
63 c->drawLine(0, 1, 1, 1, paint);
64
65 c->save();
66 c->scale(0.5, 0.5);
67
68 c->translate(0, 1);
69 pics += this->sierpinsky(c, lvl, paint);
70
71 c->translate(1, 0);
72 pics += this->sierpinsky(c, lvl, paint);
73
74 c->translate(-0.5, -1);
75 pics += this->sierpinsky(c, lvl, paint);
76 c->restore();
77
78 if (recordPicture) {
79 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
80 canvas->drawPicture(picture);
81 }
82
83 return pics;
84 }
85
86 int fMaxLevel;
87 int fMaxPictureLevel;
88
89private:
kkinnunenb33402b2014-11-18 04:50:50 -080090 int countPics() const {
91 // Solve: pics from sierpinsky
92 // f(m) = 1 + 3*f(m - 1)
93 // f(0) = 0
94 // via "recursive function to closed form" tricks
95 // f(m) = 1/2 (3^m - 1)
96 return static_cast<int>((pow(3.0, fMaxPictureLevel) - 1.0) / 2.0);
97 }
98
fmalita44162672014-09-15 16:46:16 -070099 SkString fName;
100 SkPaint fPaint;
101
102 typedef Benchmark INHERITED;
103};
104
105class PictureNestingRecording : public PictureNesting {
106public:
107 PictureNestingRecording(int maxLevel, int maxPictureLevel)
108 : INHERITED("recording", maxLevel, maxPictureLevel) {
109 }
110
111protected:
mtkleine1daac92014-09-16 10:12:42 -0700112 virtual bool isSuitableFor(Backend backend) {
113 return backend == kNonRendering_Backend;
114 }
115
116 virtual void onDraw(const int loops, SkCanvas*) {
fmalita44162672014-09-15 16:46:16 -0700117 SkIPoint canvasSize = onGetSize();
118 SkPictureRecorder recorder;
119
120 for (int i = 0; i < loops; i++) {
121 SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
122 SkIntToScalar(canvasSize.y()));
123 this->doDraw(c);
124 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
125 }
126 }
127
128private:
129 typedef PictureNesting INHERITED;
130};
131
132class PictureNestingPlayback : public PictureNesting {
133public:
134 PictureNestingPlayback(int maxLevel, int maxPictureLevel)
135 : INHERITED("playback", maxLevel, maxPictureLevel) {
kkinnunenb33402b2014-11-18 04:50:50 -0800136 }
137protected:
138 virtual void onPreDraw() SK_OVERRIDE {
139 this->INHERITED::onPreDraw();
fmalita44162672014-09-15 16:46:16 -0700140
141 SkIPoint canvasSize = onGetSize();
142 SkPictureRecorder recorder;
143 SkCanvas* c = recorder.beginRecording(SkIntToScalar(canvasSize.x()),
144 SkIntToScalar(canvasSize.y()));
145
146 this->doDraw(c);
147 fPicture.reset(recorder.endRecording());
148 }
149
fmalita44162672014-09-15 16:46:16 -0700150 virtual void onDraw(const int loops, SkCanvas* canvas) {
151 for (int i = 0; i < loops; i++) {
152 canvas->drawPicture(fPicture);
153 }
154 }
155
156private:
157 SkAutoTUnref<SkPicture> fPicture;
158
159 typedef PictureNesting INHERITED;
160};
161
162DEF_BENCH( return new PictureNestingRecording(8, 0); )
163DEF_BENCH( return new PictureNestingRecording(8, 1); )
164DEF_BENCH( return new PictureNestingRecording(8, 2); )
165DEF_BENCH( return new PictureNestingRecording(8, 3); )
166DEF_BENCH( return new PictureNestingRecording(8, 4); )
167DEF_BENCH( return new PictureNestingRecording(8, 5); )
168DEF_BENCH( return new PictureNestingRecording(8, 6); )
169DEF_BENCH( return new PictureNestingRecording(8, 7); )
170DEF_BENCH( return new PictureNestingRecording(8, 8); )
171
172DEF_BENCH( return new PictureNestingPlayback(8, 0); )
173DEF_BENCH( return new PictureNestingPlayback(8, 1); )
174DEF_BENCH( return new PictureNestingPlayback(8, 2); )
175DEF_BENCH( return new PictureNestingPlayback(8, 3); )
176DEF_BENCH( return new PictureNestingPlayback(8, 4); )
177DEF_BENCH( return new PictureNestingPlayback(8, 5); )
178DEF_BENCH( return new PictureNestingPlayback(8, 6); )
179DEF_BENCH( return new PictureNestingPlayback(8, 7); )
180DEF_BENCH( return new PictureNestingPlayback(8, 8); )