1
2/*
3 * Copyright 2013 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include "Benchmark.h"
10#include "SkCanvas.h"
11#include "SkPaint.h"
12#include "SkRandom.h"
13#include "SkString.h"
14#include "SkXfermode.h"
15
16// Benchmark that draws non-AA rects or AA text with an SkXfermode::Mode.
17class XfermodeBench : public Benchmark {
18public:
19    XfermodeBench(SkXfermode::Mode mode, bool aa) {
20        fXfermode.reset(SkXfermode::Create(mode));
21        fAA = aa;
22        SkASSERT(fXfermode.get() || SkXfermode::kSrcOver_Mode == mode);
23        fName.printf("Xfermode_%s%s", SkXfermode::ModeName(mode), aa ? "_aa" : "");
24    }
25
26    XfermodeBench(SkXfermode* xferMode, const char* name, bool aa) {
27        SkASSERT(xferMode);
28        fXfermode.reset(xferMode);
29        fAA = aa;
30        fName.printf("Xfermode_%s%s", name, aa ? "_aa" : "");
31    }
32
33protected:
34    const char* onGetName() override { return fName.c_str(); }
35
36    void onDraw(int loops, SkCanvas* canvas) override {
37        const char* text = "Hamburgefons";
38        size_t len = strlen(text);
39        SkISize size = canvas->getDeviceSize();
40        SkRandom random;
41        for (int i = 0; i < loops; ++i) {
42            SkPaint paint;
43            paint.setXfermode(fXfermode.get());
44            paint.setColor(random.nextU());
45            if (fAA) {
46                // Draw text to exercise AA code paths.
47                paint.setAntiAlias(true);
48                paint.setTextSize(random.nextRangeScalar(12, 96));
49                SkScalar x = random.nextRangeScalar(0, (SkScalar)size.fWidth),
50                         y = random.nextRangeScalar(0, (SkScalar)size.fHeight);
51                for (int j = 0; j < 1000; ++j) {
52                    canvas->drawText(text, len, x, y, paint);
53                }
54            } else {
55                // Draw rects to exercise non-AA code paths.
56                SkScalar w = random.nextRangeScalar(50, 100);
57                SkScalar h = random.nextRangeScalar(50, 100);
58                SkRect rect = SkRect::MakeXYWH(
59                    random.nextUScalar1() * (size.fWidth - w),
60                    random.nextUScalar1() * (size.fHeight - h),
61                    w,
62                    h
63                );
64                for (int j = 0; j < 1000; ++j) {
65                    canvas->drawRect(rect, paint);
66                }
67            }
68        }
69    }
70
71private:
72    SkAutoTUnref<SkXfermode> fXfermode;
73    SkString fName;
74    bool fAA;
75
76    typedef Benchmark INHERITED;
77};
78
79class XferCreateBench : public Benchmark {
80public:
81    bool isSuitableFor(Backend backend) override {
82        return backend == kNonRendering_Backend;
83    }
84
85protected:
86    const char* onGetName() override { return "xfermode_create"; }
87
88    void onDraw(int loops, SkCanvas* canvas) override {
89        for (int outer = 0; outer < loops * 10; ++outer) {
90            for (int i = 0; i <= SkXfermode::kLastMode; ++i) {
91                SkXfermode* xfer = SkXfermode::Create(SkXfermode::Mode(i));
92                SkSafeUnref(xfer);
93            }
94        }
95    }
96
97private:
98    typedef Benchmark INHERITED;
99};
100
101//////////////////////////////////////////////////////////////////////////////
102
103#define BENCH(...)                                             \
104    DEF_BENCH( return new XfermodeBench(__VA_ARGS__, true); )  \
105    DEF_BENCH( return new XfermodeBench(__VA_ARGS__, false); )
106
107BENCH(SkXfermode::kClear_Mode)
108BENCH(SkXfermode::kSrc_Mode)
109BENCH(SkXfermode::kDst_Mode)
110BENCH(SkXfermode::kSrcOver_Mode)
111BENCH(SkXfermode::kDstOver_Mode)
112BENCH(SkXfermode::kSrcIn_Mode)
113BENCH(SkXfermode::kDstIn_Mode)
114BENCH(SkXfermode::kSrcOut_Mode)
115BENCH(SkXfermode::kDstOut_Mode)
116BENCH(SkXfermode::kSrcATop_Mode)
117BENCH(SkXfermode::kDstATop_Mode)
118BENCH(SkXfermode::kXor_Mode)
119
120BENCH(SkXfermode::kPlus_Mode)
121BENCH(SkXfermode::kModulate_Mode)
122BENCH(SkXfermode::kScreen_Mode)
123
124BENCH(SkXfermode::kOverlay_Mode)
125BENCH(SkXfermode::kDarken_Mode)
126BENCH(SkXfermode::kLighten_Mode)
127BENCH(SkXfermode::kColorDodge_Mode)
128BENCH(SkXfermode::kColorBurn_Mode)
129BENCH(SkXfermode::kHardLight_Mode)
130BENCH(SkXfermode::kSoftLight_Mode)
131BENCH(SkXfermode::kDifference_Mode)
132BENCH(SkXfermode::kExclusion_Mode)
133BENCH(SkXfermode::kMultiply_Mode)
134
135BENCH(SkXfermode::kHue_Mode)
136BENCH(SkXfermode::kSaturation_Mode)
137BENCH(SkXfermode::kColor_Mode)
138BENCH(SkXfermode::kLuminosity_Mode)
139
140DEF_BENCH(return new XferCreateBench;)
141