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
draw_into_bitmap(const SkBitmap & bm)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
conv_6_to_byte(int x)36 static int conv_6_to_byte(int x) {
37 return x * 0xFF / 5;
38 }
39
conv_byte_to_6(int x)40 static int conv_byte_to_6(int x) {
41 return x * 5 / 255;
42 }
43
compute_666_index(SkPMColor c)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
convert_to_index666(const SkBitmap & src,SkBitmap * dst)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:
RepeatTileBench(SkColorType ct,SkAlphaType at=kPremul_SkAlphaType)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:
onGetName()107 const char* onGetName() override {
108 return fName.c_str();
109 }
110
onPreDraw()111 void onPreDraw() 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
onDraw(const int loops,SkCanvas * canvas)130 void onDraw(const int loops, SkCanvas* canvas) 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))
147