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