/*
* 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 "AnimTimer.h"
#include "SkBlurMask.h"
#include "SkBlurMaskFilter.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkString.h"
#include "gm.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 = AnimTimer::PingPong(
                0, kRadiusPingPoingPeriod, kRadiusPingPoingShift, kMinRadius, kMaxRadius);
        fAnimBlurRadius = AnimTimer::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 SkMaskFilter::MakeBlur(kNormal_SkBlurStyle,
                                          SkBlurMask::ConvertRadiusToSigma(radius));
        };

        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 AnimTimer& 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();)
