Flutter Engine
The Flutter Engine
RotatedRectBench.cpp
Go to the documentation of this file.
1/*
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
8#include "bench/Benchmark.h"
13
14#include <ctype.h>
15
16/** This benchmark tests rendering rotated rectangles. It can optionally apply AA and/or change the
17 paint color between each rect in different ways using the ColorType enum. The xfermode used can
18 be specified as well.
19 */
20
28};
29
30static inline SkColor start_color(ColorType ct) {
31 switch (ct) {
35 return 0xFFA07040;
38 return 0x80A07040;
40 return SK_ColorWHITE;
41 }
42 SK_ABORT("Shouldn't reach here.");
43}
44
45static inline SkColor advance_color(SkColor old, ColorType ct, int step) {
48 }
49 switch (ct) {
53 return old;
55 return 0xFF000000 | (old + 0x00010307);
57 return (0x00FFFFFF & (old + 0x00010307)) | 0x80000000;
59 SK_ABORT("Can't get here");
60 }
61 SK_ABORT("Shouldn't reach here.");
62}
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
72class RotRectBench: public Benchmark {
73public:
74 RotRectBench(bool aa, ColorType ct, SkBlendMode mode, bool perspective = false)
75 : fAA(aa)
76 , fPerspective(perspective)
77 , fColorType(ct)
78 , fMode(mode) {
79 this->makeName();
80 }
81
82protected:
83 const char* onGetName() override { return fName.c_str(); }
84
85 void onDraw(int loops, SkCanvas* canvas) override {
87 paint.setAntiAlias(fAA);
88 paint.setBlendMode(fMode);
89 SkColor color = start_color(fColorType);
90
91 int w = this->getSize().width();
92 int h = this->getSize().height();
93
94 static const SkScalar kRectW = 25.1f;
95 static const SkScalar kRectH = 25.9f;
96
97 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} };
101 paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2,
103 }
104
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
112 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
122 for (int i = 0; i < loops; ++i) {
123 canvas->save();
124 canvas->translate(tx, ty);
125 canvas->concat(m);
126 paint.setColor(color);
127 color = advance_color(color, fColorType, i);
128
129 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 }
153 if (fPerspective) {
154 fName.append("_persp");
155 }
156 switch (fColorType) {
158 fName.append("_same_opaque");
159 break;
161 fName.append("_same_transparent");
162 break;
164 fName.append("_changing_opaque");
165 break;
167 fName.append("_changing_transparent");
168 break;
170 fName.append("_alternating_transparent_and_opaque");
171 break;
173 fName.append("_shader_opaque");
174 break;
175 }
176 fName.appendf("_%s", to_lower(SkBlendMode_Name(fMode)).c_str());
177 }
178
179 bool fAA;
180 bool fPerspective;
181 ColorType fColorType;
182 SkBlendMode fMode;
183 SkString fName;
184
185 using INHERITED = Benchmark;
186};
187
188#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
199// 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.
204
205// 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);)
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
static SkString to_lower(const char *str)
@ kAlternatingOpaqueAndTransparent_ColorType
@ kChangingTransparent_ColorType
@ kConstantTransparent_ColorType
@ kConstantOpaque_ColorType
@ kChangingOpaque_ColorType
@ kShaderOpaque_ColorType
#define DEF_FOR_PERSP_MODES(aa)
#define DEF_FOR_AA_MODES(blend)
static SkColor start_color(ColorType ct)
static SkColor advance_color(SkColor old, ColorType ct, int step)
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
SK_API const char * SkBlendMode_Name(SkBlendMode blendMode)
SkBlendMode
Definition: SkBlendMode.h:38
@ kSrcOver
r = s + (1-sa)*d
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
static bool rotate(const SkDCubic &cubic, int zero, int index, SkDCubic &rotPath)
SkISize getSize()
Definition: Benchmark.cpp:26
const char * onGetName() override
void onDraw(int loops, SkCanvas *canvas) override
RotRectBench(bool aa, ColorType ct, SkBlendMode mode, bool perspective=false)
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
SkMatrix & setSkewX(SkScalar v)
Definition: SkMatrix.h:518
SkMatrix & setPerspX(SkScalar v)
Definition: SkMatrix.h:537
SkMatrix & setPerspY(SkScalar v)
Definition: SkMatrix.h:544
SkMatrix & setIdentity()
Definition: SkMatrix.h:626
void append(const char text[])
Definition: SkString.h:203
const char * c_str() const
Definition: SkString.h:133
void void void appendf(const char format[],...) SK_PRINTF_LIKE(2
Definition: SkString.cpp:550
const Paint & paint
Definition: color_source.cc:38
DlColor color
float SkScalar
Definition: extension.cpp:12
PODArray< SkColor > colors
Definition: SkRecords.h:276
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
SkScalar w
SkScalar h
constexpr int32_t width() const
Definition: SkSize.h:36
constexpr int32_t height() const
Definition: SkSize.h:37
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609