2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
11 #include "SkPicture.h"
12 #include "SkPictureRecorder.h"
18 class PictureRecordBench : public Benchmark {
20 PictureRecordBench(const char name[]) {
21 fName.printf("picture_record_%s", name);
24 virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
25 return backend == kNonRendering_Backend;
30 PICTURE_HEIGHT = 4000,
33 virtual const char* onGetName() SK_OVERRIDE {
38 typedef Benchmark INHERITED;
42 static const int kMaxLoopsPerCanvas = 10000;
45 * An SkPicture has internal dictionaries to store bitmaps, matrices, paints,
46 * and regions. This bench populates those dictionaries to test the speed of
47 * reading and writing to those particular dictionary data structures.
49 class DictionaryRecordBench : public PictureRecordBench {
51 DictionaryRecordBench() : INHERITED("dictionaries") {}
54 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
55 SkPictureRecorder recorder;
56 SkCanvas* canvas = NULL;
58 const SkPoint translateDelta = getTranslateDelta(loops);
60 for (int i = 0; i < loops; i++) {
61 if (0 == i % kMaxLoopsPerCanvas) {
62 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
63 canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
66 SkColor color = SK_ColorYELLOW + (i % 255);
67 SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
71 // set the clip to the given region
74 canvas->clipRegion(region);
76 // fill the clip with a color
78 paint.setColor(color);
79 canvas->drawPaint(paint);
81 // set a matrix on the canvas
83 matrix.setRotate(SkIntToScalar(i % 360));
84 canvas->setMatrix(matrix);
86 // create a simple bitmap
88 bitmap.allocPixels(SkImageInfo::Make(10, 10,
89 kRGB_565_SkColorType, kOpaque_SkAlphaType));
91 // draw a single color into the bitmap
92 SkCanvas bitmapCanvas(bitmap);
93 bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
95 // draw the bitmap onto the canvas
96 canvas->drawBitmapMatrix(bitmap, matrix);
99 canvas->translate(translateDelta.fX, translateDelta.fY);
103 SkPoint getTranslateDelta(int M) {
104 SkIPoint canvasSize = onGetSize();
105 return SkPoint::Make(SkIntToScalar((PICTURE_WIDTH - canvasSize.fX)/M),
106 SkIntToScalar((PICTURE_HEIGHT- canvasSize.fY)/M));
109 typedef PictureRecordBench INHERITED;
113 * Populates the SkPaint dictionary with a large number of unique paint
114 * objects that differ only by color
116 class UniquePaintDictionaryRecordBench : public PictureRecordBench {
118 UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }
121 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
124 SkPictureRecorder recorder;
125 SkCanvas* canvas = NULL;
126 for (int i = 0; i < loops; i++) {
127 if (0 == i % kMaxLoopsPerCanvas) {
128 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
129 canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
131 paint.setColor(rand.nextU());
132 canvas->drawPaint(paint);
137 typedef PictureRecordBench INHERITED;
141 * Populates the SkPaint dictionary with a number of unique paint
142 * objects that get reused repeatedly.
144 * Re-creating the paint objects in the inner loop slows the benchmark down 10%.
145 * Using setColor(i % objCount) instead of a random color creates a very high rate
146 * of hash conflicts, slowing us down 12%.
148 class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
150 RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionary") {
152 for (int i = 0; i < ObjCount; i++) {
153 fPaint[i].setColor(rand.nextU());
158 ObjCount = 100, // number of unique paint objects
161 virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
162 SkPictureRecorder recorder;
163 SkCanvas* canvas = recorder.beginRecording(PICTURE_WIDTH, PICTURE_HEIGHT, NULL, 0);
164 for (int i = 0; i < loops; i++) {
165 canvas->drawPaint(fPaint[i % ObjCount]);
170 SkPaint fPaint [ObjCount];
171 typedef PictureRecordBench INHERITED;
174 ///////////////////////////////////////////////////////////////////////////////
176 DEF_BENCH( return new DictionaryRecordBench(); )
177 DEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
178 DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )