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