/*
 * 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/SkImageFilter.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkGradientShader.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)} };
        SkColor colors[] = {
            SK_ColorBLACK, SK_ColorGREEN, SK_ColorCYAN,
            SK_ColorRED, 0, SK_ColorBLUE, SK_ColorWHITE
        };
        paint.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, std::size(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;)
