/*
 * Copyright 2023 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/SkColorSpace.h"
#include "modules/skcms/skcms.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkRasterPipelineOpContexts.h"
#include "src/core/SkRasterPipelineOpList.h"

#include <functional>

enum class Mode {
    kMultipleImage,  // Transforms multiple images via one pipeline. (skcms doesn't support this.)
    kSingleImage,    // Transforms a single image at a time.
    kSingleScanline, // Transforms an image scanline-by-scanline.
};

static const char* mode_name(Mode m) {
    switch (m) {
        case Mode::kMultipleImage:  return "MultipleImage";
        case Mode::kSingleImage:    return "SingleImage";
        case Mode::kSingleScanline: return "SingleScanline";
        default:                    SkUNREACHABLE;
    }
}

class ColorSpaceTransformBench : public Benchmark {
public:
    ColorSpaceTransformBench(Mode mode) : fMode(mode) {
        fName = std::string("ColorSpace") + mode_name(fMode) + "Transform";
    }

protected:
    const char* onGetName() override {
        return fName.c_str();
    }

    bool isSuitableFor(Backend backend) override {
        return backend == kNonRendering_Backend;
    }

    // Call before draw, allows the benchmark to do setup work outside of the
    // timer. When a benchmark is repeatedly drawn, this should be called once
    // before the initial draw.
    void onDelayedSetup() override {
        // Set the image buffer to solid white.
        std::fill(std::begin(fSrcPixels), std::end(fSrcPixels), 0xFF);

        // Create a conversion from sRGB to Adobe.
        fSRGBCS = SkColorSpace::MakeSRGB();
        fAdobeCS = SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB);

        fXformSteps = SkColorSpaceXformSteps(fSRGBCS.get(),  kPremul_SkAlphaType,
                                             fAdobeCS.get(), kPremul_SkAlphaType);

        // Build up a pipeline.
        fSrcCtx = SkRasterPipeline_MemoryCtx{fSrcPixels, kWidth};
        fDstCtx = SkRasterPipeline_MemoryCtx{fDstPixels, kWidth};

        fPipeline.append(SkRasterPipelineOp::load_8888, &fSrcCtx);
        fXformSteps.apply(&fPipeline);
        fPipeline.append(SkRasterPipelineOp::store_8888, &fDstCtx);

        fConversionPipeline = fPipeline.compile();
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        switch (fMode) {
            case Mode::kMultipleImage:
                for (int i = 0; i < loops; i++) {
                    fConversionPipeline(0, 0, kWidth, kHeight);
                }
                break;

            case Mode::kSingleImage:
                for (int i = 0; i < loops; i++) {
                    fPipeline.run(0, 0, kWidth, kHeight);
                }
                break;

            case Mode::kSingleScanline:
                for (int i = 0; i < loops; i++) {
                    for (int y = 0; y < kHeight; ++y) {
                        fPipeline.run(0, y, kWidth, 1);
                    }
                }
                break;
        }
    }

private:
    using INHERITED = Benchmark;

    Mode fMode;
    std::string fName;

    sk_sp<SkColorSpace> fAdobeCS;
    sk_sp<SkColorSpace> fSRGBCS;

    SkRasterPipeline_<256> fPipeline;
    SkRasterPipeline_MemoryCtx fSrcCtx;
    SkRasterPipeline_MemoryCtx fDstCtx;
    SkColorSpaceXformSteps fXformSteps;

    static constexpr int kWidth = 512;
    static constexpr int kHeight = 512;
    static constexpr int kBytesPerPixel = 4;
    uint8_t fSrcPixels[kWidth * kHeight * kBytesPerPixel];
    uint8_t fDstPixels[kWidth * kHeight * kBytesPerPixel];

    std::function<void(size_t, size_t, size_t, size_t)> fConversionPipeline;
};

class SkcmsTransformBench : public Benchmark {
public:
    SkcmsTransformBench(Mode mode) : fMode(mode) {
        fName = std::string("Skcms") + mode_name(fMode) + "Transform";
    }

protected:
    const char* onGetName() override {
        return fName.c_str();
    }

    bool isSuitableFor(Backend backend) override {
        return backend == kNonRendering_Backend;
    }

    // Call before draw, allows the benchmark to do setup work outside of the
    // timer. When a benchmark is repeatedly drawn, this should be called once
    // before the initial draw.
    void onDelayedSetup() override {
        // Set the image buffer to solid white. NANs/denorms might affect timing, but otherwise it
        // doesn't really matter.
        std::fill(std::begin(fSrcPixels), std::end(fSrcPixels), 0xFF);

        // Create profiles for sRGB to Adobe.
        SkColorSpace::MakeSRGB()->toProfile(&fSRGBProfile);
        SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2,
                              SkNamedGamut::kAdobeRGB)->toProfile(&fAdobeProfile);
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        switch (fMode) {
            case Mode::kMultipleImage:
                SkUNREACHABLE;

            case Mode::kSingleImage:
                for (int i = 0; i < loops; i++) {
                    skcms_Transform(fSrcPixels,
                                    skcms_PixelFormat_RGBA_8888,
                                    skcms_AlphaFormat_PremulAsEncoded,
                                    &fSRGBProfile,
                                    fDstPixels,
                                    skcms_PixelFormat_RGBA_8888,
                                    skcms_AlphaFormat_PremulAsEncoded,
                                    &fAdobeProfile,
                                    kWidth * kHeight);
                }
                break;

            case Mode::kSingleScanline:
                for (int i = 0; i < loops; i++) {
                    uint8_t* src = fSrcPixels;
                    uint8_t* dst = fDstPixels;
                    for (int y = 0; y < kHeight; ++y) {
                        skcms_Transform(src,
                                        skcms_PixelFormat_RGBA_8888,
                                        skcms_AlphaFormat_PremulAsEncoded,
                                        &fSRGBProfile,
                                        dst,
                                        skcms_PixelFormat_RGBA_8888,
                                        skcms_AlphaFormat_PremulAsEncoded,
                                        &fAdobeProfile,
                                        kWidth);
                        src += kWidth * kBytesPerPixel;
                        dst += kWidth * kBytesPerPixel;
                    }
                }
                break;
        }
    }

private:
    using INHERITED = Benchmark;

    Mode fMode;
    std::string fName;

    skcms_ICCProfile fAdobeProfile;
    skcms_ICCProfile fSRGBProfile;

    static constexpr int kWidth = 512;
    static constexpr int kHeight = 512;
    static constexpr int kBytesPerPixel = 4;
    uint8_t fSrcPixels[kWidth * kHeight * kBytesPerPixel];
    uint8_t fDstPixels[kWidth * kHeight * kBytesPerPixel];
};

DEF_BENCH(return new ColorSpaceTransformBench(Mode::kMultipleImage);)
DEF_BENCH(return new ColorSpaceTransformBench(Mode::kSingleImage);)
DEF_BENCH(return new ColorSpaceTransformBench(Mode::kSingleScanline);)
DEF_BENCH(return new SkcmsTransformBench(Mode::kSingleImage);)
DEF_BENCH(return new SkcmsTransformBench(Mode::kSingleScanline);)
