xref: /third_party/skia/bench/BlendmodeBench.cpp (revision cb93a386)
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
18namespace {
19enum Type {
20    kText,
21    kRect,
22    kSprite,
23};
24}
25
26const char* gTypeNames[] = {
27    "mask", "rect", "sprite",
28};
29
30// Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
31class XfermodeBench : public Benchmark {
32public:
33    XfermodeBench(SkBlendMode mode, Type t) : fBlendMode(mode) {
34        fType = t;
35        fName.printf("blendmicro_%s_%s", gTypeNames[t], SkBlendMode_Name(mode));
36    }
37
38protected:
39    const char* onGetName() override { return fName.c_str(); }
40
41    void onDelayedSetup() override {
42        if (fType == kSprite) {
43            fImage = GetResourceAsImage("images/color_wheel.png");
44        }
45    }
46
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
97    bool isSuitableFor(Backend backend) override {
98        return backend == kRaster_Backend;
99    }
100
101private:
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
117BENCH(SkBlendMode::kClear)
118BENCH(SkBlendMode::kSrc)
119BENCH(SkBlendMode::kDst)
120BENCH(SkBlendMode::kSrcOver)
121BENCH(SkBlendMode::kDstOver)
122BENCH(SkBlendMode::kSrcIn)
123BENCH(SkBlendMode::kDstIn)
124BENCH(SkBlendMode::kSrcOut)
125BENCH(SkBlendMode::kDstOut)
126BENCH(SkBlendMode::kSrcATop)
127BENCH(SkBlendMode::kDstATop)
128BENCH(SkBlendMode::kXor)
129
130BENCH(SkBlendMode::kPlus)
131BENCH(SkBlendMode::kModulate)
132BENCH(SkBlendMode::kScreen)
133
134BENCH(SkBlendMode::kOverlay)
135BENCH(SkBlendMode::kDarken)
136BENCH(SkBlendMode::kLighten)
137BENCH(SkBlendMode::kColorDodge)
138BENCH(SkBlendMode::kColorBurn)
139BENCH(SkBlendMode::kHardLight)
140BENCH(SkBlendMode::kSoftLight)
141BENCH(SkBlendMode::kDifference)
142BENCH(SkBlendMode::kExclusion)
143BENCH(SkBlendMode::kMultiply)
144
145BENCH(SkBlendMode::kHue)
146BENCH(SkBlendMode::kSaturation)
147BENCH(SkBlendMode::kColor)
148BENCH(SkBlendMode::kLuminosity)
149