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