blob: cbfad3806d1f9ef984e766280ea26ff70aa154fd [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);
bsalomon@google.com9e679352013-05-30 19:52:38 +000023 fIsRendering = false;
djsollen@google.comdde718c2012-05-30 16:50:11 +000024 }
25
26 enum {
djsollen@google.comdde718c2012-05-30 16:50:11 +000027 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*) {
mtklein@google.comc2897432013-09-10 19:23:38 +000036 SkPicture picture;
djsollen@google.comdde718c2012-05-30 16:50:11 +000037
mtklein@google.comc2897432013-09-10 19:23:38 +000038 SkCanvas* pCanvas = picture.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
39 recordCanvas(pCanvas);
djsollen@google.comdde718c2012-05-30 16:50:11 +000040
mtklein@google.comc2897432013-09-10 19:23:38 +000041 // we don't need to draw the picture as the endRecording step will
42 // do the work of transferring the recorded content into a playback
43 // object.
44 picture.endRecording();
djsollen@google.comdde718c2012-05-30 16:50:11 +000045 }
46
47 virtual void recordCanvas(SkCanvas* canvas) = 0;
48
49 SkString fName;
50 SkScalar fPictureWidth;
51 SkScalar fPictureHeight;
52 SkScalar fTextSize;
53private:
54 typedef SkBenchmark INHERITED;
55};
56
57/*
58 * An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
59 * and regions. This bench populates those dictionaries to test the speed of
60 * reading and writing to those particular dictionary data structures.
61 */
62class DictionaryRecordBench : public PictureRecordBench {
63public:
64 DictionaryRecordBench(void* param)
65 : INHERITED(param, "dictionaries") { }
66
djsollen@google.comdde718c2012-05-30 16:50:11 +000067protected:
68 virtual void recordCanvas(SkCanvas* canvas) {
69
mtklein@google.comc2897432013-09-10 19:23:38 +000070 const SkPoint translateDelta = getTranslateDelta(this->getLoops());
djsollen@google.comdde718c2012-05-30 16:50:11 +000071
mtklein@google.comc2897432013-09-10 19:23:38 +000072 for (int i = 0; i < this->getLoops(); i++) {
djsollen@google.comdde718c2012-05-30 16:50:11 +000073
74 SkColor color = SK_ColorYELLOW + (i % 255);
mtklein@google.comc2897432013-09-10 19:23:38 +000075 SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
djsollen@google.comdde718c2012-05-30 16:50:11 +000076
77 canvas->save();
78
79 // set the clip to the given region
80 SkRegion region;
81 region.setRect(rect);
82 canvas->clipRegion(region);
83
84 // fill the clip with a color
85 SkPaint paint;
86 paint.setColor(color);
87 canvas->drawPaint(paint);
88
89 // set a matrix on the canvas
90 SkMatrix matrix;
91 matrix.setRotate(SkIntToScalar(i % 360));
92 canvas->setMatrix(matrix);
93
94 // create a simple bitmap
95 SkBitmap bitmap;
96 bitmap.setConfig(SkBitmap::kRGB_565_Config, 10, 10);
97 bitmap.allocPixels();
98
99 // draw a single color into the bitmap
100 SkCanvas bitmapCanvas(bitmap);
101 bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
102
103 // draw the bitmap onto the canvas
104 canvas->drawBitmapMatrix(bitmap, matrix);
105
106 canvas->restore();
107 canvas->translate(translateDelta.fX, translateDelta.fY);
108 }
109 }
110
mtklein@google.comc2897432013-09-10 19:23:38 +0000111 SkPoint getTranslateDelta(int M) {
djsollen@google.comdde718c2012-05-30 16:50:11 +0000112 SkIPoint canvasSize = onGetSize();
113 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
114 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
115 }
116private:
117 typedef PictureRecordBench INHERITED;
118};
119
junov@chromium.orgef760602012-06-27 20:03:16 +0000120/*
121 * Populates the SkPaint dictionary with a large number of unique paint
122 * objects that differ only by color
123 */
124class UniquePaintDictionaryRecordBench : public PictureRecordBench {
125public:
126 UniquePaintDictionaryRecordBench(void* param)
127 : INHERITED(param, "unique_paint_dictionary") { }
128
junov@chromium.orgef760602012-06-27 20:03:16 +0000129protected:
130 virtual void recordCanvas(SkCanvas* canvas) {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000131 SkRandom rand;
mtklein@google.comc2897432013-09-10 19:23:38 +0000132 for (int i = 0; i < this->getLoops(); i++) {
junov@chromium.orgef760602012-06-27 20:03:16 +0000133 SkPaint paint;
reed@google.com7fe64092012-07-10 13:17:45 +0000134 paint.setColor(rand.nextU());
junov@chromium.orgef760602012-06-27 20:03:16 +0000135 canvas->drawPaint(paint);
136 }
137 }
138
139private:
140 typedef PictureRecordBench INHERITED;
141};
142
143/*
144 * Populates the SkPaint dictionary with a number of unique paint
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000145 * objects that get reused repeatedly.
146 *
147 * Re-creating the paint objects in the inner loop slows the benchmark down 10%.
148 * Using setColor(i % objCount) instead of a random color creates a very high rate
149 * of hash conflicts, slowing us down 12%.
junov@chromium.orgef760602012-06-27 20:03:16 +0000150 */
151class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
152public:
153 RecurringPaintDictionaryRecordBench(void* param)
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000154 : INHERITED(param, "recurring_paint_dictionary") {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000155 SkRandom rand;
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000156 for (int i = 0; i < ObjCount; i++) {
157 fPaint[i].setColor(rand.nextU());
158 }
159 }
junov@chromium.orgef760602012-06-27 20:03:16 +0000160
161 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000162 ObjCount = 100, // number of unique paint objects
junov@chromium.orgef760602012-06-27 20:03:16 +0000163 };
164protected:
165 virtual void recordCanvas(SkCanvas* canvas) {
166
mtklein@google.comc2897432013-09-10 19:23:38 +0000167 for (int i = 0; i < this->getLoops(); i++) {
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000168 canvas->drawPaint(fPaint[i % ObjCount]);
junov@chromium.orgef760602012-06-27 20:03:16 +0000169 }
170 }
171
172private:
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000173 SkPaint fPaint [ObjCount];
junov@chromium.orgef760602012-06-27 20:03:16 +0000174 typedef PictureRecordBench INHERITED;
175};
176
djsollen@google.comdde718c2012-05-30 16:50:11 +0000177///////////////////////////////////////////////////////////////////////////////
178
179static SkBenchmark* Fact0(void* p) { return new DictionaryRecordBench(p); }
junov@chromium.orgef760602012-06-27 20:03:16 +0000180static SkBenchmark* Fact1(void* p) { return new UniquePaintDictionaryRecordBench(p); }
181static SkBenchmark* Fact2(void* p) { return new RecurringPaintDictionaryRecordBench(p); }
djsollen@google.comdde718c2012-05-30 16:50:11 +0000182
183static BenchRegistry gReg0(Fact0);
junov@chromium.orgef760602012-06-27 20:03:16 +0000184static BenchRegistry gReg1(Fact1);
185static BenchRegistry gReg2(Fact2);