/*
 * 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 "bench/Benchmark.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkGradient.h"
#include "include/effects/SkImageFilters.h"

// Chains several matrix color filters image filter or several
// table filter image filters and draws a bitmap.
// This bench shows an improvement in performance and memory
// when collapsing matrices or tables is implemented since all
// the passes are collapsed in one.

class BaseImageFilterCollapseBench : public Benchmark {
public:
    BaseImageFilterCollapseBench() {}

protected:
    void doPreDraw(sk_sp<SkColorFilter> colorFilters[], int nFilters) {
        SkASSERT(!fImageFilter);

        // Create a chain of ImageFilters from colorFilters
        for(int i = nFilters; i --> 0;) {
            fImageFilter = SkImageFilters::ColorFilter(colorFilters[i], fImageFilter);
        }
    }

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

        for(int i = 0; i < loops; i++) {
            SkPaint paint;
            paint.setImageFilter(fImageFilter);
            canvas->drawImage(fImage, 0, 0, SkSamplingOptions(), &paint);
        }
    }

private:
    sk_sp<SkImageFilter> fImageFilter;
    sk_sp<SkImage> fImage;

    void makeBitmap() {
        int W = 400;
        int H = 400;
        auto surf = SkSurfaces::Raster(SkImageInfo::MakeN32Premul(W, H));

        SkPaint paint;
        SkPoint pts[] = { {0, 0}, {SkIntToScalar(W), SkIntToScalar(H)} };
        SkColor4f colors[] = {
            SkColors::kBlack, SkColors::kGreen, SkColors::kCyan,
            SkColors::kRed, SkColors::kTransparent, SkColors::kBlue, SkColors::kWhite
        };
        paint.setShader(SkShaders::LinearGradient(pts, {{colors, {}, SkTileMode::kClamp}, {}}));
        surf->getCanvas()->drawPaint(paint);
        fImage = surf->makeImageSnapshot();       // shader->makeImage()
    }
};

class TableCollapseBench: public BaseImageFilterCollapseBench {
protected:
    const char* onGetName() override {
        return "image_filter_collapse_table";
    }

    void onDelayedSetup() override {
        for (int i = 0; i < 256; ++i) {
            int n = i >> 5;
            table1[i] = (n << 5) | (n << 2) | (n >> 1);

            table2[i] = i * i / 255;

            float fi = i / 255.0f;
            table3[i] = static_cast<uint8_t>(sqrtf(fi) * 255);
        }

        sk_sp<SkColorFilter> colorFilters[] = {
            SkColorFilters::Table(table1),
            SkColorFilters::Table(table2),
            SkColorFilters::Table(table3),
        };

        this->doPreDraw(colorFilters, std::size(colorFilters));
    }

private:
    uint8_t table1[256], table2[256], table3[256];
};

static sk_sp<SkColorFilter> make_brightness(float amount) {
    SkScalar matrix[20] = { 1, 0, 0, 0, amount,
                            0, 1, 0, 0, amount,
                            0, 0, 1, 0, amount,
                            0, 0, 0, 1, 0 };
    return SkColorFilters::Matrix(matrix);
}

static sk_sp<SkColorFilter> make_grayscale() {
    float matrix[20];
    memset(matrix, 0, 20 * sizeof(float));
    matrix[0] = matrix[5] = matrix[10] = 0.2126f;
    matrix[1] = matrix[6] = matrix[11] = 0.7152f;
    matrix[2] = matrix[7] = matrix[12] = 0.0722f;
    matrix[18] = 1.0f;
    return SkColorFilters::Matrix(matrix);
}

class MatrixCollapseBench: public BaseImageFilterCollapseBench {
protected:
    const char* onGetName() override {
        return "image_filter_collapse_matrix";
    }

    void onDelayedSetup() override {
        sk_sp<SkColorFilter> colorFilters[] = {
            make_brightness(0.1f),
            make_grayscale(),
            make_brightness(-0.1f),
        };

        this->doPreDraw(colorFilters, std::size(colorFilters));
    }
};

DEF_BENCH(return new TableCollapseBench;)
DEF_BENCH(return new MatrixCollapseBench;)
