Flutter Engine
The Flutter Engine
animatedimageblurs.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"
14#include "include/core/SkRect.h"
16#include "include/core/SkSize.h"
21#include "src/base/SkRandom.h"
22#include "tools/DecodeUtils.h"
24
25static const SkScalar kBlurMax = 7.0f;
26static const int kNumNodes = 30;
27static const int kWidth = 512;
28static const int kHeight = 512;
29static const SkScalar kBlurAnimationDuration = 4.0f; // in secs
30
31// This GM draws a lot of layers with animating BlurImageFilters
33public:
34 AnimatedImageBlurs() : fLastTime(0.0f) {
35 this->setBGColor(0xFFCCCCCC);
36 }
37
38protected:
39 bool runAsBench() const override { return true; }
40
41 SkString getName() const override { return SkString("animated-image-blurs"); }
42
43 SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
44
45 void onOnceBeforeDraw() override {
46 for (int i = 0; i < kNumNodes; ++i) {
47 fNodes[i].init(&fRand);
48 }
49 }
50
51 void onDraw(SkCanvas* canvas) override {
53 paint.setAntiAlias(true);
54
55 for (int i = 0; i < kNumNodes; ++i) {
56 SkPaint layerPaint;
57 layerPaint.setImageFilter(SkImageFilters::Blur(fNodes[i].sigma(), fNodes[i].sigma(),
58 nullptr));
59
60 canvas->saveLayer(nullptr, &layerPaint);
61 // The rect is outset to block the circle case
62 SkRect rect = SkRect::MakeLTRB(fNodes[i].pos().fX - fNodes[i].size()-0.5f,
63 fNodes[i].pos().fY - fNodes[i].size()-0.5f,
64 fNodes[i].pos().fX + fNodes[i].size()+0.5f,
65 fNodes[i].pos().fY + fNodes[i].size()+0.5f);
66 SkRRect rrect = SkRRect::MakeRectXY(rect, fNodes[i].size(), fNodes[i].size());
67 canvas->drawRRect(rrect, paint);
68 canvas->restore();
69 }
70 }
71
72 bool onAnimate(double nanos) override {
73 if (0.0f != fLastTime) {
74 for (int i = 0; i < kNumNodes; ++i) {
75 fNodes[i].update(nanos, fLastTime);
76 }
77 }
78
79 fLastTime = 1e-9 * nanos;
80 return true;
81 }
82
83private:
84 class Node {
85 public:
86 Node()
87 : fSize(0.0f)
88 , fPos { 0.0f, 0.0f }
89 , fDir { 1.0f, 0.0f }
90 , fBlurOffset(0.0f)
91 , fBlur(fBlurOffset)
92 , fSpeed(0.0f) {
93 }
94
95 void init(SkRandom* rand) {
96 fSize = rand->nextRangeF(10.0f, 60.f);
97 fPos.fX = rand->nextRangeF(fSize, kWidth - fSize);
98 fPos.fY = rand->nextRangeF(fSize, kHeight - fSize);
99 fDir.fX = rand->nextRangeF(-1.0f, 1.0f);
100 fDir.fY = SkScalarSqrt(1.0f - fDir.fX * fDir.fX);
101 if (rand->nextBool()) {
102 fDir.fY = -fDir.fY;
103 }
104 fBlurOffset = rand->nextRangeF(0.0f, kBlurMax);
105 fBlur = fBlurOffset;
106 fSpeed = rand->nextRangeF(20.0f, 60.0f);
107 }
108
109 void update(double nanos, SkScalar lastTime) {
110 SkScalar deltaTime = 1e-9 * nanos - lastTime;
111
112 fPos.fX += deltaTime * fSpeed * fDir.fX;
113 fPos.fY += deltaTime * fSpeed * fDir.fY;
114 if (fPos.fX >= kWidth || fPos.fX < 0.0f) {
115 fPos.fX = SkTPin<SkScalar>(fPos.fX, 0.0f, kWidth);
116 fDir.fX = -fDir.fX;
117 }
118 if (fPos.fY >= kHeight || fPos.fY < 0.0f) {
119 fPos.fY = SkTPin<SkScalar>(fPos.fY, 0.0f, kHeight);
120 fDir.fY = -fDir.fY;
121 }
122
123 fBlur = TimeUtils::PingPong(1e-9 * nanos, kBlurAnimationDuration, fBlurOffset, 0.0f, kBlurMax);
124 }
125
126 SkScalar sigma() const { return fBlur; }
127 const SkPoint& pos() const { return fPos; }
128 SkScalar size() const { return fSize; }
129
130 private:
131 SkScalar fSize;
132 SkPoint fPos;
133 SkVector fDir;
134 SkScalar fBlurOffset;
135 SkScalar fBlur;
136 SkScalar fSpeed;
137 };
138
139 Node fNodes[kNumNodes];
140 SkRandom fRand;
141 SkScalar fLastTime;
142
143 using INHERITED = GM;
144};
145
146// This GM draws an image with a tiled blur that animates from large to small sigmas
148static constexpr float kMaxBlurSigma = 250.f;
149static constexpr float kAnimationDuration = 12.f; // seconds
150public:
151 AnimatedTiledImageBlur() : fBlurSigma(0.3f * kMaxBlurSigma) {
152 this->setBGColor(0xFFCCCCCC);
153 }
154
155protected:
156 bool runAsBench() const override { return true; }
157
158 SkString getName() const override { return SkString("animated-tiled-image-blur"); }
159
160 SkISize getISize() override { return SkISize::Make(530, 530); }
161
162 void onOnceBeforeDraw() override {
163 fImage = ToolUtils::GetResourceAsImage("images/mandrill_512.png");
164 }
165
166 void onDraw(SkCanvas* canvas) override {
167 auto drawBlurredImage = [&](float tx, float ty, SkTileMode tileMode) {
169 SkRect rect = SkRect::MakeIWH(250, 250);
170 canvas->save();
171 canvas->translate(tx, ty);
172 paint.setImageFilter(SkImageFilters::Blur(fBlurSigma, fBlurSigma, tileMode,
173 nullptr, rect));
174 canvas->drawImageRect(fImage, rect, SkFilterMode::kLinear, &paint);
175 canvas->restore();
176 };
177
178 drawBlurredImage(10.f, 10.f, SkTileMode::kDecal);
179 drawBlurredImage(270.f, 10.f, SkTileMode::kClamp);
180 drawBlurredImage(10.f, 270.f, SkTileMode::kRepeat);
181 drawBlurredImage(270.f, 270.f, SkTileMode::kMirror);
182 }
183
184 bool onAnimate(double nanos) override {
185 fBlurSigma = TimeUtils::PingPong(1e-9 * nanos, kAnimationDuration,
186 0.f, 0.0f, kMaxBlurSigma);
187 return true;
188 }
189
190private:
191 sk_sp<SkImage> fImage;
192 SkScalar fBlurSigma;
193};
194
195//////////////////////////////////////////////////////////////////////////////
196
197DEF_GM(return new AnimatedImageBlurs;)
SkPoint pos
#define SkScalarSqrt(x)
Definition: SkScalar.h:42
SkTileMode
Definition: SkTileMode.h:13
static const SkScalar kBlurMax
static const SkScalar kBlurAnimationDuration
static const int kNumNodes
static const int kHeight
static const int kWidth
SkISize getISize() override
SkString getName() const override
void onDraw(SkCanvas *canvas) override
bool runAsBench() const override
bool onAnimate(double nanos) override
void onOnceBeforeDraw() override
bool onAnimate(double nanos) override
bool runAsBench() const override
void onDraw(SkCanvas *canvas) override
SkISize getISize() override
SkString getName() const override
void onOnceBeforeDraw() override
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
Definition: SkCanvas.cpp:1705
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
Definition: SkCanvas.cpp:2333
int save()
Definition: SkCanvas.cpp:447
static sk_sp< SkImageFilter > Blur(SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp< SkImageFilter > input, const CropRect &cropRect={})
void setImageFilter(sk_sp< SkImageFilter > imageFilter)
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
bool nextBool()
Definition: SkRandom.h:117
float nextRangeF(float min, float max)
Definition: SkRandom.h:64
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
void setBGColor(SkColor)
Definition: gm.cpp:159
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
#define DEF_GM(CODE)
Definition: gm.h:40
Definition: dart.idl:29
static bool init()
SkRRect rrect
Definition: SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
static float PingPong(double time, float period, float phase, float ends, float mid)
Definition: TimeUtils.h:37
sk_sp< SkImage > GetResourceAsImage(const char *resource)
Definition: DecodeUtils.h:25
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 keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
Definition: update.py:1
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646