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

#include "bench/Benchmark.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkFont.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPath.h"
#include "src/core/SkRandom.h"
#include "src/core/SkStrike.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "tools/ToolUtils.h"
#include "tools/fonts/FontToolUtils.h"

static constexpr int kScreenWidth = 1500;
static constexpr int kScreenHeight = 1500;

static constexpr int kNumDraws = 2000;

// I and l are rects on OS X.
static constexpr char kGlyphs[] =  "ABCDEFGH7JKLMNOPQRSTUVWXYZabcdefghijk1mnopqrstuvwxyz";
static constexpr int kNumGlyphs = sizeof(kGlyphs) - 1;
static_assert(52 == kNumGlyphs, "expected 52 glyphs");

/*
 * This class benchmarks drawing many glyphs at random scales and rotations.
 */
class PathTextBench : public Benchmark {
public:
    PathTextBench(bool clipped, bool uncached) : fClipped(clipped), fUncached(uncached) {}

private:
    const char* onGetName() override {
        fName = "path_text";
        if (fClipped) {
            fName.append("_clipped");
        }
        if (fUncached) {
            fName.append("_uncached");
        }
        return fName.c_str();
    }
    SkISize onGetSize() override { return SkISize::Make(kScreenWidth, kScreenHeight); }

    void onDelayedSetup() override {
        SkFont defaultFont = ToolUtils::DefaultFont();
        SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(defaultFont);
        SkBulkGlyphMetricsAndPaths pathMaker{strikeSpec};
        for (int i = 0; i < kNumGlyphs; ++i) {
            SkGlyphID id(defaultFont.unicharToGlyph(kGlyphs[i]));
            const SkGlyph* glyph = pathMaker.glyph(id);
            if (glyph->path()) {
                fGlyphs[i] = *glyph->path();
            }
            fGlyphs[i].setIsVolatile(fUncached);
        }

        SkRandom rand;
        for (int i = 0; i < kNumDraws; ++i) {
            const SkPath& glyph = fGlyphs[i % kNumGlyphs];
            const SkRect& bounds = glyph.getBounds();
            float glyphSize = std::max(bounds.width(), bounds.height());
            SkASSERT(glyphSize > 0);

            float t0 = pow(rand.nextF(), 100);
            float size = (1 - t0) * std::min(kScreenWidth, kScreenHeight) / 50 +
                         t0 * std::min(kScreenWidth, kScreenHeight) / 3;
            float scale = size / glyphSize;
            float t1 = rand.nextF(), t2 = rand.nextF();
            fXforms[i].setTranslate((1 - t1) * sqrt(2) * scale/2 * glyphSize +
                                     t1 * (kScreenWidth - sqrt(2) * scale/2 * glyphSize),
                                     (1 - t2) * sqrt(2) * scale/2 * glyphSize +
                                     t2 * (kScreenHeight - sqrt(2) * scale/2 * glyphSize));
            fXforms[i].preRotate(rand.nextF() * 360);
            fXforms[i].preTranslate(-scale/2 * bounds.width(), -scale/2 * bounds.height());
            fXforms[i].preScale(scale, scale);
            fPaints[i].setAntiAlias(true);
            fPaints[i].setColor(rand.nextU() | 0x80808080);
        }

        if (fClipped) {
            fClipPath = ToolUtils::make_star(SkRect::MakeIWH(kScreenWidth, kScreenHeight), 11, 3);
            fClipPath.setIsVolatile(fUncached);
        }
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        SkAutoCanvasRestore acr(canvas, true);
        if (fClipped) {
            canvas->clipPath(fClipPath, SkClipOp::kIntersect, true);
        }
        for (int i = 0; i < kNumDraws; ++i) {
            const SkPath& glyph = fGlyphs[i % kNumGlyphs];
            canvas->setMatrix(fXforms[i]);
            canvas->drawPath(glyph, fPaints[i]);
        }
    }

    const bool fClipped;
    const bool fUncached;
    SkString fName;
    SkPath fGlyphs[kNumGlyphs];
    SkPaint fPaints[kNumDraws];
    SkMatrix fXforms[kNumDraws];
    SkPath fClipPath;

    using INHERITED = Benchmark;
};

DEF_BENCH(return new PathTextBench(false, false);)
DEF_BENCH(return new PathTextBench(false, true);)
DEF_BENCH(return new PathTextBench(true, true);)
