/*
* 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"
#include "SkRandom.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.
 *
 * Bench mode draws the same as GM mode but without the comparison almost-circle paths. It also
 * slightly perturbs the blur and circle radii to stress caching of blurred profiles in GPU mode.
 */
class BlurCircles2GM : public skiagm::GM {
public:
    BlurCircles2GM() {
        fAnimRadius = SkAnimTimer::PingPong(0, kRadiusPingPoingPeriod, kRadiusPingPoingShift,
                                            kMinRadius, kMaxRadius);
        fAnimBlurRadius = SkAnimTimer::PingPong(0, kBlurRadiusPingPoingPeriod,
                                                kBlurRadiusPingPoingShift, kMinBlurRadius,
                                                kMaxBlurRadius);
    }

protected:
    bool runAsBench() const override { return true; }

    SkString onShortName() override { return SkString("blurcircles2"); }

    SkISize onISize() override {
        return SkISize::Make(730, 1350);
    }

    void onDraw(SkCanvas* canvas) override {
        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 {
            bool benchMode = this->getMode() == kBench_Mode;
            canvas->save();
            constexpr SkScalar kPad = 5;
            constexpr SkScalar kRadiusSteps = 5;
            constexpr SkScalar kBlurRadiusSteps = 5;
            canvas->translate(kPad + kMinRadius + kMaxBlurRadius,
                              kPad + kMinRadius + kMaxBlurRadius);
            constexpr SkScalar kDeltaRadius = (kMaxRadius - kMinRadius) / kRadiusSteps;
            constexpr SkScalar kDeltaBlurRadius = (kMaxBlurRadius - kMinBlurRadius) /
                                                         kBlurRadiusSteps;
            SkScalar lineWidth = 0;
            if (!benchMode) {
                for (int r = 0; r < kRadiusSteps - 1; ++r) {
                    const SkScalar radius = r * kDeltaRadius + kMinRadius;
                    lineWidth += 2 * (radius + kMaxBlurRadius) + kPad;
                }
            }
            for (int br = 0; br < kBlurRadiusSteps; ++br) {
                SkScalar blurRadius = br * kDeltaBlurRadius + kMinBlurRadius;
                if (benchMode) {
                    blurRadius += fRandom.nextSScalar1() * kDeltaBlurRadius;
                }
                const SkScalar maxRowR = blurRadius + kMaxRadius;
                paint.setMaskFilter(blurMaker(blurRadius));
                canvas->save();
                for (int r = 0; r < kRadiusSteps; ++r) {
                    SkScalar radius = r * kDeltaRadius + kMinRadius;
                    if (benchMode) {
                        radius += fRandom.nextSScalar1() * kDeltaRadius;
                    }
                    SkPath almostCircle;
                    if (!benchMode) {
                        almostCircleMaker(radius, &almostCircle);
                    }
                    canvas->save();
                        canvas->drawCircle(0, 0, radius, paint);
                        canvas->translate(0, 2 * maxRowR + kPad);
                    if (!benchMode) {
                        canvas->drawPath(almostCircle, paint);
                    }
                    canvas->restore();
                    const SkScalar maxColR = radius + kMaxBlurRadius;
                    canvas->translate(maxColR * 2 + kPad, 0);
                }
                canvas->restore();
                if (!benchMode) {
                    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;

    SkRandom    fRandom;

    typedef skiagm::GM INHERITED;
};

DEF_GM(return new BlurCircles2GM();)
