1 /*
2  * Copyright 2013 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 
8 #include "Benchmark.h"
9 #include "SkBitmap.h"
10 #include "SkCanvas.h"
11 #include "SkShader.h"
12 #include "SkString.h"
13 
14 static void create_gradient(SkBitmap* bm) {
15     SkASSERT(1 == bm->width());
16     const int height = bm->height();
17 
18     float deltaB = 255.0f / height;
19     float blue = 255.0f;
20 
21     for (int y = 0; y < height; y++) {
22         *bm->getAddr32(0, y) = SkColorSetRGB(0, 0, (U8CPU) blue);
23         blue -= deltaB;
24     }
25 }
26 
27 // Test out the special case of a tiled 1xN texture. Test out opacity,
28 // filtering and the different tiling modes
29 class ConstXTileBench : public Benchmark {
30     SkPaint             fPaint;
31     SkString            fName;
32     bool                fDoFilter;
33     bool                fDoTrans;
34     bool                fDoScale;
35     static const int kWidth = 1;
36     static const int kHeight = 300;
37 
38 public:
39     ConstXTileBench(SkShader::TileMode xTile,
40                     SkShader::TileMode yTile,
41                     bool doFilter,
42                     bool doTrans,
43                     bool doScale)
44         : fDoFilter(doFilter)
45         , fDoTrans(doTrans)
46         , fDoScale(doScale) {
47         SkBitmap bm;
48 
49         bm.allocN32Pixels(kWidth, kHeight, true);
50         bm.eraseColor(SK_ColorWHITE);
51 
52         create_gradient(&bm);
53 
54         fPaint.setShader(SkShader::MakeBitmapShader(bm, xTile, yTile));
55 
56         fName.printf("constXTile_");
57 
58         static const char* gTileModeStr[SkShader::kTileModeCount] = { "C", "R", "M" };
59         fName.append(gTileModeStr[xTile]);
60         fName.append(gTileModeStr[yTile]);
61 
62         if (doFilter) {
63             fName.append("_filter");
64         }
65 
66         if (doTrans) {
67             fName.append("_trans");
68         }
69 
70         if (doScale) {
71             fName.append("_scale");
72         }
73     }
74 
75 protected:
76     virtual const char* onGetName() {
77         return fName.c_str();
78     }
79 
80     virtual void onDraw(int loops, SkCanvas* canvas) {
81         SkPaint paint(fPaint);
82         this->setupPaint(&paint);
83         paint.setFilterQuality(fDoFilter ? kLow_SkFilterQuality
84                                          : kNone_SkFilterQuality);
85         if (fDoTrans) {
86             paint.setColor(SkColorSetARGBMacro(0x80, 0xFF, 0xFF, 0xFF));
87         }
88 
89         SkRect r;
90 
91         if (fDoScale) {
92             r = SkRect::MakeWH(SkIntToScalar(2 * 640), SkIntToScalar(2 * 480));
93             canvas->scale(SK_ScalarHalf, SK_ScalarHalf);
94         } else {
95             r = SkRect::MakeWH(SkIntToScalar(640), SkIntToScalar(480));
96         }
97 
98         SkPaint bgPaint;
99         bgPaint.setColor(SK_ColorWHITE);
100 
101         for (int i = 0; i < loops; i++) {
102             if (fDoTrans) {
103                 canvas->drawRect(r, bgPaint);
104             }
105 
106             canvas->drawRect(r, paint);
107         }
108     }
109 
110 private:
111     typedef Benchmark INHERITED;
112 };
113 
114 // Scaled benches are trending towards free.  Seems like caching.
115 // TODO(mtklein, reed): fix and reenable
116 
117 //DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, false, false, true))
118 DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, false, false, false))
119 //DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, false, false, true))
120 
121 DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, true, false, false))
122 //DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, true, false, true))
123 DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, true, false, false))
124 
125 //DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, false, true, true))
126 DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, false, true, false))
127 //DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, false, true, true))
128 
129 DEF_BENCH(return new ConstXTileBench(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, true, true, false))
130 //DEF_BENCH(return new ConstXTileBench(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, true, true, true))
131 DEF_BENCH(return new ConstXTileBench(SkShader::kMirror_TileMode, SkShader::kMirror_TileMode, true, true, false))
132