blob: 2b2b6ad1fe2ab043cf03d1553b3cf8dd0a352054 [file] [log] [blame]
djsollen@google.com809a2a92012-02-23 20:57:09 +00001/*
2 * Copyright 2011 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 */
tfarinaf168b862014-06-19 12:32:29 -07007#include "Benchmark.h"
djsollen@google.com809a2a92012-02-23 20:57:09 +00008#include "SkCanvas.h"
9#include "SkColor.h"
10#include "SkPaint.h"
11#include "SkPicture.h"
robertphillips@google.com770963f2014-04-18 18:04:41 +000012#include "SkPictureRecorder.h"
djsollen@google.com809a2a92012-02-23 20:57:09 +000013#include "SkPoint.h"
mtkleinbf5dd412014-11-11 10:39:27 -080014#include "SkRandom.h"
djsollen@google.com809a2a92012-02-23 20:57:09 +000015#include "SkRect.h"
16#include "SkString.h"
17
18// This is designed to emulate about 4 screens of textual content
19
20
tfarinaf168b862014-06-19 12:32:29 -070021class PicturePlaybackBench : public Benchmark {
djsollen@google.com809a2a92012-02-23 20:57:09 +000022public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000023 PicturePlaybackBench(const char name[]) {
djsollen@google.com809a2a92012-02-23 20:57:09 +000024 fName.printf("picture_playback_%s", name);
25 fPictureWidth = SkIntToScalar(PICTURE_WIDTH);
26 fPictureHeight = SkIntToScalar(PICTURE_HEIGHT);
27 fTextSize = SkIntToScalar(TEXT_SIZE);
28 }
29
30 enum {
djsollen@google.com809a2a92012-02-23 20:57:09 +000031 PICTURE_WIDTH = 1000,
32 PICTURE_HEIGHT = 4000,
33 TEXT_SIZE = 10
34 };
35protected:
36 virtual const char* onGetName() {
37 return fName.c_str();
38 }
39
mtkleina1ebeb22015-10-01 09:43:39 -070040 virtual void onDraw(int loops, SkCanvas* canvas) {
djsollen@google.com809a2a92012-02-23 20:57:09 +000041
robertphillips@google.com84b18c72014-04-13 19:09:42 +000042 SkPictureRecorder recorder;
halcanary96fcdcc2015-08-27 07:41:13 -070043 SkCanvas* pCanvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, nullptr, 0);
robertphillips@google.com84b18c72014-04-13 19:09:42 +000044 this->recordCanvas(pCanvas);
reedca2622b2016-03-18 07:25:55 -070045 sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
djsollen@google.com809a2a92012-02-23 20:57:09 +000046
commit-bot@chromium.org33614712013-12-03 18:17:16 +000047 const SkPoint translateDelta = getTranslateDelta(loops);
djsollen@google.com809a2a92012-02-23 20:57:09 +000048
commit-bot@chromium.org33614712013-12-03 18:17:16 +000049 for (int i = 0; i < loops; i++) {
robertphillipsc5ba71d2014-09-04 08:42:50 -070050 picture->playback(canvas);
djsollen@google.com809a2a92012-02-23 20:57:09 +000051 canvas->translate(translateDelta.fX, translateDelta.fY);
52 }
53 }
54
55 virtual void recordCanvas(SkCanvas* canvas) = 0;
mtklein@google.comc2897432013-09-10 19:23:38 +000056 virtual SkPoint getTranslateDelta(int N) {
djsollen@google.com809a2a92012-02-23 20:57:09 +000057 SkIPoint canvasSize = onGetSize();
58 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/N),
59 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/N));
60 }
61
62 SkString fName;
63 SkScalar fPictureWidth;
64 SkScalar fPictureHeight;
65 SkScalar fTextSize;
66private:
tfarinaf168b862014-06-19 12:32:29 -070067 typedef Benchmark INHERITED;
djsollen@google.com809a2a92012-02-23 20:57:09 +000068};
69
70
71class TextPlaybackBench : public PicturePlaybackBench {
72public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000073 TextPlaybackBench() : INHERITED("drawText") { }
djsollen@google.com809a2a92012-02-23 20:57:09 +000074protected:
mtklein36352bf2015-03-25 18:17:31 -070075 void recordCanvas(SkCanvas* canvas) override {
djsollen@google.com809a2a92012-02-23 20:57:09 +000076 SkPaint paint;
77 paint.setTextSize(fTextSize);
78 paint.setColor(SK_ColorBLACK);
79
80 const char* text = "Hamburgefons";
81 size_t len = strlen(text);
82 const SkScalar textWidth = paint.measureText(text, len);
83
84 for (SkScalar x = 0; x < fPictureWidth; x += textWidth) {
85 for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) {
86 canvas->drawText(text, len, x, y, paint);
87 }
88 }
89 }
90private:
91 typedef PicturePlaybackBench INHERITED;
92};
93
94class PosTextPlaybackBench : public PicturePlaybackBench {
95public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000096 PosTextPlaybackBench(bool drawPosH)
97 : INHERITED(drawPosH ? "drawPosTextH" : "drawPosText")
djsollen@google.com710c2692012-02-27 16:22:48 +000098 , fDrawPosH(drawPosH) { }
djsollen@google.com809a2a92012-02-23 20:57:09 +000099protected:
mtklein36352bf2015-03-25 18:17:31 -0700100 void recordCanvas(SkCanvas* canvas) override {
djsollen@google.com809a2a92012-02-23 20:57:09 +0000101 SkPaint paint;
102 paint.setTextSize(fTextSize);
103 paint.setColor(SK_ColorBLACK);
104
105 const char* text = "Hamburgefons";
106 size_t len = strlen(text);
107 const SkScalar textWidth = paint.measureText(text, len);
108
109 SkScalar* adv = new SkScalar[len];
110 paint.getTextWidths(text, len, adv);
111
112 for (SkScalar x = 0; x < fPictureWidth; x += textWidth) {
113 for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) {
114
115 SkPoint* pos = new SkPoint[len];
116 SkScalar advX = 0;
117
118 for (size_t i = 0; i < len; i++) {
119 if (fDrawPosH)
120 pos[i].set(x + advX, y);
121 else
borenet@google.comb7961192012-08-20 18:58:26 +0000122 pos[i].set(x + advX, y + i);
djsollen@google.com809a2a92012-02-23 20:57:09 +0000123 advX += adv[i];
124 }
125
126 canvas->drawPosText(text, len, pos, paint);
127 delete[] pos;
128 }
129 }
130 delete[] adv;
131 }
132private:
133 bool fDrawPosH;
134 typedef PicturePlaybackBench INHERITED;
135};
136
137
138///////////////////////////////////////////////////////////////////////////////
139
mtklein@google.com410e6e82013-09-13 19:52:27 +0000140DEF_BENCH( return new TextPlaybackBench(); )
141DEF_BENCH( return new PosTextPlaybackBench(true); )
142DEF_BENCH( return new PosTextPlaybackBench(false); )
mtkleinbf5dd412014-11-11 10:39:27 -0800143
144// Chrome draws into small tiles with impl-side painting.
145// This benchmark measures the relative performance of our bounding-box hierarchies,
146// both when querying tiles perfectly and when not.
mtklein703dd2e2015-01-09 06:41:48 -0800147enum BBH { kNone, kRTree };
mtkleinbf5dd412014-11-11 10:39:27 -0800148enum Mode { kTiled, kRandom };
149class TiledPlaybackBench : public Benchmark {
150public:
151 TiledPlaybackBench(BBH bbh, Mode mode) : fBBH(bbh), fMode(mode), fName("tiled_playback") {
152 switch (fBBH) {
153 case kNone: fName.append("_none" ); break;
154 case kRTree: fName.append("_rtree" ); break;
mtkleinbf5dd412014-11-11 10:39:27 -0800155 }
156 switch (fMode) {
157 case kTiled: fName.append("_tiled" ); break;
158 case kRandom: fName.append("_random"); break;
159 }
160 }
161
mtklein36352bf2015-03-25 18:17:31 -0700162 const char* onGetName() override { return fName.c_str(); }
163 SkIPoint onGetSize() override { return SkIPoint::Make(1024,1024); }
mtkleinbf5dd412014-11-11 10:39:27 -0800164
joshualitt8a6697a2015-09-30 12:11:07 -0700165 void onDelayedSetup() override {
mtkleinbf5dd412014-11-11 10:39:27 -0800166 SkAutoTDelete<SkBBHFactory> factory;
167 switch (fBBH) {
168 case kNone: break;
169 case kRTree: factory.reset(new SkRTreeFactory); break;
mtkleinbf5dd412014-11-11 10:39:27 -0800170 }
171
172 SkPictureRecorder recorder;
173 SkCanvas* canvas = recorder.beginRecording(1024, 1024, factory);
174 SkRandom rand;
175 for (int i = 0; i < 10000; i++) {
176 SkScalar x = rand.nextRangeScalar(0, 1024),
177 y = rand.nextRangeScalar(0, 1024),
178 w = rand.nextRangeScalar(0, 128),
179 h = rand.nextRangeScalar(0, 128);
180 SkPaint paint;
181 paint.setColor(rand.nextU());
182 paint.setAlpha(0xFF);
183 canvas->drawRect(SkRect::MakeXYWH(x,y,w,h), paint);
184 }
reedca2622b2016-03-18 07:25:55 -0700185 fPic = recorder.finishRecordingAsPicture();
mtkleinbf5dd412014-11-11 10:39:27 -0800186 }
187
mtkleina1ebeb22015-10-01 09:43:39 -0700188 void onDraw(int loops, SkCanvas* canvas) override {
mtkleinbf5dd412014-11-11 10:39:27 -0800189 for (int i = 0; i < loops; i++) {
190 // This inner loop guarantees we make the same choices for all bench variants.
191 SkRandom rand;
192 for (int j = 0; j < 10; j++) {
193 SkScalar x = 0, y = 0;
194 switch (fMode) {
195 case kTiled: x = SkScalar(256 * rand.nextULessThan(4));
196 y = SkScalar(256 * rand.nextULessThan(4));
197 break;
198 case kRandom: x = rand.nextRangeScalar(0, 768);
199 y = rand.nextRangeScalar(0, 768);
200 break;
201 }
202 SkAutoCanvasRestore ar(canvas, true/*save now*/);
203 canvas->clipRect(SkRect::MakeXYWH(x,y,256,256));
204 fPic->playback(canvas);
205 }
206 }
207 }
208
209private:
reedca2622b2016-03-18 07:25:55 -0700210 BBH fBBH;
211 Mode fMode;
212 SkString fName;
213 sk_sp<SkPicture> fPic;
mtkleinbf5dd412014-11-11 10:39:27 -0800214};
215
216DEF_BENCH( return new TiledPlaybackBench(kNone, kRandom); )
217DEF_BENCH( return new TiledPlaybackBench(kNone, kTiled ); )
218DEF_BENCH( return new TiledPlaybackBench(kRTree, kRandom); )
219DEF_BENCH( return new TiledPlaybackBench(kRTree, kTiled ); )