Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / bench / PictureRecordBench.cpp
1 /*
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 "Benchmark.h"
8 #include "SkCanvas.h"
9 #include "SkColor.h"
10 #include "SkPaint.h"
11 #include "SkPicture.h"
12 #include "SkPictureRecorder.h"
13 #include "SkPoint.h"
14 #include "SkRandom.h"
15 #include "SkRect.h"
16 #include "SkString.h"
17
18 class PictureRecordBench : public Benchmark {
19 public:
20     PictureRecordBench(const char name[])  {
21         fName.printf("picture_record_%s", name);
22     }
23
24     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
25         return backend == kNonRendering_Backend;
26     }
27
28     enum {
29         PICTURE_WIDTH = 1000,
30         PICTURE_HEIGHT = 4000,
31     };
32 protected:
33     virtual const char* onGetName() SK_OVERRIDE {
34         return fName.c_str();
35     }
36 private:
37     SkString fName;
38     typedef Benchmark INHERITED;
39 };
40
41
42 static const int kMaxLoopsPerCanvas = 10000;
43
44 /*
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.
48  */
49 class DictionaryRecordBench : public PictureRecordBench {
50 public:
51     DictionaryRecordBench() : INHERITED("dictionaries") {}
52
53 protected:
54     virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
55         SkPictureRecorder recorder;
56         SkCanvas* canvas = NULL;
57
58         const SkPoint translateDelta = getTranslateDelta(loops);
59
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);
64             }
65
66             SkColor color = SK_ColorYELLOW + (i % 255);
67             SkIRect rect = SkIRect::MakeWH(i % PICTURE_WIDTH, i % PICTURE_HEIGHT);
68
69             canvas->save();
70
71             // set the clip to the given region
72             SkRegion region;
73             region.setRect(rect);
74             canvas->clipRegion(region);
75
76             // fill the clip with a color
77             SkPaint paint;
78             paint.setColor(color);
79             canvas->drawPaint(paint);
80
81             // set a matrix on the canvas
82             SkMatrix matrix;
83             matrix.setRotate(SkIntToScalar(i % 360));
84             canvas->setMatrix(matrix);
85
86             // create a simple bitmap
87             SkBitmap bitmap;
88             bitmap.allocPixels(SkImageInfo::Make(10, 10,
89                                                  kRGB_565_SkColorType, kOpaque_SkAlphaType));
90
91             // draw a single color into the bitmap
92             SkCanvas bitmapCanvas(bitmap);
93             bitmapCanvas.drawColor(SkColorSetA(color, i % 255));
94
95             // draw the bitmap onto the canvas
96             canvas->drawBitmapMatrix(bitmap, matrix);
97
98             canvas->restore();
99             canvas->translate(translateDelta.fX, translateDelta.fY);
100         }
101     }
102
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));
107     }
108 private:
109     typedef PictureRecordBench INHERITED;
110 };
111
112 /*
113  *  Populates the SkPaint dictionary with a large number of unique paint
114  *  objects that differ only by color
115  */
116 class UniquePaintDictionaryRecordBench : public PictureRecordBench {
117 public:
118     UniquePaintDictionaryRecordBench() : INHERITED("unique_paint_dictionary") { }
119
120 protected:
121     virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
122         SkRandom rand;
123         SkPaint paint;
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);
130             }
131             paint.setColor(rand.nextU());
132             canvas->drawPaint(paint);
133         }
134     }
135
136 private:
137     typedef PictureRecordBench INHERITED;
138 };
139
140 /*
141  *  Populates the SkPaint dictionary with a number of unique paint
142  *  objects that get reused repeatedly.
143  *
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%.
147  */
148 class RecurringPaintDictionaryRecordBench : public PictureRecordBench {
149 public:
150     RecurringPaintDictionaryRecordBench() : INHERITED("recurring_paint_dictionary") {
151         SkRandom rand;
152         for (int i = 0; i < ObjCount; i++) {
153             fPaint[i].setColor(rand.nextU());
154         }
155     }
156
157     enum {
158         ObjCount = 100,  // number of unique paint objects
159     };
160 protected:
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]);
166         }
167     }
168
169 private:
170     SkPaint fPaint [ObjCount];
171     typedef PictureRecordBench INHERITED;
172 };
173
174 ///////////////////////////////////////////////////////////////////////////////
175
176 DEF_BENCH( return new DictionaryRecordBench(); )
177 DEF_BENCH( return new UniquePaintDictionaryRecordBench(); )
178 DEF_BENCH( return new RecurringPaintDictionaryRecordBench(); )