/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include "gm/gm.h"
#include "include/core/SkBlurTypes.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkMaskFilter.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkTypes.h"
#include "src/core/SkBlurMask.h"

class BlurCirclesGM : public skiagm::GM {
public:
    BlurCirclesGM() { }

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

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

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

    void onOnceBeforeDraw() override {
        const float blurRadii[kNumBlurs] = {1.f, 5.f, 10.f, 20.f};

        for (int i = 0; i < kNumBlurs; ++i) {
            fBlurFilters[i] = SkMaskFilter::MakeBlur(
                                    kNormal_SkBlurStyle,
                                    SkBlurMask::ConvertRadiusToSigma(blurRadii[i]));
        }
    }

    void onDraw(SkCanvas* canvas) override {
        canvas->scale(1.5f, 1.5f);
        canvas->translate(50,50);

        const float circleRadii[] = {5.f, 10.f, 25.f, 50.f};

        for (size_t i = 0; i < kNumBlurs; ++i) {
            SkAutoCanvasRestore autoRestore(canvas, true);
            canvas->translate(0, 150.f*i);
            for (size_t j = 0; j < SK_ARRAY_COUNT(circleRadii); ++j) {
                SkPaint paint;
                paint.setColor(SK_ColorBLACK);
                paint.setMaskFilter(fBlurFilters[i]);

                static constexpr SkPoint kCenter = {50.f, 50.f};
                // Throw a rotation in the mix to make sure GPU fast path handles it correctly.
                canvas->save();
                canvas->rotate(j*22.f, kCenter.fX, kCenter.fY);
                canvas->drawCircle(kCenter, circleRadii[j], paint);
                canvas->restore();
                canvas->translate(150.f, 0.f);
            }
        }
    }
private:
    static constexpr int kNumBlurs = 4;

    sk_sp<SkMaskFilter> fBlurFilters[kNumBlurs];

    using INHERITED =         skiagm::GM;
};

DEF_GM(return new BlurCirclesGM();)
