/*
* 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 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 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();)
