• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkBenchmark.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 
16 static const char* gConfigName[] = {
17     "ERROR", "a1", "a8", "index8", "565", "4444", "8888"
18 };
19 
draw_into_bitmap(const SkBitmap & bm)20 static void draw_into_bitmap(const SkBitmap& bm) {
21     const int w = bm.width();
22     const int h = bm.height();
23 
24     SkCanvas canvas(bm);
25     SkPaint p;
26     p.setAntiAlias(true);
27     p.setColor(SK_ColorRED);
28     canvas.drawCircle(SkIntToScalar(w)/2, SkIntToScalar(h)/2,
29                       SkIntToScalar(SkMin32(w, h))*3/8, p);
30 
31     SkRect r;
32     r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h));
33     p.setStyle(SkPaint::kStroke_Style);
34     p.setStrokeWidth(SkIntToScalar(4));
35     p.setColor(SK_ColorBLUE);
36     canvas.drawRect(r, p);
37 }
38 
conv_6_to_byte(int x)39 static int conv_6_to_byte(int x) {
40     return x * 0xFF / 5;
41 }
42 
conv_byte_to_6(int x)43 static int conv_byte_to_6(int x) {
44     return x * 5 / 255;
45 }
46 
compute_666_index(SkPMColor c)47 static uint8_t compute_666_index(SkPMColor c) {
48     int r = SkGetPackedR32(c);
49     int g = SkGetPackedG32(c);
50     int b = SkGetPackedB32(c);
51 
52     return conv_byte_to_6(r) * 36 + conv_byte_to_6(g) * 6 + conv_byte_to_6(b);
53 }
54 
convert_to_index666(const SkBitmap & src,SkBitmap * dst,bool isOpaque)55 static void convert_to_index666(const SkBitmap& src, SkBitmap* dst,
56                                 bool isOpaque) {
57     SkPMColor storage[216];
58     SkPMColor* colors = storage;
59     // rrr ggg bbb
60     for (int r = 0; r < 6; r++) {
61         int rr = conv_6_to_byte(r);
62         for (int g = 0; g < 6; g++) {
63             int gg = conv_6_to_byte(g);
64             for (int b = 0; b < 6; b++) {
65                 int bb = conv_6_to_byte(b);
66                 *colors++ = SkPreMultiplyARGB(0xFF, rr, gg, bb);
67             }
68         }
69     }
70     SkAlphaType aType = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
71     SkColorTable* ctable = new SkColorTable(storage, 216, aType);
72     dst->setConfig(SkBitmap::kIndex8_Config, src.width(), src.height());
73     dst->allocPixels(ctable);
74     ctable->unref();
75 
76     SkAutoLockPixels alps(src);
77     SkAutoLockPixels alpd(*dst);
78 
79     for (int y = 0; y < src.height(); y++) {
80         const SkPMColor* srcP = src.getAddr32(0, y);
81         uint8_t* dstP = dst->getAddr8(0, y);
82         for (int x = src.width() - 1; x >= 0; --x) {
83             *dstP++ = compute_666_index(*srcP++);
84         }
85     }
86 }
87 
88 class RepeatTileBench : public SkBenchmark {
89     SkPaint          fPaint;
90     SkString         fName;
91     SkBitmap         fBitmap;
92     bool             fIsOpaque;
93     SkBitmap::Config fConfig;
94 public:
RepeatTileBench(SkBitmap::Config c,bool isOpaque=false)95     RepeatTileBench(SkBitmap::Config c, bool isOpaque = false)  {
96         const int w = 50;
97         const int h = 50;
98         fConfig = c;
99         fIsOpaque = isOpaque;
100 
101         if (SkBitmap::kIndex8_Config == fConfig) {
102             fBitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h);
103         } else {
104             fBitmap.setConfig(fConfig, w, h);
105         }
106         fName.printf("repeatTile_%s_%c",
107                      gConfigName[fBitmap.config()], isOpaque ? 'X' : 'A');
108     }
109 
110 protected:
onGetName()111     virtual const char* onGetName() SK_OVERRIDE {
112         return fName.c_str();
113     }
114 
onPreDraw()115     virtual void onPreDraw() SK_OVERRIDE {
116         fBitmap.allocPixels();
117         fBitmap.eraseColor(fIsOpaque ? SK_ColorWHITE : 0);
118         fBitmap.setAlphaType(fIsOpaque ?
119                              kOpaque_SkAlphaType : kPremul_SkAlphaType);
120 
121         draw_into_bitmap(fBitmap);
122 
123         if (SkBitmap::kIndex8_Config == fConfig) {
124             SkBitmap tmp;
125             convert_to_index666(fBitmap, &tmp, fIsOpaque);
126             fBitmap = tmp;
127         }
128 
129         SkShader* s = SkShader::CreateBitmapShader(fBitmap,
130                                                    SkShader::kRepeat_TileMode,
131                                                    SkShader::kRepeat_TileMode);
132         fPaint.setShader(s)->unref();
133     }
134 
135 
onDraw(const int loops,SkCanvas * canvas)136     virtual void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
137         SkPaint paint(fPaint);
138         this->setupPaint(&paint);
139 
140         for (int i = 0; i < loops; i++) {
141             canvas->drawPaint(paint);
142         }
143     }
144 
145 private:
146     typedef SkBenchmark INHERITED;
147 };
148 
149 DEF_BENCH(return new RepeatTileBench(SkBitmap::kARGB_8888_Config, true))
150 DEF_BENCH(return new RepeatTileBench(SkBitmap::kARGB_8888_Config, false))
151 DEF_BENCH(return new RepeatTileBench(SkBitmap::kRGB_565_Config))
152 DEF_BENCH(return new RepeatTileBench(SkBitmap::kIndex8_Config))
153