blob: 87e7240ca9713106f1c34360fc1d1a8d03bb08b4 [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);
bsalomon@google.com9e679352013-05-30 19:52:38 +000021 fIsRendering = false;
djsollen@google.comdde718c2012-05-30 16:50:11 +000022 }
23
24 enum {
djsollen@google.comdde718c2012-05-30 16:50:11 +000025 PICTURE_WIDTH = 1000,
26 PICTURE_HEIGHT = 4000,
27 };
28protected:
mtklein@google.com93d2f552013-09-17 18:58:53 +000029 virtual const char* onGetName() SK_OVERRIDE {
djsollen@google.comdde718c2012-05-30 16:50:11 +000030 return fName.c_str();
31 }
djsollen@google.comdde718c2012-05-30 16:50:11 +000032private:
mtklein@google.com93d2f552013-09-17 18:58:53 +000033 SkString fName;
djsollen@google.comdde718c2012-05-30 16:50:11 +000034 typedef SkBenchmark INHERITED;
35};
36
mtklein@google.com93d2f552013-09-17 18:58:53 +000037
38static const int kMaxLoopsPerCanvas = 10000;
39
djsollen@google.comdde718c2012-05-30 16:50:11 +000040/*
41 * An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
42 * and regions. This bench populates those dictionaries to test the speed of
43 * reading and writing to those particular dictionary data structures.
44 */
45class DictionaryRecordBench : public PictureRecordBench {
46public:
mtklein@google.com93d2f552013-09-17 18:58:53 +000047 DictionaryRecordBench() : INHERITED("dictionaries") {}
djsollen@google.comdde718c2012-05-30 16:50:11 +000048
djsollen@google.comdde718c2012-05-30 16:50:11 +000049protected:
mtklein@google.com93d2f552013-09-17 18:58:53 +000050 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
51 SkAutoTDelete<SkPicture> picture;
52 SkCanvas* canvas = NULL;
djsollen@google.comdde718c2012-05-30 16:50:11 +000053
mtklein@google.comc2897432013-09-10 19:23:38 +000054 const SkPoint translateDelta = getTranslateDelta(this->getLoops());
djsollen@google.comdde718c2012-05-30 16:50:11 +000055
mtklein@google.comc2897432013-09-10 19:23:38 +000056 for (int i = 0; i < this->getLoops(); i++) {
mtklein@google.com93d2f552013-09-17 18:58:53 +000057 if (0 == i % kMaxLoopsPerCanvas) {
58 picture.reset(SkNEW(SkPicture));
59 canvas = picture->beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
60 }
djsollen@google.comdde718c2012-05-30 16:50:11 +000061
62 SkColor color = SK_ColorYELLOW + (i % 255);
mtklein@google.comc2897432013-09-10 19:23:38 +000063 SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
djsollen@google.comdde718c2012-05-30 16:50:11 +000064
65 canvas->save();
66
67 // set the clip to the given region
68 SkRegion region;
69 region.setRect(rect);
70 canvas->clipRegion(region);
71
72 // fill the clip with a color
73 SkPaint paint;
74 paint.setColor(color);
75 canvas->drawPaint(paint);
76
77 // set a matrix on the canvas
78 SkMatrix matrix;
79 matrix.setRotate(SkIntToScalar(i % 360));
80 canvas->setMatrix(matrix);
81
82 // create a simple bitmap
83 SkBitmap bitmap;
84 bitmap.setConfig(SkBitmap::kRGB_565_Config, 10, 10);
85 bitmap.allocPixels();
86
87 // draw a single color into the bitmap
88 SkCanvas bitmapCanvas(bitmap);
89 bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
90
91 // draw the bitmap onto the canvas
92 canvas->drawBitmapMatrix(bitmap, matrix);
93
94 canvas->restore();
95 canvas->translate(translateDelta.fX, translateDelta.fY);
96 }
97 }
98
mtklein@google.comc2897432013-09-10 19:23:38 +000099 SkPoint getTranslateDelta(int M) {
djsollen@google.comdde718c2012-05-30 16:50:11 +0000100 SkIPoint canvasSize = onGetSize();
101 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
102 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
103 }
104private:
105 typedef PictureRecordBench INHERITED;
106};
107
junov@chromium.orgef760602012-06-27 20:03:16 +0000108/*
109 * Populates the SkPaint dictionary with a large number of unique paint
110 * objects that differ only by color
111 */
112class UniquePaintDictionaryRecordBench : public PictureRecordBench {
113public:
mtklein@google.com93d2f552013-09-17 18:58:53 +0000114 UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }
junov@chromium.orgef760602012-06-27 20:03:16 +0000115
junov@chromium.orgef760602012-06-27 20:03:16 +0000116protected:
mtklein@google.com93d2f552013-09-17 18:58:53 +0000117 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000118 SkRandom rand;
mtklein@google.com5e5239e2013-09-17 17:14:25 +0000119 SkPaint paint;
120 SkAutoTDelete<SkPicture> picture;
121 SkCanvas* canvas = NULL;
mtklein@google.comc2897432013-09-10 19:23:38 +0000122 for (int i = 0; i < this->getLoops(); i++) {
mtklein@google.com93d2f552013-09-17 18:58:53 +0000123 if (0 == i % kMaxLoopsPerCanvas) {
mtklein@google.com5e5239e2013-09-17 17:14:25 +0000124 picture.reset(SkNEW(SkPicture));
125 canvas = picture->beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
126 }
reed@google.com7fe64092012-07-10 13:17:45 +0000127 paint.setColor(rand.nextU());
junov@chromium.orgef760602012-06-27 20:03:16 +0000128 canvas->drawPaint(paint);
129 }
130 }
131
132private:
133 typedef PictureRecordBench INHERITED;
134};
135
136/*
137 * Populates the SkPaint dictionary with a number of unique paint
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000138 * objects that get reused repeatedly.
139 *
140 * Re-creating the paint objects in the inner loop slows the benchmark down 10%.
141 * Using setColor(i % objCount) instead of a random color creates a very high rate
142 * of hash conflicts, slowing us down 12%.
junov@chromium.orgef760602012-06-27 20:03:16 +0000143 */
144class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
145public:
mtklein@google.com93d2f552013-09-17 18:58:53 +0000146 RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionary") {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000147 SkRandom rand;
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000148 for (int i = 0; i < ObjCount; i++) {
149 fPaint[i].setColor(rand.nextU());
150 }
151 }
junov@chromium.orgef760602012-06-27 20:03:16 +0000152
153 enum {
mtklein@google.comc2897432013-09-10 19:23:38 +0000154 ObjCount = 100, // number of unique paint objects
junov@chromium.orgef760602012-06-27 20:03:16 +0000155 };
156protected:
mtklein@google.com93d2f552013-09-17 18:58:53 +0000157 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
158 SkPicture picture;
159 SkCanvas* canvas = picture.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT);
mtklein@google.comc2897432013-09-10 19:23:38 +0000160 for (int i = 0; i < this->getLoops(); i++) {
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000161 canvas->drawPaint(fPaint[i % ObjCount]);
junov@chromium.orgef760602012-06-27 20:03:16 +0000162 }
163 }
164
165private:
commit-bot@chromium.org0c4e21d2013-07-11 14:26:09 +0000166 SkPaint fPaint [ObjCount];
junov@chromium.orgef760602012-06-27 20:03:16 +0000167 typedef PictureRecordBench INHERITED;
168};
169
djsollen@google.comdde718c2012-05-30 16:50:11 +0000170///////////////////////////////////////////////////////////////////////////////
171
mtklein@google.com410e6e82013-09-13 19:52:27 +0000172DEF_BENCH( return new DictionaryRecordBench(); )
173DEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
174DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )