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 "SkBlendModePriv.h"
10 #include "SkCanvas.h"
11 #include "SkFont.h"
12 #include "SkPaint.h"
13 #include "SkRandom.h"
14 #include "SkString.h"
15 #include "SkTextBlob.h"
16 
17 // Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
18 class XfermodeBench : public Benchmark {
19 public:
XfermodeBench(SkBlendMode mode,bool aa)20     XfermodeBench(SkBlendMode mode, bool aa) : fBlendMode(mode) {
21         fAA = aa;
22         fName.printf("blendmode_%s_%s", aa ? "mask" : "rect", SkBlendMode_Name(mode));
23     }
24 
25 protected:
onGetName()26     const char* onGetName() override { return fName.c_str(); }
27 
onDraw(int loops,SkCanvas * canvas)28     void onDraw(int loops, SkCanvas* canvas) override {
29         const char* text = "Hamburgefons";
30         size_t len = strlen(text);
31         SkISize size = canvas->getBaseLayerSize();
32         SkRandom random;
33         for (int i = 0; i < loops; ++i) {
34             SkPaint paint;
35             paint.setBlendMode(fBlendMode);
36             paint.setColor(random.nextU());
37             if (fAA) {
38                 // Draw text to exercise AA code paths.
39                 SkFont font;
40                 font.setSize(random.nextRangeScalar(12, 96));
41                 SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth),
42                          y = random.nextRangeScalar(0, (SkScalar)size.fHeight);
43                 auto blob = SkTextBlob::MakeFromText(text, len, font, kUTF8_SkTextEncoding);
44                 for (int j = 0; j < 1000; ++j) {
45                     canvas->drawTextBlob(blob, x, y, paint);
46                 }
47             } else {
48                 // Draw rects to exercise non-AA code paths.
49                 SkScalar w = random.nextRangeScalar(50, 100);
50                 SkScalar h = random.nextRangeScalar(50, 100);
51                 SkRect rect = SkRect::MakeXYWH(
52                     random.nextUScalar1() * (size.fWidth - w),
53                     random.nextUScalar1() * (size.fHeight - h),
54                     w,
55                     h
56                 );
57                 for (int j = 0; j < 1000; ++j) {
58                     canvas->drawRect(rect, paint);
59                 }
60             }
61         }
62     }
63 
64 private:
65     SkBlendMode fBlendMode;
66     SkString    fName;
67     bool        fAA;
68 
69     typedef Benchmark INHERITED;
70 };
71 
72 //////////////////////////////////////////////////////////////////////////////
73 
74 #define BENCH(...)                                             \
75     DEF_BENCH( return new XfermodeBench(__VA_ARGS__, true); )  \
76     DEF_BENCH( return new XfermodeBench(__VA_ARGS__, false); )
77 
78 BENCH(SkBlendMode::kClear)
79 BENCH(SkBlendMode::kSrc)
80 BENCH(SkBlendMode::kDst)
81 BENCH(SkBlendMode::kSrcOver)
82 BENCH(SkBlendMode::kDstOver)
83 BENCH(SkBlendMode::kSrcIn)
84 BENCH(SkBlendMode::kDstIn)
85 BENCH(SkBlendMode::kSrcOut)
86 BENCH(SkBlendMode::kDstOut)
87 BENCH(SkBlendMode::kSrcATop)
88 BENCH(SkBlendMode::kDstATop)
89 BENCH(SkBlendMode::kXor)
90 
91 BENCH(SkBlendMode::kPlus)
92 BENCH(SkBlendMode::kModulate)
93 BENCH(SkBlendMode::kScreen)
94 
95 BENCH(SkBlendMode::kOverlay)
96 BENCH(SkBlendMode::kDarken)
97 BENCH(SkBlendMode::kLighten)
98 BENCH(SkBlendMode::kColorDodge)
99 BENCH(SkBlendMode::kColorBurn)
100 BENCH(SkBlendMode::kHardLight)
101 BENCH(SkBlendMode::kSoftLight)
102 BENCH(SkBlendMode::kDifference)
103 BENCH(SkBlendMode::kExclusion)
104 BENCH(SkBlendMode::kMultiply)
105 
106 BENCH(SkBlendMode::kHue)
107 BENCH(SkBlendMode::kSaturation)
108 BENCH(SkBlendMode::kColor)
109 BENCH(SkBlendMode::kLuminosity)
110