diff --git a/gm/animatedimageblurs.cpp b/gm/animatedimageblurs.cpp new file mode 100644 index 0000000000..db8f55b544 --- /dev/null +++ b/gm/animatedimageblurs.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gm.h" +#include "SkAnimTimer.h" +#include "SkBlurImageFilter.h" +#include "SkRandom.h" +#include "SkRRect.h" + +static const SkScalar kBlurMax = 7.0f; +static const int kNumNodes = 30; +static const int kWidth = 512; +static const int kHeight = 512; +static const SkScalar kBlurAnimationDuration = 4.0f; // in secs + +// This GM draws a lot of layers with animating BlurImageFilters +class AnimatedImageBlurs : public skiagm::GM { +public: + AnimatedImageBlurs() : fLastTime(0.0f) { + this->setBGColor(sk_tool_utils::color_to_565(0xFFCCCCCC)); + } + +protected: + bool runAsBench() const override { return true; } + + SkString onShortName() override { return SkString("animated-image-blurs"); } + + SkISize onISize() override { return SkISize::Make(kWidth, kHeight); } + + void onOnceBeforeDraw() override { + for (int i = 0; i < kNumNodes; ++i) { + fNodes[i].init(&fRand); + } + } + + void onDraw(SkCanvas* canvas) override { + SkPaint paint; + paint.setAntiAlias(true); + + for (int i = 0; i < kNumNodes; ++i) { + SkPaint layerPaint; + layerPaint.setImageFilter(SkBlurImageFilter::Make(fNodes[i].sigma(), + fNodes[i].sigma(), + nullptr)); + + canvas->saveLayer(nullptr, &layerPaint); + // The rect is outset to block the circle case + SkRect rect = SkRect::MakeLTRB(fNodes[i].pos().fX - fNodes[i].size()-0.5f, + fNodes[i].pos().fY - fNodes[i].size()-0.5f, + fNodes[i].pos().fX + fNodes[i].size()+0.5f, + fNodes[i].pos().fY + fNodes[i].size()+0.5f); + SkRRect rrect = SkRRect::MakeRectXY(rect, fNodes[i].size(), fNodes[i].size()); + canvas->drawRRect(rrect, paint); + canvas->restore(); + } + } + + bool onAnimate(const SkAnimTimer& timer) override { + if (0.0f != fLastTime) { + for (int i = 0; i < kNumNodes; ++i) { + fNodes[i].update(timer, fLastTime); + } + } + + fLastTime = timer.secs(); + return true; + } + +private: + class Node { + public: + Node() + : fSize(0.0f) + , fPos { 0.0f, 0.0f } + , fDir { 1.0f, 0.0f } + , fBlurOffset(0.0f) + , fBlur(fBlurOffset) + , fSpeed(0.0f) { + } + + void init(SkRandom* rand) { + fSize = rand->nextRangeF(10.0f, 60.f); + fPos.fX = rand->nextRangeF(fSize, kWidth - fSize); + fPos.fY = rand->nextRangeF(fSize, kHeight - fSize); + fDir.fX = rand->nextRangeF(-1.0f, 1.0f); + fDir.fY = SkScalarSqrt(1.0f - fDir.fX * fDir.fX); + if (rand->nextBool()) { + fDir.fY = -fDir.fY; + } + fBlurOffset = rand->nextRangeF(0.0f, kBlurMax); + fBlur = fBlurOffset; + fSpeed = rand->nextRangeF(20.0f, 60.0f); + } + + void update(const SkAnimTimer& timer, SkScalar lastTime) { + + SkScalar deltaTime = timer.secs() - lastTime; + + fPos.fX += deltaTime * fSpeed * fDir.fX; + fPos.fY += deltaTime * fSpeed * fDir.fY; + if (fPos.fX >= kWidth || fPos.fX < 0.0f) { + fPos.fX = SkTPin(fPos.fX, 0.0f, kWidth); + fDir.fX = -fDir.fX; + } + if (fPos.fY >= kHeight || fPos.fY < 0.0f) { + fPos.fY = SkTPin(fPos.fY, 0.0f, kHeight); + fDir.fY = -fDir.fY; + } + + fBlur = timer.pingPong(kBlurAnimationDuration, fBlurOffset, 0.0f, kBlurMax); + } + + SkScalar sigma() const { return fBlur; } + const SkPoint& pos() const { return fPos; } + SkScalar size() const { return fSize; } + + private: + SkScalar fSize; + SkPoint fPos; + SkVector fDir; + SkScalar fBlurOffset; + SkScalar fBlur; + SkScalar fSpeed; + }; + + Node fNodes[kNumNodes]; + SkRandom fRand; + SkScalar fLastTime; + + typedef GM INHERITED; +}; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new AnimatedImageBlurs;) diff --git a/gn/gm.gni b/gn/gm.gni index 4732e0368d..66bc3aa1ae 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -15,6 +15,7 @@ gm_sources = [ "$_gm/all_bitmap_configs.cpp", "$_gm/alphagradients.cpp", "$_gm/animatedGif.cpp", + "$_gm/animatedimageblurs.cpp", "$_gm/anisotropic.cpp", "$_gm/annotated_text.cpp", "$_gm/arcofzorro.cpp",