blob: d569fd364de32debb82dfc4a40031f0eb4001e65 [file] [log] [blame]
bsalomon3342ed52014-07-30 08:58:20 -07001/*
2 * Copyright 2014 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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "bench/Benchmark.h"
9#include "include/core/SkCanvas.h"
10#include "include/core/SkPaint.h"
11#include "include/effects/SkGradientShader.h"
12#include "src/core/SkBlendModePriv.h"
bsalomon3342ed52014-07-30 08:58:20 -070013
bsalomon65635622014-08-08 07:43:29 -070014#include <ctype.h>
15
bsalomon3342ed52014-07-30 08:58:20 -070016/** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
bsalomon65635622014-08-08 07:43:29 -070017 paint color between each rect in different ways using the ColorType enum. The xfermode used can
halcanary9d524f22016-03-29 09:03:52 -070018 be specified as well.
bsalomon65635622014-08-08 07:43:29 -070019 */
20
21enum ColorType {
22 kConstantOpaque_ColorType,
23 kConstantTransparent_ColorType,
24 kChangingOpaque_ColorType,
25 kChangingTransparent_ColorType,
26 kAlternatingOpaqueAndTransparent_ColorType,
Michael Ludwigdde8b552018-11-20 14:58:23 -050027 kShaderOpaque_ColorType
bsalomon65635622014-08-08 07:43:29 -070028};
29
30static inline SkColor start_color(ColorType ct) {
31 switch (ct) {
32 case kConstantOpaque_ColorType:
33 case kChangingOpaque_ColorType:
34 case kAlternatingOpaqueAndTransparent_ColorType:
35 return 0xFFA07040;
36 case kConstantTransparent_ColorType:
37 case kChangingTransparent_ColorType:
38 return 0x80A07040;
Michael Ludwigdde8b552018-11-20 14:58:23 -050039 case kShaderOpaque_ColorType:
40 return SK_ColorWHITE;
bsalomon65635622014-08-08 07:43:29 -070041 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040042 SK_ABORT("Shouldn't reach here.");
bsalomon65635622014-08-08 07:43:29 -070043}
44
45static inline SkColor advance_color(SkColor old, ColorType ct, int step) {
46 if (kAlternatingOpaqueAndTransparent_ColorType == ct) {
47 ct = (step & 0x1) ? kChangingOpaque_ColorType : kChangingTransparent_ColorType ;
48 }
49 switch (ct) {
50 case kConstantOpaque_ColorType:
51 case kConstantTransparent_ColorType:
Michael Ludwigdde8b552018-11-20 14:58:23 -050052 case kShaderOpaque_ColorType:
bsalomon65635622014-08-08 07:43:29 -070053 return old;
54 case kChangingOpaque_ColorType:
55 return 0xFF000000 | (old + 0x00010307);
56 case kChangingTransparent_ColorType:
57 return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000;
58 case kAlternatingOpaqueAndTransparent_ColorType:
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040059 SK_ABORT("Can't get here");
bsalomon65635622014-08-08 07:43:29 -070060 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -040061 SK_ABORT("Shouldn't reach here.");
bsalomon65635622014-08-08 07:43:29 -070062}
63
64static SkString to_lower(const char* str) {
65 SkString lower(str);
66 for (size_t i = 0; i < lower.size(); i++) {
67 lower[i] = tolower(lower[i]);
68 }
69 return lower;
70}
71
bsalomon3342ed52014-07-30 08:58:20 -070072class RotRectBench: public Benchmark {
73public:
Michael Ludwigdde8b552018-11-20 14:58:23 -050074 RotRectBench(bool aa, ColorType ct, SkBlendMode mode, bool perspective = false)
bsalomon3342ed52014-07-30 08:58:20 -070075 : fAA(aa)
Michael Ludwigdde8b552018-11-20 14:58:23 -050076 , fPerspective(perspective)
bsalomon65635622014-08-08 07:43:29 -070077 , fColorType(ct)
78 , fMode(mode) {
bsalomon3342ed52014-07-30 08:58:20 -070079 this->makeName();
80 }
81
82protected:
mtklein36352bf2015-03-25 18:17:31 -070083 const char* onGetName() override { return fName.c_str(); }
bsalomon3342ed52014-07-30 08:58:20 -070084
mtkleina1ebeb22015-10-01 09:43:39 -070085 void onDraw(int loops, SkCanvas* canvas) override {
bsalomon3342ed52014-07-30 08:58:20 -070086 SkPaint paint;
87 paint.setAntiAlias(fAA);
reed374772b2016-10-05 17:33:02 -070088 paint.setBlendMode(fMode);
bsalomon65635622014-08-08 07:43:29 -070089 SkColor color = start_color(fColorType);
bsalomon3342ed52014-07-30 08:58:20 -070090
tomhudsonc589f6c2015-03-23 07:46:13 -070091 int w = this->getSize().x();
92 int h = this->getSize().y();
bsalomon3342ed52014-07-30 08:58:20 -070093
94 static const SkScalar kRectW = 25.1f;
95 static const SkScalar kRectH = 25.9f;
96
Michael Ludwigdde8b552018-11-20 14:58:23 -050097 if (fColorType == kShaderOpaque_ColorType) {
98 // The only requirement for the shader is that it requires local coordinates
99 SkPoint pts[2] = { {0.0f, 0.0f}, {kRectW, kRectH} };
100 SkColor colors[] = { color, SK_ColorBLUE };
101 paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
Mike Reedfae8fce2019-04-03 10:27:45 -0400102 SkTileMode::kClamp));
Michael Ludwigdde8b552018-11-20 14:58:23 -0500103 }
104
bsalomon3342ed52014-07-30 08:58:20 -0700105 SkMatrix rotate;
106 // This value was chosen so that we frequently hit the axis-aligned case.
107 rotate.setRotate(30.f, kRectW / 2, kRectH / 2);
108 SkMatrix m = rotate;
109
110 SkScalar tx = 0, ty = 0;
111
Michael Ludwigdde8b552018-11-20 14:58:23 -0500112 if (fPerspective) {
113 // Apply some fixed perspective to change how ops may draw the rects
114 SkMatrix perspective;
115 perspective.setIdentity();
116 perspective.setPerspX(1e-4f);
117 perspective.setPerspY(1e-3f);
118 perspective.setSkewX(0.1f);
119 canvas->concat(perspective);
120 }
121
bsalomon3342ed52014-07-30 08:58:20 -0700122 for (int i = 0; i < loops; ++i) {
123 canvas->save();
124 canvas->translate(tx, ty);
125 canvas->concat(m);
126 paint.setColor(color);
bsalomon65635622014-08-08 07:43:29 -0700127 color = advance_color(color, fColorType, i);
128
bsalomon3342ed52014-07-30 08:58:20 -0700129 canvas->drawRect(SkRect::MakeWH(kRectW, kRectH), paint);
130 canvas->restore();
131
132 tx += kRectW + 2;
133 if (tx > w) {
134 tx = 0;
135 ty += kRectH + 2;
136 if (ty > h) {
137 ty = 0;
138 }
139 }
140
141 m.postConcat(rotate);
142 }
143 }
144
145private:
146 void makeName() {
147 fName = "rotated_rects";
148 if (fAA) {
149 fName.append("_aa");
150 } else {
151 fName.append("_bw");
152 }
Michael Ludwigdde8b552018-11-20 14:58:23 -0500153 if (fPerspective) {
154 fName.append("_persp");
155 }
bsalomon65635622014-08-08 07:43:29 -0700156 switch (fColorType) {
157 case kConstantOpaque_ColorType:
158 fName.append("_same_opaque");
159 break;
160 case kConstantTransparent_ColorType:
161 fName.append("_same_transparent");
162 break;
163 case kChangingOpaque_ColorType:
164 fName.append("_changing_opaque");
165 break;
166 case kChangingTransparent_ColorType:
167 fName.append("_changing_transparent");
168 break;
169 case kAlternatingOpaqueAndTransparent_ColorType:
170 fName.append("_alternating_transparent_and_opaque");
171 break;
Michael Ludwigdde8b552018-11-20 14:58:23 -0500172 case kShaderOpaque_ColorType:
173 fName.append("_shader_opaque");
174 break;
bsalomon3342ed52014-07-30 08:58:20 -0700175 }
Mike Reedd4706732016-11-15 16:44:34 -0500176 fName.appendf("_%s", to_lower(SkBlendMode_Name(fMode)).c_str());
bsalomon3342ed52014-07-30 08:58:20 -0700177 }
178
reed374772b2016-10-05 17:33:02 -0700179 bool fAA;
Michael Ludwigdde8b552018-11-20 14:58:23 -0500180 bool fPerspective;
reed374772b2016-10-05 17:33:02 -0700181 ColorType fColorType;
182 SkBlendMode fMode;
183 SkString fName;
bsalomon3342ed52014-07-30 08:58:20 -0700184
John Stiles7571f9e2020-09-02 22:42:33 -0400185 using INHERITED = Benchmark;
bsalomon3342ed52014-07-30 08:58:20 -0700186};
187
Michael Ludwigdde8b552018-11-20 14:58:23 -0500188#define DEF_FOR_COLOR_TYPES(aa, blend) \
189 DEF_BENCH(return new RotRectBench(aa, kConstantOpaque_ColorType, blend);) \
190 DEF_BENCH(return new RotRectBench(aa, kConstantTransparent_ColorType, blend);) \
191 DEF_BENCH(return new RotRectBench(aa, kChangingOpaque_ColorType, blend);) \
192 DEF_BENCH(return new RotRectBench(aa, kChangingTransparent_ColorType, blend);) \
193 DEF_BENCH(return new RotRectBench(aa, kAlternatingOpaqueAndTransparent_ColorType, blend);) \
194 DEF_BENCH(return new RotRectBench(aa, kShaderOpaque_ColorType, blend);)
195#define DEF_FOR_AA_MODES(blend) \
196 DEF_FOR_COLOR_TYPES(true, blend) \
197 DEF_FOR_COLOR_TYPES(false, blend)
198
bsalomon65635622014-08-08 07:43:29 -0700199// Choose kSrcOver because it always allows coverage and alpha to be conflated. kSrc only allows
200// conflation when opaque, and kDarken because it isn't possilbe with standard GL blending.
Michael Ludwigdde8b552018-11-20 14:58:23 -0500201DEF_FOR_AA_MODES(SkBlendMode::kSrcOver)
202DEF_FOR_AA_MODES(SkBlendMode::kSrc)
203DEF_FOR_AA_MODES(SkBlendMode::kDarken)
bsalomon65635622014-08-08 07:43:29 -0700204
Michael Ludwigdde8b552018-11-20 14:58:23 -0500205// Only do a limited run of perspective tests
206#define DEF_FOR_PERSP_MODES(aa) \
207 DEF_BENCH(return new RotRectBench(aa, kConstantOpaque_ColorType, SkBlendMode::kSrcOver, true);)\
208 DEF_BENCH(return new RotRectBench(aa, kShaderOpaque_ColorType, SkBlendMode::kSrcOver, true);)
209DEF_FOR_PERSP_MODES(true)
210DEF_FOR_PERSP_MODES(false)