Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
blurcircles2.cpp
Go to the documentation of this file.
1/*
2* Copyright 2016 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 "gm/gm.h"
15#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
20#include "src/base/SkRandom.h"
21#include "src/core/SkBlurMask.h"
23
24/**
25 * In GM mode this draws an array of circles with different radii and different blur radii. Below
26 * each circle an almost-circle path is drawn with the same blur filter for comparison.
27 *
28 * In Sample mode this draws a single circle and almost-circle with animating radius and blur
29 * radius.
30 *
31 * Bench mode draws the same as GM mode but without the comparison almost-circle paths. It also
32 * slightly perturbs the blur and circle radii to stress caching of blurred profiles in GPU mode.
33 */
34class BlurCircles2GM : public skiagm::GM {
35public:
37 fAnimRadius = TimeUtils::PingPong(
38 0, kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius, kMaxRadius);
39 fAnimBlurRadius = TimeUtils::PingPong(0,
40 kBlurRadiusPingPoingPeriod,
41 kBlurRadiusPingPoingShift,
42 kMinBlurRadius,
43 kMaxBlurRadius);
44 }
45
46protected:
47 bool runAsBench() const override { return true; }
48
49 SkString getName() const override { return SkString("blurcircles2"); }
50
51 SkISize getISize() override { return SkISize::Make(730, 1350); }
52
53 void onDraw(SkCanvas* canvas) override {
54 constexpr SkScalar kMaxR = kMaxRadius + kMaxBlurRadius;
55
56 auto almostCircleMaker = [] (SkScalar radius) {
57 return SkPathBuilder().addArc(SkRect::MakeXYWH(-radius, -radius, 2 * radius, 2 * radius), 0, 355)
58 .setIsVolatile(true)
59 .close()
60 .detach();
61 };
62
63 auto blurMaker = [] (SkScalar radius) ->sk_sp<SkMaskFilter> {
66 };
67
69 paint.setColor(SK_ColorBLACK);
70
71 if (this->getMode() == kSample_Mode) {
72 paint.setMaskFilter(blurMaker(fAnimBlurRadius));
73 SkISize size = canvas->getBaseLayerSize();
74 SkPath almostCircle = almostCircleMaker(fAnimRadius);
75 canvas->save();
76 canvas->translate(size.fWidth / 2.f, size.fHeight / 4.f);
77 canvas->drawCircle(0, 0, fAnimRadius, paint);
78 canvas->translate(0, 2 * kMaxR);
79 canvas->drawPath(almostCircle, paint);
80 canvas->restore();
81 } else {
82 bool benchMode = this->getMode() == kBench_Mode;
83 canvas->save();
84 constexpr SkScalar kPad = 5;
85 constexpr SkScalar kRadiusSteps = 5;
86 constexpr SkScalar kBlurRadiusSteps = 5;
87 canvas->translate(kPad + kMinRadius + kMaxBlurRadius,
88 kPad + kMinRadius + kMaxBlurRadius);
89 constexpr SkScalar kDeltaRadius = (kMaxRadius - kMinRadius) / kRadiusSteps;
90 constexpr SkScalar kDeltaBlurRadius = (kMaxBlurRadius - kMinBlurRadius) /
91 kBlurRadiusSteps;
92 SkScalar lineWidth = 0;
93 if (!benchMode) {
94 for (int r = 0; r < kRadiusSteps - 1; ++r) {
95 const SkScalar radius = r * kDeltaRadius + kMinRadius;
96 lineWidth += 2 * (radius + kMaxBlurRadius) + kPad;
97 }
98 }
99 for (int br = 0; br < kBlurRadiusSteps; ++br) {
100 SkScalar blurRadius = br * kDeltaBlurRadius + kMinBlurRadius;
101 if (benchMode) {
102 blurRadius += fRandom.nextSScalar1() * kDeltaBlurRadius;
103 }
104 const SkScalar maxRowR = blurRadius + kMaxRadius;
105 paint.setMaskFilter(blurMaker(blurRadius));
106 canvas->save();
107 for (int r = 0; r < kRadiusSteps; ++r) {
108 SkScalar radius = r * kDeltaRadius + kMinRadius;
109 if (benchMode) {
110 radius += fRandom.nextSScalar1() * kDeltaRadius;
111 }
112 SkPath almostCircle;
113 if (!benchMode) {
114 almostCircle = almostCircleMaker(radius);
115 }
116 canvas->save();
117 canvas->drawCircle(0, 0, radius, paint);
118 canvas->translate(0, 2 * maxRowR + kPad);
119 if (!benchMode) {
120 canvas->drawPath(almostCircle, paint);
121 }
122 canvas->restore();
123 const SkScalar maxColR = radius + kMaxBlurRadius;
124 canvas->translate(maxColR * 2 + kPad, 0);
125 }
126 canvas->restore();
127 if (!benchMode) {
128 SkPaint blackPaint;
129 blackPaint.setColor(SK_ColorBLACK);
130 const SkScalar lineY = 3 * maxRowR + 1.5f * kPad;
131 if (br != kBlurRadiusSteps - 1) {
132 canvas->drawLine(0, lineY, lineWidth, lineY, blackPaint);
133 }
134 }
135 canvas->translate(0, maxRowR * 4 + 2 * kPad);
136 }
137 canvas->restore();
138 }
139 }
140
141 bool onAnimate(double nanos) override {
142 fAnimRadius = TimeUtils::PingPong(1e-9 * nanos, kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius,
143 kMaxRadius);
144 fAnimBlurRadius = TimeUtils::PingPong(1e-9 * nanos, kBlurRadiusPingPoingPeriod, kBlurRadiusPingPoingShift,
145 kMinBlurRadius, kMaxBlurRadius);
146 return true;
147 }
148
149private:
150 inline static constexpr SkScalar kMinRadius = 15;
151 inline static constexpr SkScalar kMaxRadius = 45;
152 inline static constexpr SkScalar kRadiusPingPoingPeriod = 8;
153 inline static constexpr SkScalar kRadiusPingPoingShift = 3;
154
155 inline static constexpr SkScalar kMinBlurRadius = 5;
156 inline static constexpr SkScalar kMaxBlurRadius = 45;
157 inline static constexpr SkScalar kBlurRadiusPingPoingPeriod = 3;
158 inline static constexpr SkScalar kBlurRadiusPingPoingShift = 1.5;
159
160 SkScalar fAnimRadius;
161 SkScalar fAnimBlurRadius;
162
163 SkRandom fRandom;
164
165 using INHERITED = skiagm::GM;
166};
167
168DEF_GM(return new BlurCircles2GM();)
@ kNormal_SkBlurStyle
fuzzy inside and outside
Definition SkBlurTypes.h:12
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr int kPad
bool runAsBench() const override
SkISize getISize() override
bool onAnimate(double nanos) override
SkString getName() const override
void onDraw(SkCanvas *canvas) override
static SkScalar SK_SPI ConvertRadiusToSigma(SkScalar radius)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
virtual SkISize getBaseLayerSize() const
Definition SkCanvas.cpp:373
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setMaskFilter(sk_sp< SkMaskFilter > maskFilter)
SkPathBuilder & close()
SkPathBuilder & addArc(const SkRect &oval, SkScalar startAngleDeg, SkScalar sweepAngleDeg)
SkPathBuilder & setIsVolatile(bool isVolatile)
SkScalar nextSScalar1()
Definition SkRandom.h:113
@ kBench_Mode
Definition gm.h:121
@ kSample_Mode
Definition gm.h:120
Mode getMode() const
Definition gm.h:125
const Paint & paint
float SkScalar
Definition extension.cpp:12
#define DEF_GM(CODE)
Definition gm.h:40
static float PingPong(double time, float period, float phase, float ends, float mid)
Definition TimeUtils.h:37
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659