diff options
author | bsalomon <bsalomon@google.com> | 2016-05-13 13:48:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-05-13 13:48:48 -0700 |
commit | c67bb575d0393bef8517810c8f7c578804403c61 (patch) | |
tree | 914645228edb45ef513a742548ffa953bf591f1c /gm | |
parent | 2c0aacbfa403dae16c9e4ccad5dcbaa258481663 (diff) |
Add blurcircles2 GM
In GM mode this draws an array of circles with different radii and different blur radii. Below each circle an almost-circle path is drawn with the same blur filter for comparison.
In Sample mode this draws a single circle and almost-circle with animating radius and blur radius.
BUG=skia:5224
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1974353003
Review-Url: https://codereview.chromium.org/1974353003
Diffstat (limited to 'gm')
-rw-r--r-- | gm/SkAnimTimer.h | 17 | ||||
-rw-r--r-- | gm/blurcircles2.cpp | 141 |
2 files changed, 158 insertions, 0 deletions
diff --git a/gm/SkAnimTimer.h b/gm/SkAnimTimer.h index 2c8a723e5b..060de00c2e 100644 --- a/gm/SkAnimTimer.h +++ b/gm/SkAnimTimer.h @@ -104,6 +104,23 @@ public: return SkDoubleToScalar(value); } + /** + * Transitions from ends->mid->ends linearly over period seconds. The phase specifies a phase + * shift in seconds. + */ + SkScalar pingPong(SkScalar period, SkScalar phase, SkScalar ends, SkScalar mid) const { + return PingPong(this->secs(), period, phase, ends, mid); + } + + /** Helper for computing a ping-pong value without a SkAnimTimer object. */ + static SkScalar PingPong(double t, SkScalar period, SkScalar phase, SkScalar ends, + SkScalar mid) { + double value = ::fmod(t + phase, period); + double half = period / 2.0; + double diff = ::fabs(value - half); + return SkDoubleToScalar(ends + (1.0 - diff / half) * (mid - ends)); + } + private: double fBaseTimeNanos; double fCurrTimeNanos; diff --git a/gm/blurcircles2.cpp b/gm/blurcircles2.cpp new file mode 100644 index 0000000000..284c1ab24e --- /dev/null +++ b/gm/blurcircles2.cpp @@ -0,0 +1,141 @@ +/* +* 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 "SkBlurMask.h" +#include "SkBlurMaskFilter.h" +#include "SkCanvas.h" +#include "SkPaint.h" +#include "SkPath.h" +#include "SkString.h" + +/** + * In GM mode this draws an array of circles with different radii and different blur radii. Below + * each circle an almost-circle path is drawn with the same blur filter for comparison. + * + * In Sample mode this draws a single circle and almost-circle with animating radius and blur + * radius. + */ +class BlurCircles2GM : public skiagm::GM { +public: + BlurCircles2GM() { + fAnimRadius = SkAnimTimer::PingPong(0, kRadiusPingPoingPeriod, kRadiusPingPoingShift, + kMinRadius, kMaxRadius); + fAnimBlurRadius = SkAnimTimer::PingPong(0, kBlurRadiusPingPoingPeriod, + kBlurRadiusPingPoingShift, kMinBlurRadius, + kMaxBlurRadius); + } + +protected: + SkString onShortName() override { return SkString("blurcircles2"); } + + SkISize onISize() override { + return SkISize::Make(730, 1350); + } + + void onDraw(SkCanvas* canvas) override { + static constexpr SkScalar kMaxR = kMaxRadius + kMaxBlurRadius; + + auto almostCircleMaker = [] (SkScalar radius, SkPath* dst) { + dst->reset(); + dst->addArc(SkRect::MakeXYWH(-radius, -radius, 2 * radius, 2 * radius), 0, 355); + dst->setIsVolatile(true); + dst->close(); + }; + + auto blurMaker = [] (SkScalar radius) ->sk_sp<SkMaskFilter> { + return SkBlurMaskFilter::Make(kNormal_SkBlurStyle, + SkBlurMask::ConvertRadiusToSigma(radius), + SkBlurMaskFilter::kHighQuality_BlurFlag); + }; + + SkPaint paint; + paint.setColor(SK_ColorBLACK); + + if (this->getMode() == kSample_Mode) { + paint.setMaskFilter(blurMaker(fAnimBlurRadius)); + SkISize size = canvas->getBaseLayerSize(); + SkPath almostCircle; + almostCircleMaker(fAnimRadius, &almostCircle); + canvas->save(); + canvas->translate(size.fWidth / 2.f, size.fHeight / 4.f); + canvas->drawCircle(0, 0, fAnimRadius, paint); + canvas->translate(0, 2 * kMaxR); + canvas->drawPath(almostCircle, paint); + canvas->restore(); + } else { + canvas->save(); + static constexpr SkScalar kPad = 5; + static constexpr SkScalar kRadiusSteps = 5; + static constexpr SkScalar kBlurRadiusSteps = 5; + canvas->translate(kPad + kMinRadius + kMaxBlurRadius, + kPad + kMinRadius + kMaxBlurRadius); + SkScalar lineWidth = 0; + for (int r = 0; r < kRadiusSteps - 1; ++r) { + const SkScalar radius = r * (kMaxRadius - kMinRadius) / kBlurRadiusSteps + + kMinRadius; + lineWidth += 2 * (radius + kMaxBlurRadius) + kPad; + } + for (int br = 0; br < kBlurRadiusSteps; ++br) { + const SkScalar blurRadius = br * (kMaxBlurRadius - kMinBlurRadius) / + kBlurRadiusSteps + kMinBlurRadius; + const SkScalar maxRowR = blurRadius + kMaxRadius; + paint.setMaskFilter(blurMaker(blurRadius)); + canvas->save(); + for (int r = 0; r < kRadiusSteps; ++r) { + const SkScalar radius = r * (kMaxRadius - kMinRadius) / kBlurRadiusSteps + + kMinRadius; + SkPath almostCircle; + almostCircleMaker(radius, &almostCircle); + canvas->save(); + canvas->drawCircle(0, 0, radius, paint); + canvas->translate(0, 2 * maxRowR + kPad); + canvas->drawPath(almostCircle, paint); + canvas->restore(); + const SkScalar maxColR = radius + kMaxBlurRadius; + canvas->translate(maxColR * 2 + kPad, 0); + } + canvas->restore(); + SkPaint blackPaint; + blackPaint.setColor(SK_ColorBLACK); + const SkScalar lineY = 3 * maxRowR + 1.5f * kPad; + if (br != kBlurRadiusSteps - 1) { + canvas->drawLine(0, lineY, lineWidth, lineY, blackPaint); + } + canvas->translate(0, maxRowR * 4 + 2 * kPad); + } + canvas->restore(); + } + } + + bool onAnimate(const SkAnimTimer& timer) override { + fAnimRadius = timer.pingPong(kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius, + kMaxRadius); + fAnimBlurRadius = timer.pingPong(kBlurRadiusPingPoingPeriod, kBlurRadiusPingPoingShift, + kMinBlurRadius, kMaxBlurRadius); + return true; + } + +private: + static constexpr SkScalar kMinRadius = 15; + static constexpr SkScalar kMaxRadius = 45; + static constexpr SkScalar kRadiusPingPoingPeriod = 8; + static constexpr SkScalar kRadiusPingPoingShift = 3; + + static constexpr SkScalar kMinBlurRadius = 5; + static constexpr SkScalar kMaxBlurRadius = 45; + static constexpr SkScalar kBlurRadiusPingPoingPeriod = 3; + static constexpr SkScalar kBlurRadiusPingPoingShift = 1.5; + + SkScalar fAnimRadius; + SkScalar fAnimBlurRadius; + + typedef skiagm::GM INHERITED; +}; + +DEF_GM(return new BlurCircles2GM();) |