1 
2 /*
3  * Copyright 2013 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 
9 #include "Benchmark.h"
10 #include "SkCanvas.h"
11 #include "SkPaint.h"
12 #include "SkRandom.h"
13 #include "SkString.h"
14 #include "SkXfermode.h"
15 
16 // Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
17 class XfermodeBench : public Benchmark {
18 public:
XfermodeBench(SkXfermode::Mode mode,bool aa)19     XfermodeBench(SkXfermode::Mode mode, bool aa) {
20         fXfermode.reset(SkXfermode::Create(mode));
21         fAA = aa;
22         SkASSERT(fXfermode.get() || SkXfermode::kSrcOver_Mode == mode);
23         fName.printf("Xfermode_%s%s", SkXfermode::ModeName(mode), aa ? "_aa" : "");
24     }
25 
XfermodeBench(SkXfermode * xferMode,const char * name,bool aa)26     XfermodeBench(SkXfermode* xferMode, const char* name, bool aa) {
27         SkASSERT(xferMode);
28         fXfermode.reset(xferMode);
29         fAA = aa;
30         fName.printf("Xfermode_%s%s", name, aa ? "_aa" : "");
31     }
32 
33 protected:
onGetName()34     const char* onGetName() override { return fName.c_str(); }
35 
onDraw(const int loops,SkCanvas * canvas)36     void onDraw(const int loops, SkCanvas* canvas) override {
37         const char* text = "Hamburgefons";
38         size_t len = strlen(text);
39         SkISize size = canvas->getDeviceSize();
40         SkRandom random;
41         for (int i = 0; i < loops; ++i) {
42             SkPaint paint;
43             paint.setXfermode(fXfermode.get());
44             paint.setColor(random.nextU());
45             if (fAA) {
46                 // Draw text to exercise AA code paths.
47                 paint.setAntiAlias(true);
48                 paint.setTextSize(random.nextRangeScalar(12, 96));
49                 SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth),
50                          y = random.nextRangeScalar(0, (SkScalar)size.fHeight);
51                 for (int j = 0; j < 1000; ++j) {
52                     canvas->drawText(text, len, x, y, paint);
53                 }
54             } else {
55                 // Draw rects to exercise non-AA code paths.
56                 SkScalar w = random.nextRangeScalar(50, 100);
57                 SkScalar h = random.nextRangeScalar(50, 100);
58                 SkRect rect = SkRect::MakeXYWH(
59                     random.nextUScalar1() * (size.fWidth - w),
60                     random.nextUScalar1() * (size.fHeight - h),
61                     w,
62                     h
63                 );
64                 for (int j = 0; j < 1000; ++j) {
65                     canvas->drawRect(rect, paint);
66                 }
67             }
68         }
69     }
70 
71 private:
72     SkAutoTUnref<SkXfermode> fXfermode;
73     SkString fName;
74     bool fAA;
75 
76     typedef Benchmark INHERITED;
77 };
78 
79 class XferCreateBench : public Benchmark {
80 public:
isSuitableFor(Backend backend)81     bool isSuitableFor(Backend backend) override {
82         return backend == kNonRendering_Backend;
83     }
84 
85 protected:
onGetName()86     const char* onGetName() override { return "xfermode_create"; }
87 
onDraw(const int loops,SkCanvas * canvas)88     void onDraw(const int loops, SkCanvas* canvas) override {
89         for (int outer = 0; outer < loops * 10; ++outer) {
90             for (int i = 0; i <= SkXfermode::kLastMode; ++i) {
91                 SkXfermode* xfer = SkXfermode::Create(SkXfermode::Mode(i));
92                 SkSafeUnref(xfer);
93             }
94         }
95     }
96 
97 private:
98     typedef Benchmark INHERITED;
99 };
100 
101 //////////////////////////////////////////////////////////////////////////////
102 
103 #define BENCH(...)                                             \
104     DEF_BENCH( return new XfermodeBench(__VA_ARGS__, true); )  \
105     DEF_BENCH( return new XfermodeBench(__VA_ARGS__, false); )
106 
107 BENCH(SkXfermode::kClear_Mode)
108 BENCH(SkXfermode::kSrc_Mode)
109 BENCH(SkXfermode::kDst_Mode)
110 BENCH(SkXfermode::kSrcOver_Mode)
111 BENCH(SkXfermode::kDstOver_Mode)
112 BENCH(SkXfermode::kSrcIn_Mode)
113 BENCH(SkXfermode::kDstIn_Mode)
114 BENCH(SkXfermode::kSrcOut_Mode)
115 BENCH(SkXfermode::kDstOut_Mode)
116 BENCH(SkXfermode::kSrcATop_Mode)
117 BENCH(SkXfermode::kDstATop_Mode)
118 BENCH(SkXfermode::kXor_Mode)
119 
120 BENCH(SkXfermode::kPlus_Mode)
121 BENCH(SkXfermode::kModulate_Mode)
122 BENCH(SkXfermode::kScreen_Mode)
123 
124 BENCH(SkXfermode::kOverlay_Mode)
125 BENCH(SkXfermode::kDarken_Mode)
126 BENCH(SkXfermode::kLighten_Mode)
127 BENCH(SkXfermode::kColorDodge_Mode)
128 BENCH(SkXfermode::kColorBurn_Mode)
129 BENCH(SkXfermode::kHardLight_Mode)
130 BENCH(SkXfermode::kSoftLight_Mode)
131 BENCH(SkXfermode::kDifference_Mode)
132 BENCH(SkXfermode::kExclusion_Mode)
133 BENCH(SkXfermode::kMultiply_Mode)
134 
135 BENCH(SkXfermode::kHue_Mode)
136 BENCH(SkXfermode::kSaturation_Mode)
137 BENCH(SkXfermode::kColor_Mode)
138 BENCH(SkXfermode::kLuminosity_Mode)
139 
140 DEF_BENCH(return new XferCreateBench;)
141