From c67bb575d0393bef8517810c8f7c578804403c61 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Fri, 13 May 2016 13:48:48 -0700 Subject: 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 --- gm/blurcircles2.cpp | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 gm/blurcircles2.cpp (limited to 'gm/blurcircles2.cpp') 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 { + 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();) -- cgit v1.2.3