blob: c057f6442c564a391e9392f78d49d6708807929c [file] [log] [blame]
djsollen@google.comdde718c2012-05-30 16:50:11 +00001/*
2 * Copyright 2012 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#include "SkBenchmark.h"
8#include "SkCanvas.h"
9#include "SkColor.h"
10#include "SkPaint.h"
11#include "SkPicture.h"
12#include "SkPoint.h"
reed@google.com7fe64092012-07-10 13:17:45 +000013#include "SkRandom.h"
djsollen@google.comdde718c2012-05-30 16:50:11 +000014#include "SkRect.h"
15#include "SkString.h"
16
17class PictureRecordBench : public SkBenchmark {
18public:
19 PictureRecordBench(void* param, const char name[]) : INHERITED(param) {
20 fName.printf("picture_record_%s", name);
21 fPictureWidth = SkIntToScalar(PICTURE_WIDTH);
22 fPictureHeight = SkIntToScalar(PICTURE_HEIGHT);
23 }
24
25 enum {
26 N = SkBENCHLOOP(25), // number of times to create the picture
27 PICTURE_WIDTH = 1000,
28 PICTURE_HEIGHT = 4000,
29 };
30protected:
31 virtual const char* onGetName() {
32 return fName.c_str();
33 }
34
sugoi@google.com77472f02013-03-05 18:50:01 +000035 virtual void onDraw(SkCanvas*) {
reed@google.comf1d46952012-07-03 13:53:41 +000036 int n = (int)(N * this->innerLoopScale());
37 n = SkMax32(1, n);
djsollen@google.comdde718c2012-05-30 16:50:11 +000038
reed@google.comf1d46952012-07-03 13:53:41 +000039 for (int i = 0; i < n; i++) {
djsollen@google.comdde718c2012-05-30 16:50:11 +000040
41 SkPicture picture;
42
43 SkCanvas* pCanvas = picture.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
44 recordCanvas(pCanvas);
45
46 // we don't need to draw the picture as the endRecording step will
47 // do the work of transferring the recorded content into a playback
48 // object.
49 picture.endRecording();
50 }
51 }
52
53 virtual void recordCanvas(SkCanvas* canvas) = 0;
reed@google.comf1d46952012-07-03 13:53:41 +000054 virtual float innerLoopScale() const { return 1; }
djsollen@google.comdde718c2012-05-30 16:50:11 +000055
56 SkString fName;
57 SkScalar fPictureWidth;
58 SkScalar fPictureHeight;
59 SkScalar fTextSize;
60private:
61 typedef SkBenchmark INHERITED;
62};
63
64/*
65 * An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
66 * and regions. This bench populates those dictionaries to test the speed of
67 * reading and writing to those particular dictionary data structures.
68 */
69class DictionaryRecordBench : public PictureRecordBench {
70public:
71 DictionaryRecordBench(void* param)
72 : INHERITED(param, "dictionaries") { }
73
74 enum {
75 M = SkBENCHLOOP(100), // number of elements in each dictionary
76 };
77protected:
78 virtual void recordCanvas(SkCanvas* canvas) {
79
80 const SkPoint translateDelta = getTranslateDelta();
81
82 for (int i = 0; i < M; i++) {
83
84 SkColor color = SK_ColorYELLOW + (i % 255);
85 SkIRect rect = SkIRect::MakeWH(i,i);
86
87 canvas->save();
88
89 // set the clip to the given region
90 SkRegion region;
91 region.setRect(rect);
92 canvas->clipRegion(region);
93
94 // fill the clip with a color
95 SkPaint paint;
96 paint.setColor(color);
97 canvas->drawPaint(paint);
98
99 // set a matrix on the canvas
100 SkMatrix matrix;
101 matrix.setRotate(SkIntToScalar(i % 360));
102 canvas->setMatrix(matrix);
103
104 // create a simple bitmap
105 SkBitmap bitmap;
106 bitmap.setConfig(SkBitmap::kRGB_565_Config, 10, 10);
107 bitmap.allocPixels();
108
109 // draw a single color into the bitmap
110 SkCanvas bitmapCanvas(bitmap);
111 bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
112
113 // draw the bitmap onto the canvas
114 canvas->drawBitmapMatrix(bitmap, matrix);
115
116 canvas->restore();
117 canvas->translate(translateDelta.fX, translateDelta.fY);
118 }
119 }
120
121 SkPoint getTranslateDelta() {
122 SkIPoint canvasSize = onGetSize();
123 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
124 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
125 }
126private:
127 typedef PictureRecordBench INHERITED;
128};
129
junov@chromium.orgef760602012-06-27 20:03:16 +0000130/*
131 * Populates the SkPaint dictionary with a large number of unique paint
132 * objects that differ only by color
133 */
134class UniquePaintDictionaryRecordBench : public PictureRecordBench {
135public:
136 UniquePaintDictionaryRecordBench(void* param)
137 : INHERITED(param, "unique_paint_dictionary") { }
138
139 enum {
140 M = SkBENCHLOOP(15000), // number of unique paint objects
141 };
142protected:
reed@google.comf1d46952012-07-03 13:53:41 +0000143 virtual float innerLoopScale() const SK_OVERRIDE { return 0.1f; }
junov@chromium.orgef760602012-06-27 20:03:16 +0000144 virtual void recordCanvas(SkCanvas* canvas) {
reed@google.com7fe64092012-07-10 13:17:45 +0000145 SkRandom rand;
junov@chromium.orgef760602012-06-27 20:03:16 +0000146 for (int i = 0; i < M; i++) {
147 SkPaint paint;
reed@google.com7fe64092012-07-10 13:17:45 +0000148 paint.setColor(rand.nextU());
junov@chromium.orgef760602012-06-27 20:03:16 +0000149 canvas->drawPaint(paint);
150 }
151 }
152
153private:
154 typedef PictureRecordBench INHERITED;
155};
156
157/*
158 * Populates the SkPaint dictionary with a number of unique paint
159 * objects that get reused repeatedly
160 */
161class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
162public:
163 RecurringPaintDictionaryRecordBench(void* param)
164 : INHERITED(param, "recurring_paint_dictionary") { }
165
166 enum {
167 ObjCount = 100, // number of unique paint objects
168 M = SkBENCHLOOP(50000), // number of draw iterations
169 };
170protected:
reed@google.comf1d46952012-07-03 13:53:41 +0000171 virtual float innerLoopScale() const SK_OVERRIDE { return 0.1f; }
junov@chromium.orgef760602012-06-27 20:03:16 +0000172 virtual void recordCanvas(SkCanvas* canvas) {
173
174 for (int i = 0; i < M; i++) {
175 SkPaint paint;
176 paint.setColor(i % ObjCount);
177 canvas->drawPaint(paint);
178 }
179 }
180
181private:
182 typedef PictureRecordBench INHERITED;
183};
184
djsollen@google.comdde718c2012-05-30 16:50:11 +0000185///////////////////////////////////////////////////////////////////////////////
186
187static SkBenchmark* Fact0(void* p) { return new DictionaryRecordBench(p); }
junov@chromium.orgef760602012-06-27 20:03:16 +0000188static SkBenchmark* Fact1(void* p) { return new UniquePaintDictionaryRecordBench(p); }
189static SkBenchmark* Fact2(void* p) { return new RecurringPaintDictionaryRecordBench(p); }
djsollen@google.comdde718c2012-05-30 16:50:11 +0000190
191static BenchRegistry gReg0(Fact0);
junov@chromium.orgef760602012-06-27 20:03:16 +0000192static BenchRegistry gReg1(Fact1);
193static BenchRegistry gReg2(Fact2);