0e63336a0f89fbcafa9d53a096c1e0f853c1b44d
[platform/upstream/libSkiaSharp.git] / bench / RepeatTileBench.cpp
1
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #include "Benchmark.h"
9 #include "SkBitmap.h"
10 #include "SkCanvas.h"
11 #include "SkColorPriv.h"
12 #include "SkPaint.h"
13 #include "SkShader.h"
14 #include "SkString.h"
15 #include "sk_tool_utils.h"
16
17 static void draw_into_bitmap(const SkBitmap& bm) {
18     const int w = bm.width();
19     const int h = bm.height();
20
21     SkCanvas canvas(bm);
22     SkPaint p;
23     p.setAntiAlias(true);
24     p.setColor(SK_ColorRED);
25     canvas.drawCircle(SkIntToScalar(w)/2, SkIntToScalar(h)/2,
26                       SkIntToScalar(SkMin32(w, h))*3/8, p);
27
28     SkRect r;
29     r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
30     p.setStyle(SkPaint::kStroke_Style);
31     p.setStrokeWidth(SkIntToScalar(4));
32     p.setColor(SK_ColorBLUE);
33     canvas.drawRect(r, p);
34 }
35
36 static int conv_6_to_byte(int x) {
37     return x * 0xFF / 5;
38 }
39
40 static int conv_byte_to_6(int x) {
41     return x * 5 / 255;
42 }
43
44 static uint8_t compute_666_index(SkPMColor c) {
45     int r = SkGetPackedR32(c);
46     int g = SkGetPackedG32(c);
47     int b = SkGetPackedB32(c);
48
49     return conv_byte_to_6(r) * 36 + conv_byte_to_6(g) * 6 + conv_byte_to_6(b);
50 }
51
52 static void convert_to_index666(const SkBitmap& src, SkBitmap* dst) {
53     SkPMColor storage[216];
54     SkPMColor* colors = storage;
55     // rrr ggg bbb
56     for (int r = 0; r < 6; r++) {
57         int rr = conv_6_to_byte(r);
58         for (int g = 0; g < 6; g++) {
59             int gg = conv_6_to_byte(g);
60             for (int b = 0; b < 6; b++) {
61                 int bb = conv_6_to_byte(b);
62                 *colors++ = SkPreMultiplyARGB(0xFF, rr, gg, bb);
63             }
64         }
65     }
66     SkColorTable* ctable = new SkColorTable(storage, 216);
67     dst->allocPixels(SkImageInfo::Make(src.width(), src.height(),
68                                        kIndex_8_SkColorType, kOpaque_SkAlphaType),
69                      NULL, ctable);
70     ctable->unref();
71
72     SkAutoLockPixels alps(src);
73     SkAutoLockPixels alpd(*dst);
74
75     for (int y = 0; y < src.height(); y++) {
76         const SkPMColor* srcP = src.getAddr32(0, y);
77         uint8_t* dstP = dst->getAddr8(0, y);
78         for (int x = src.width() - 1; x >= 0; --x) {
79             *dstP++ = compute_666_index(*srcP++);
80         }
81     }
82 }
83
84 class RepeatTileBench : public Benchmark {
85     const SkColorType   fColorType;
86     const SkAlphaType   fAlphaType;
87     SkPaint             fPaint;
88     SkString            fName;
89     SkBitmap            fBitmap;
90 public:
91     RepeatTileBench(SkColorType ct, SkAlphaType at = kPremul_SkAlphaType)
92         : fColorType(ct), fAlphaType(at)
93     {
94         const int w = 50;
95         const int h = 50;
96
97         if (kIndex_8_SkColorType == ct) {
98             fBitmap.setInfo(SkImageInfo::MakeN32(w, h, at));
99         } else {
100             fBitmap.setInfo(SkImageInfo::Make(w, h, ct, at));
101         }
102         fName.printf("repeatTile_%s_%c",
103                      sk_tool_utils::colortype_name(ct), kOpaque_SkAlphaType == at ? 'X' : 'A');
104     }
105
106 protected:
107     const char* onGetName() SK_OVERRIDE {
108         return fName.c_str();
109     }
110
111     void onPreDraw() SK_OVERRIDE {
112         fBitmap.allocPixels();
113         fBitmap.eraseColor(kOpaque_SkAlphaType == fAlphaType ? SK_ColorWHITE : 0);
114
115         draw_into_bitmap(fBitmap);
116
117         if (kIndex_8_SkColorType == fColorType) {
118             SkBitmap tmp;
119             convert_to_index666(fBitmap, &tmp);
120             fBitmap = tmp;
121         }
122
123         SkShader* s = SkShader::CreateBitmapShader(fBitmap,
124                                                    SkShader::kRepeat_TileMode,
125                                                    SkShader::kRepeat_TileMode);
126         fPaint.setShader(s)->unref();
127     }
128
129
130     void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
131         SkPaint paint(fPaint);
132         this->setupPaint(&paint);
133
134         for (int i = 0; i < loops; i++) {
135             canvas->drawPaint(paint);
136         }
137     }
138
139 private:
140     typedef Benchmark INHERITED;
141 };
142
143 DEF_BENCH(return new RepeatTileBench(kN32_SkColorType, kOpaque_SkAlphaType))
144 DEF_BENCH(return new RepeatTileBench(kN32_SkColorType, kPremul_SkAlphaType))
145 DEF_BENCH(return new RepeatTileBench(kRGB_565_SkColorType, kOpaque_SkAlphaType))
146 DEF_BENCH(return new RepeatTileBench(kIndex_8_SkColorType, kPremul_SkAlphaType))