• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bench/Benchmark.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkFont.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkString.h"
13 #include "include/core/SkTextBlob.h"
14 #include "include/utils/SkRandom.h"
15 #include "src/core/SkBlendModePriv.h"
16 #include "tools/Resources.h"
17 
18 namespace {
19 enum Type {
20     kText,
21     kRect,
22     kSprite,
23 };
24 }
25 
26 const char* gTypeNames[] = {
27     "mask", "rect", "sprite",
28 };
29 
30 // Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
31 class XfermodeBench : public Benchmark {
32 public:
XfermodeBench(SkBlendMode mode,Type t)33     XfermodeBench(SkBlendMode mode, Type t) : fBlendMode(mode) {
34         fType = t;
35         fName.printf("blendmicro_%s_%s", gTypeNames[t], SkBlendMode_Name(mode));
36     }
37 
38 protected:
onGetName()39     const char* onGetName() override { return fName.c_str(); }
40 
onDelayedSetup()41     void onDelayedSetup() override {
42         if (fType == kSprite) {
43             fImage = GetResourceAsImage("images/color_wheel.png");
44         }
45     }
46 
onDraw(int loops,SkCanvas * canvas)47     void onDraw(int loops, SkCanvas* canvas) override {
48         const char* text = "Hamburgefons";
49         size_t len = strlen(text);
50         SkISize size = canvas->getBaseLayerSize();
51         SkRandom random;
52         while (loops > 0) {
53             SkPaint paint;
54             paint.setBlendMode(fBlendMode);
55             paint.setColor(random.nextU());
56             switch (fType) {
57                 case kText: {
58                     // Draw text to exercise AA code paths.
59                     SkFont font;
60                     font.setSize(random.nextRangeScalar(12, 96));
61                     SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth),
62                              y = random.nextRangeScalar(0, (SkScalar)size.fHeight);
63                     auto blob = SkTextBlob::MakeFromText(text, len, font, SkTextEncoding::kUTF8);
64                     int iterations = std::min(1000, loops);
65                     for (int j = 0; j < iterations; ++j) {
66                         canvas->drawTextBlob(blob, x, y, paint);
67                     }
68                     loops -= iterations;
69                 } break;
70                 case kRect: {
71                     // Draw rects to exercise non-AA code paths.
72                     SkScalar w = random.nextRangeScalar(50, 100);
73                     SkScalar h = random.nextRangeScalar(50, 100);
74                     SkRect rect = SkRect::MakeXYWH(
75                         random.nextUScalar1() * (size.fWidth - w),
76                         random.nextUScalar1() * (size.fHeight - h),
77                         w,
78                         h
79                     );
80                     int iterations = std::min(1000, loops);
81                     for (int j = 0; j < iterations; ++j) {
82                         canvas->drawRect(rect, paint);
83                     }
84                     loops -= iterations;
85                 } break;
86                 case kSprite:
87                     paint.setAlphaf(1.0f);
88                     for (int i = 0; i < 10; ++i) {
89                         canvas->drawImage(fImage, 0, 0, SkSamplingOptions(), &paint);
90                     }
91                     loops -= 1;
92                     break;
93             }
94         }
95     }
96 
isSuitableFor(Backend backend)97     bool isSuitableFor(Backend backend) override {
98         return backend == kRaster_Backend;
99     }
100 
101 private:
102     SkBlendMode fBlendMode;
103     SkString    fName;
104     sk_sp<SkImage> fImage;
105     Type        fType;
106 
107     using INHERITED = Benchmark;
108 };
109 
110 //////////////////////////////////////////////////////////////////////////////
111 
112 #define BENCH(mode)                                      \
113     DEF_BENCH( return new XfermodeBench(mode, kText); )  \
114     DEF_BENCH( return new XfermodeBench(mode, kRect); )  \
115     DEF_BENCH( return new XfermodeBench(mode, kSprite); )
116 
117 BENCH(SkBlendMode::kClear)
118 BENCH(SkBlendMode::kSrc)
119 BENCH(SkBlendMode::kDst)
120 BENCH(SkBlendMode::kSrcOver)
121 BENCH(SkBlendMode::kDstOver)
122 BENCH(SkBlendMode::kSrcIn)
123 BENCH(SkBlendMode::kDstIn)
124 BENCH(SkBlendMode::kSrcOut)
125 BENCH(SkBlendMode::kDstOut)
126 BENCH(SkBlendMode::kSrcATop)
127 BENCH(SkBlendMode::kDstATop)
128 BENCH(SkBlendMode::kXor)
129 
130 BENCH(SkBlendMode::kPlus)
131 BENCH(SkBlendMode::kModulate)
132 BENCH(SkBlendMode::kScreen)
133 
134 BENCH(SkBlendMode::kOverlay)
135 BENCH(SkBlendMode::kDarken)
136 BENCH(SkBlendMode::kLighten)
137 BENCH(SkBlendMode::kColorDodge)
138 BENCH(SkBlendMode::kColorBurn)
139 BENCH(SkBlendMode::kHardLight)
140 BENCH(SkBlendMode::kSoftLight)
141 BENCH(SkBlendMode::kDifference)
142 BENCH(SkBlendMode::kExclusion)
143 BENCH(SkBlendMode::kMultiply)
144 
145 BENCH(SkBlendMode::kHue)
146 BENCH(SkBlendMode::kSaturation)
147 BENCH(SkBlendMode::kColor)
148 BENCH(SkBlendMode::kLuminosity)
149