blob: 4083f81af71ff5a9b648da094e3b8ac0d4fb7649 [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:
mtklein@google.com410e6e82013-09-13 19:52:27 +000019 PictureRecordBench(const char name[]) {
djsollen@google.comdde718c2012-05-30 16:50:11 +000020 fName.printf("picture_record_%s", name);
commit-bot@chromium.org644629c2013-11-21 06:21:58 +000021 }
22
23 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
24 return backend == kNonRendering_Backend;
djsollen@google.comdde718c2012-05-30 16:50:11 +000025 }
26
27 enum {
djsollen@google.comdde718c2012-05-30 16:50:11 +000028 PICTURE_WIDTH = 1000,
29 PICTURE_HEIGHT = 4000,
30 };
31protected:
mtklein@google.com93d2f552013-09-17 18:58:53 +000032 virtual const char* onGetName() SK_OVERRIDE {
djsollen@google.comdde718c2012-05-30 16:50:11 +000033 return fName.c_str();
34 }
djsollen@google.comdde718c2012-05-30 16:50:11 +000035private:
mtklein@google.com93d2f552013-09-17 18:58:53 +000036 SkString fName;
djsollen@google.comdde718c2012-05-30 16:50:11 +000037 typedef SkBenchmark INHERITED;
38};
39
mtklein@google.com93d2f552013-09-17 18:58:53 +000040
41static const int kMaxLoopsPerCanvas = 10000;
42
djsollen@google.comdde718c2012-05-30 16:50:11 +000043/*
44 * An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
45 * and regions. This bench populates those dictionaries to test the speed of
46 * reading and writing to those particular dictionary data structures.
47 */
48class DictionaryRecordBench : public PictureRecordBench {
49public:
mtklein@google.com93d2f552013-09-17 18:58:53 +000050 DictionaryRecordBench() : INHERITED("dictionaries") {}
djsollen@google.comdde718c2012-05-30 16:50:11 +000051
djsollen@google.comdde718c2012-05-30 16:50:11 +000052protected:
commit-bot@chromium.org33614712013-12-03 18:17:16 +000053 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
mtklein@google.com93d2f552013-09-17 18:58:53 +000054 SkAutoTDelete<SkPicture> picture;
55 SkCanvas* canvas = NULL;
djsollen@google.comdde718c2012-05-30 16:50:11 +000056
commit-bot@chromium.org33614712013-12-03 18:17:16 +000057 const SkPoint translateDelta = getTranslateDelta(loops);
djsollen@google.comdde718c2012-05-30 16:50:11 +000058
commit-bot@chromium.org33614712013-12-03 18:17:16 +000059 for (int i = 0; i < loops; i++) {
mtklein@google.com93d2f552013-09-17 18:58:53 +000060 if (0 == i % kMaxLoopsPerCanvas) {
61 picture.reset(SkNEW(SkPicture));
62 canvas = picture->beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
63 }
djsollen@google.comdde718c2012-05-30 16:50:11 +000064
65 SkColor color = SK_ColorYELLOW + (i % 255);
mtklein@google.comc2897432013-09-10 19:23:38 +000066 SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
djsollen@google.comdde718c2012-05-30 16:50:11 +000067
68 canvas->save();
69
70 // set the clip to the given region
71 SkRegion region;
72 region.setRect(rect);
73 canvas->clipRegion(region);
74
75 // fill the clip with a color
76 SkPaint paint;
77 paint.setColor(color);
78 canvas->drawPaint(paint);
79
80 // set a matrix on the canvas
81 SkMatrix matrix;
82 matrix.setRotate(SkIntToScalar(i % 360));
83 canvas->setMatrix(matrix);
84
85 // create a simple bitmap
86 SkBitmap bitmap;
87 bitmap.setConfig(SkBitmap::kRGB_565_Config, 10, 10);
88 bitmap.allocPixels();
89
90 // draw a single color into the bitmap
91 SkCanvas bitmapCanvas(bitmap);
92 bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
93
94 // draw the bitmap onto the canvas
95 canvas->drawBitmapMatrix(bitmap, matrix);
96
97 canvas->restore();
98 canvas->translate(translateDelta.fX, translateDelta.fY);
99 }
100 }
101
mtklein@google.comc2897432013-09-10 19:23:38 +0000102 SkPoint getTranslateDelta(int M) {
djsollen@google.comdde718c2012-05-30 16:50:11 +0000103 SkIPoint canvasSize = onGetSize();
104 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
105 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
106 }
107private:
108 typedef PictureRecordBench INHERITED;
109};
110
junov@chromium.orgef760602012-06-27 20:03:16 +0000111/*
112 * Populates the SkPaint dictionary with a large number of unique paint
113 * objects that differ only by color
114 */
115class UniquePaintDictionaryRecordBench : public PictureRecordBench {
116public:
mtklein@google.com93d2f552013-09-17 18:58:53 +0000117 UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }
junov@chromium.orgef760602012-06-27 20:03:16 +0000118
junov@chromium.orgef760602012-06-27 20:03:16 +0000119protected:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000120 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000121 SkRandom rand;
mtklein@google.com5e5239e2013-09-17 17:14:25 +0000122 SkPaint paint;
123 SkAutoTDelete<SkPicture> picture;
124 SkCanvas* canvas = NULL;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000125 for (int i = 0; i < loops; i++) {
mtklein@google.com93d2f552013-09-17 18:58:53 +0000126 if (0 == i % kMaxLoopsPerCanvas) {
mtklein@google.com5e5239e2013-09-17 17:14:25 +0000127 picture.reset(SkNEW(SkPicture));
128 canvas = picture->beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
129 }
reed@google.com7fe64092012-07-10 13:17:45 +0000130 paint.setColor(rand.nextU());
junov@chromium.orgef760602012-06-27 20:03:16 +0000131 canvas->drawPaint(paint);
132 }
133 }
134
135private:
136 typedef PictureRecordBench INHERITED;
137};
138
139/*
140 * Populates the SkPaint dictionary with a number of unique paint
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000141 * objects that get reused repeatedly.
142 *
143 * Re-creating the paint objects in the inner loop slows the benchmark down 10%.
144 * Using setColor(i % objCount) instead of a random color creates a very high rate
145 * of hash conflicts, slowing us down 12%.
junov@chromium.orgef760602012-06-27 20:03:16 +0000146 */
147class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
148public:
mtklein@google.com93d2f552013-09-17 18:58:53 +0000149 RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionary") {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000150 SkRandom rand;
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000151 for (int i = 0; i < ObjCount; i++) {
152 fPaint[i].setColor(rand.nextU());
153 }
154 }
junov@chromium.orgef760602012-06-27 20:03:16 +0000155
156 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000157 ObjCount = 100, // number of unique paint objects
junov@chromium.orgef760602012-06-27 20:03:16 +0000158 };
159protected:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000160 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
mtklein@google.com93d2f552013-09-17 18:58:53 +0000161 SkPicture picture;
162 SkCanvas* canvas = picture.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000163 for (int i = 0; i < loops; i++) {
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000164 canvas->drawPaint(fPaint[i % ObjCount]);
junov@chromium.orgef760602012-06-27 20:03:16 +0000165 }
166 }
167
168private:
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000169 SkPaint fPaint [ObjCount];
junov@chromium.orgef760602012-06-27 20:03:16 +0000170 typedef PictureRecordBench INHERITED;
171};
172
djsollen@google.comdde718c2012-05-30 16:50:11 +0000173///////////////////////////////////////////////////////////////////////////////
174
mtklein@google.com410e6e82013-09-13 19:52:27 +0000175DEF_BENCH( return new DictionaryRecordBench(); )
176DEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
177DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )