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

#include "ColorCodecBench.h"
#include "Resources.h"
#include "SkCodec.h"
#include "SkCodecPriv.h"
#include "SkColorSpace_XYZ.h"
#include "SkColorSpaceXform.h"
#include "SkCommandLineFlags.h"

DEFINE_bool(xform_only, false, "Only time the color xform, do not include the decode time");
DEFINE_bool(srgb,       false, "Convert to srgb dst space");
DEFINE_bool(nonstd,     false, "Convert to non-standard dst space");
DEFINE_bool(half,       false, "Convert to half floats");

ColorCodecBench::ColorCodecBench(const char* name, sk_sp<SkData> encoded)
    : fEncoded(std::move(encoded))
{
    fName.appendf("Color%s", FLAGS_xform_only ? "Xform" : "Codec");
    fName.appendf("_%s", name);
}

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

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

void ColorCodecBench::decodeAndXform() {
#ifdef SK_DEBUG
    SkCodec::Result result =
#endif
    SkCodec::MakeFromData(fEncoded)->getPixels(fDstInfo, fDst.get(), fDstInfo.minRowBytes());
    SkASSERT(SkCodec::kSuccess == result);
}

void ColorCodecBench::xformOnly() {
    std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(fSrcSpace.get(),
                                                                      fDstSpace.get());
    SkASSERT(xform);

    void* dst = fDst.get();
    void* src = fSrc.get();
    for (int y = 0; y < fSrcInfo.height(); y++) {
        SkAssertResult(xform->apply(select_xform_format(fDstInfo.colorType()), dst,
                                    SkColorSpaceXform::kRGBA_8888_ColorFormat, src,
                                    fSrcInfo.width(), fDstInfo.alphaType()));
        dst = SkTAddOffset<void>(dst, fDstInfo.minRowBytes());
        src = SkTAddOffset<void>(src, fSrcInfo.minRowBytes());
    }
}

void ColorCodecBench::onDelayedSetup() {
    std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(fEncoded);
    fSrcInfo = codec->getInfo().makeColorType(kRGBA_8888_SkColorType);
    fDstInfo = fSrcInfo;

    fDstSpace = nullptr;
    if (FLAGS_srgb) {
        fDstSpace = SkColorSpace::MakeSRGB();
    } else if (FLAGS_nonstd) {
        SkColorSpaceTransferFn gamma;
        gamma.fA = 1.0f;
        gamma.fB = gamma.fC = gamma.fD = gamma.fE = gamma.fF = 0.0f;
        gamma.fG = 4.0f;
        SkMatrix44 matrix = SkMatrix44(SkMatrix44::kUninitialized_Constructor);
        matrix.set3x3(0.30f, 0.31f, 0.28f, 0.32f, 0.33f, 0.29f, 0.27f, 0.30f, 0.30f);
        fDstSpace = SkColorSpace::MakeRGB(gamma, matrix);
    } else {
        sk_sp<SkData> dstData = GetResourceAsData("icc_profiles/HP_ZR30w.icc");
        SkASSERT(dstData);
        fDstSpace = SkColorSpace::MakeICC(dstData->data(), dstData->size());
    }
    SkASSERT(fDstSpace);
    fDstInfo = fDstInfo.makeColorSpace(fDstSpace);

    if (FLAGS_half) {
        fDstInfo = fDstInfo.makeColorType(kRGBA_F16_SkColorType);
        fDstSpace = fDstSpace->makeLinearGamma();
    }

    fDst.reset(fDstInfo.computeMinByteSize());

    if (FLAGS_xform_only) {
        fSrc.reset(fSrcInfo.computeMinByteSize());
        fSrcSpace = codec->getInfo().refColorSpace();
        codec->getPixels(fSrcInfo, fSrc.get(), fSrcInfo.minRowBytes());
    }
}

void ColorCodecBench::onDraw(int n, SkCanvas*) {
    for (int i = 0; i < n; i++) {
        if (FLAGS_xform_only) {
            this->xformOnly();
        } else {
            this->decodeAndXform();
        }
    }
}
