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

#include "SkColorMatrixFilterRowMajor255.h"
#include "SkColorData.h"
#include "SkNx.h"
#include "SkRasterPipeline.h"
#include "SkReadBuffer.h"
#include "SkRefCnt.h"
#include "SkString.h"
#include "SkUnPreMultiply.h"
#include "SkWriteBuffer.h"

static void transpose_and_scale01(float dst[20], const float src[20]) {
    const float* srcR = src + 0;
    const float* srcG = src + 5;
    const float* srcB = src + 10;
    const float* srcA = src + 15;

    for (int i = 0; i < 16; i += 4) {
        dst[i + 0] = *srcR++;
        dst[i + 1] = *srcG++;
        dst[i + 2] = *srcB++;
        dst[i + 3] = *srcA++;
    }
    // Might as well scale these translates down to [0,1] here instead of every filter call.
    dst[16] = *srcR * (1/255.0f);
    dst[17] = *srcG * (1/255.0f);
    dst[18] = *srcB * (1/255.0f);
    dst[19] = *srcA * (1/255.0f);
}

void SkColorMatrixFilterRowMajor255::initState() {
    transpose_and_scale01(fTranspose, fMatrix);

    const float* array = fMatrix;

    // check if we have to munge Alpha
    bool changesAlpha = (array[15] || array[16] || array[17] || (array[18] - 1) || array[19]);
    bool usesAlpha = (array[3] || array[8] || array[13]);

    if (changesAlpha || usesAlpha) {
        fFlags = changesAlpha ? 0 : kAlphaUnchanged_Flag;
    } else {
        fFlags = kAlphaUnchanged_Flag;
    }
}

///////////////////////////////////////////////////////////////////////////////

SkColorMatrixFilterRowMajor255::SkColorMatrixFilterRowMajor255(const SkScalar array[20]) {
    memcpy(fMatrix, array, 20 * sizeof(SkScalar));
    this->initState();
}

uint32_t SkColorMatrixFilterRowMajor255::getFlags() const {
    return this->INHERITED::getFlags() | fFlags;
}

///////////////////////////////////////////////////////////////////////////////

void SkColorMatrixFilterRowMajor255::flatten(SkWriteBuffer& buffer) const {
    SkASSERT(sizeof(fMatrix)/sizeof(SkScalar) == 20);
    buffer.writeScalarArray(fMatrix, 20);
}

sk_sp<SkFlattenable> SkColorMatrixFilterRowMajor255::CreateProc(SkReadBuffer& buffer) {
    SkScalar matrix[20];
    if (buffer.readScalarArray(matrix, 20)) {
        return sk_make_sp<SkColorMatrixFilterRowMajor255>(matrix);
    }
    return nullptr;
}

bool SkColorMatrixFilterRowMajor255::asColorMatrix(SkScalar matrix[20]) const {
    if (matrix) {
        memcpy(matrix, fMatrix, 20 * sizeof(SkScalar));
    }
    return true;
}

///////////////////////////////////////////////////////////////////////////////
//  This code was duplicated from src/effects/SkColorMatrix.cpp in order to be used in core.
//////

// To detect if we need to apply clamping after applying a matrix, we check if
// any output component might go outside of [0, 255] for any combination of
// input components in [0..255].
// Each output component is an affine transformation of the input component, so
// the minimum and maximum values are for any combination of minimum or maximum
// values of input components (i.e. 0 or 255).
// E.g. if R' = x*R + y*G + z*B + w*A + t
// Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the
// minimum value will be for R=0 if x>0 or R=255 if x<0.
// Same goes for all components.
static bool component_needs_clamping(const SkScalar row[5]) {
    SkScalar maxValue = row[4] / 255;
    SkScalar minValue = row[4] / 255;
    for (int i = 0; i < 4; ++i) {
        if (row[i] > 0)
            maxValue += row[i];
        else
            minValue += row[i];
    }
    return (maxValue > 1) || (minValue < 0);
}

static bool needs_clamping(const SkScalar matrix[20]) {
    return component_needs_clamping(matrix)
        || component_needs_clamping(matrix+5)
        || component_needs_clamping(matrix+10)
        || component_needs_clamping(matrix+15);
}

static void set_concat(SkScalar result[20], const SkScalar outer[20], const SkScalar inner[20]) {
    int index = 0;
    for (int j = 0; j < 20; j += 5) {
        for (int i = 0; i < 4; i++) {
            result[index++] =   outer[j + 0] * inner[i + 0] +
                                outer[j + 1] * inner[i + 5] +
                                outer[j + 2] * inner[i + 10] +
                                outer[j + 3] * inner[i + 15];
        }
        result[index++] =   outer[j + 0] * inner[4] +
                            outer[j + 1] * inner[9] +
                            outer[j + 2] * inner[14] +
                            outer[j + 3] * inner[19] +
                            outer[j + 4];
    }
}

///////////////////////////////////////////////////////////////////////////////
//  End duplication
//////

void SkColorMatrixFilterRowMajor255::onAppendStages(SkRasterPipeline* p,
                                                    SkColorSpace* dst,
                                                    SkArenaAlloc* scratch,
                                                    bool shaderIsOpaque) const {
    bool willStayOpaque = shaderIsOpaque && (fFlags & kAlphaUnchanged_Flag);
    bool needsClamp0 = false,
         needsClamp1 = false;
    for (int i = 0; i < 4; i++) {
        SkScalar min = fTranspose[i+16],
                 max = fTranspose[i+16];
        (fTranspose[i+ 0] < 0 ? min : max) += fTranspose[i+ 0];
        (fTranspose[i+ 4] < 0 ? min : max) += fTranspose[i+ 4];
        (fTranspose[i+ 8] < 0 ? min : max) += fTranspose[i+ 8];
        (fTranspose[i+12] < 0 ? min : max) += fTranspose[i+12];
        needsClamp0 = needsClamp0 || min < 0;
        needsClamp1 = needsClamp1 || max > 1;
    }

    if (!shaderIsOpaque) { p->append(SkRasterPipeline::unpremul); }
    if (           true) { p->append(SkRasterPipeline::matrix_4x5, fTranspose); }
    if (    needsClamp0) { p->append(SkRasterPipeline::clamp_0); }
    if (    needsClamp1) { p->append(SkRasterPipeline::clamp_1); }
    if (!willStayOpaque) { p->append(SkRasterPipeline::premul); }
}

sk_sp<SkColorFilter>
SkColorMatrixFilterRowMajor255::onMakeComposed(sk_sp<SkColorFilter> innerFilter) const {
    SkScalar innerMatrix[20];
    if (innerFilter->asColorMatrix(innerMatrix) && !needs_clamping(innerMatrix)) {
        SkScalar concat[20];
        set_concat(concat, fMatrix, innerMatrix);
        return sk_make_sp<SkColorMatrixFilterRowMajor255>(concat);
    }
    return nullptr;
}

#if SK_SUPPORT_GPU
#include "GrFragmentProcessor.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
#include "glsl/GrGLSLUniformHandler.h"

class ColorMatrixEffect : public GrFragmentProcessor {
public:
    static std::unique_ptr<GrFragmentProcessor> Make(const SkScalar matrix[20]) {
        return std::unique_ptr<GrFragmentProcessor>(new ColorMatrixEffect(matrix));
    }

    const char* name() const override { return "Color Matrix"; }

    GR_DECLARE_FRAGMENT_PROCESSOR_TEST

    std::unique_ptr<GrFragmentProcessor> clone() const override { return Make(fMatrix); }

private:
    class GLSLProcessor : public GrGLSLFragmentProcessor {
    public:
        // this class always generates the same code.
        static void GenKey(const GrProcessor&, const GrShaderCaps&, GrProcessorKeyBuilder*) {}

        void emitCode(EmitArgs& args) override {
            GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
            fMatrixHandle = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4x4_GrSLType,
                                                       "ColorMatrix");
            fVectorHandle = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
                                                       "ColorMatrixVector");

            GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder;
            // The max() is to guard against 0 / 0 during unpremul when the incoming color is
            // transparent black.
            fragBuilder->codeAppendf("\thalf nonZeroAlpha = max(%s.a, 0.00001);\n",
                                     args.fInputColor);
            fragBuilder->codeAppendf("\t%s = %s * half4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + "
                                     "%s;\n",
                                     args.fOutputColor,
                                     uniformHandler->getUniformCStr(fMatrixHandle),
                                     args.fInputColor,
                                     uniformHandler->getUniformCStr(fVectorHandle));
            fragBuilder->codeAppendf("\t%s = saturate(%s);\n",
                                     args.fOutputColor, args.fOutputColor);
            fragBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, args.fOutputColor);
        }

    protected:
        void onSetData(const GrGLSLProgramDataManager& uniManager,
                       const GrFragmentProcessor& proc) override {
            const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>();
            const float* m = cme.fMatrix;
            // The GL matrix is transposed from SkColorMatrix.
            float mt[]  = {
                m[0], m[5], m[10], m[15],
                m[1], m[6], m[11], m[16],
                m[2], m[7], m[12], m[17],
                m[3], m[8], m[13], m[18],
            };
            static const float kScale = 1.0f / 255.0f;
            float vec[] = {
                m[4] * kScale, m[9] * kScale, m[14] * kScale, m[19] * kScale,
            };
            uniManager.setMatrix4fv(fMatrixHandle, 1, mt);
            uniManager.set4fv(fVectorHandle, 1, vec);
        }

    private:
        GrGLSLProgramDataManager::UniformHandle fMatrixHandle;
        GrGLSLProgramDataManager::UniformHandle fVectorHandle;

        typedef GrGLSLFragmentProcessor INHERITED;
    };

    // We could implement the constant input->constant output optimization but haven't. Other
    // optimizations would be matrix-dependent.
    ColorMatrixEffect(const SkScalar matrix[20])
    : INHERITED(kColorMatrixEffect_ClassID, kNone_OptimizationFlags) {
        memcpy(fMatrix, matrix, sizeof(SkScalar) * 20);
    }

    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
        return new GLSLProcessor;
    }

    virtual void onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                       GrProcessorKeyBuilder* b) const override {
        GLSLProcessor::GenKey(*this, caps, b);
    }

    bool onIsEqual(const GrFragmentProcessor& s) const override {
        const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>();
        return 0 == memcmp(fMatrix, cme.fMatrix, sizeof(fMatrix));
    }

    SkScalar fMatrix[20];

    typedef GrFragmentProcessor INHERITED;
};

GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect);

#if GR_TEST_UTILS
std::unique_ptr<GrFragmentProcessor> ColorMatrixEffect::TestCreate(GrProcessorTestData* d) {
    SkScalar colorMatrix[20];
    for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix); ++i) {
        colorMatrix[i] = d->fRandom->nextSScalar1();
    }
    return ColorMatrixEffect::Make(colorMatrix);
}

#endif

std::unique_ptr<GrFragmentProcessor> SkColorMatrixFilterRowMajor255::asFragmentProcessor(
        GrContext*, const GrColorSpaceInfo&) const {
    return ColorMatrixEffect::Make(fMatrix);
}

#endif

///////////////////////////////////////////////////////////////////////////////

sk_sp<SkColorFilter> SkColorFilter::MakeMatrixFilterRowMajor255(const SkScalar array[20]) {
    if (!SkScalarsAreFinite(array, 20)) {
        return nullptr;
    }

    return sk_sp<SkColorFilter>(new SkColorMatrixFilterRowMajor255(array));
}

///////////////////////////////////////////////////////////////////////////////

sk_sp<SkColorFilter>
SkColorMatrixFilterRowMajor255::MakeSingleChannelOutput(const SkScalar row[5]) {
    if (!SkScalarsAreFinite(row, 5)) {
        return nullptr;
    }

    SkASSERT(row);
    auto cf = sk_make_sp<SkColorMatrixFilterRowMajor255>();
    static_assert(sizeof(SkScalar) * 5 * 4 == sizeof(cf->fMatrix), "sizes don't match");
    for (int i = 0; i < 4; ++i) {
        memcpy(cf->fMatrix + 5 * i, row, sizeof(SkScalar) * 5);
    }
    cf->initState();
    return std::move(cf);
}
