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

#include "Benchmark.h"
#include "SkCanvas.h"
#include "SkLayerDrawLooper.h"
#include "SkMaskFilter.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRandom.h"

// This bench replicates a problematic use case of a draw looper used
// to create an inner blurred rect
class RectoriBench : public Benchmark {
public:
    RectoriBench() {}

protected:

    const char* onGetName() override {
        return "rectori";
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkRandom Random;

        for (int i = 0; i < loops; i++) {
            SkScalar blurSigma = Random.nextRangeScalar(1.5f, 25.0f);
            SkScalar size = Random.nextRangeScalar(20*blurSigma, 50*blurSigma);

            SkScalar x = Random.nextRangeScalar(0.0f, W - size);
            SkScalar y = Random.nextRangeScalar(0.0f, H - size);

            SkRect inner = { x, y, x + size, y + size };

            SkRect outer(inner);
            // outer is always outset either 2x or 4x the blur radius (we go with 2x)
            outer.outset(2*blurSigma, 2*blurSigma);

            SkPath p;

            p.addRect(outer);
            p.addRect(inner);
            p.setFillType(SkPath::kEvenOdd_FillType);

            // This will be used to translate the normal draw outside the
            // clip rect and translate the blurred version back inside
            SkScalar translate = 2.0f * size;

            SkPaint paint;
            paint.setLooper(this->createLooper(-translate, blurSigma));
            paint.setColor(0xff000000 | Random.nextU());
            paint.setAntiAlias(true);

            canvas->save();
            // clip always equals inner rect so we get the inside blur
            canvas->clipRect(inner);
            canvas->translate(translate, 0);
            canvas->drawPath(p, paint);
            canvas->restore();
        }
    }

private:
    enum {
        W = 640,
        H = 480,
    };

    sk_sp<SkDrawLooper> createLooper(SkScalar xOff, SkScalar sigma) {
        SkLayerDrawLooper::Builder looperBuilder;

        //-----------------------------------------------
        SkLayerDrawLooper::LayerInfo info;

        // TODO: add a color filter to better match what is seen in the wild
        info.fPaintBits = /* SkLayerDrawLooper::kColorFilter_Bit |*/
                          SkLayerDrawLooper::kMaskFilter_Bit;
        info.fColorMode = SkBlendMode::kDst;
        info.fOffset.set(xOff, 0);
        info.fPostTranslate = false;

        SkPaint* paint = looperBuilder.addLayer(info);

        paint->setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, sigma));

        //-----------------------------------------------
        info.fPaintBits = 0;
        info.fOffset.set(0, 0);

        paint = looperBuilder.addLayer(info);
        return looperBuilder.detach();
    }

    typedef Benchmark INHERITED;
};

DEF_BENCH(return new RectoriBench();)
