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

#ifndef GrGLSLColorSpaceXformHelper_DEFINED
#define GrGLSLColorSpaceXformHelper_DEFINED

#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/gpu/GrColorSpaceXform.h"
#include "src/gpu/glsl/GrGLSLUniformHandler.h"

/**
 * Helper class to assist with using GrColorSpaceXform within an FP. This manages all of the
 * uniforms needed, and can be passed to shader builder functions to automatically generate the
 * correct color space transformation code.
 */
class GrGLSLColorSpaceXformHelper : public SkNoncopyable {
public:
    GrGLSLColorSpaceXformHelper() {
        memset(&fFlags, 0, sizeof(fFlags));
    }

    void emitCode(GrGLSLUniformHandler* uniformHandler, const GrColorSpaceXform* colorSpaceXform,
                  uint32_t visibility = kFragment_GrShaderFlag) {
        SkASSERT(uniformHandler);
        if (colorSpaceXform) {
            fFlags = colorSpaceXform->fSteps.flags;
            if (this->applySrcTF()) {
                fSrcTFVar = uniformHandler->addUniformArray(visibility, kHalf_GrSLType,
                                                            "SrcTF", kNumTransferFnCoeffs);
                fSrcTFKind = classify_transfer_fn(colorSpaceXform->fSteps.srcTF);
            }
            if (this->applyGamutXform()) {
                fGamutXformVar = uniformHandler->addUniform(visibility, kHalf3x3_GrSLType,
                                                            "ColorXform");
            }
            if (this->applyDstTF()) {
                fDstTFVar = uniformHandler->addUniformArray(visibility, kHalf_GrSLType,
                                                            "DstTF", kNumTransferFnCoeffs);
                fDstTFKind = classify_transfer_fn(colorSpaceXform->fSteps.dstTFInv);
            }
        }
    }

    void setData(const GrGLSLProgramDataManager& pdman, const GrColorSpaceXform* colorSpaceXform) {
        if (this->applySrcTF()) {
            pdman.set1fv(fSrcTFVar, kNumTransferFnCoeffs, &colorSpaceXform->fSteps.srcTF.g);
        }
        if (this->applyGamutXform()) {
            pdman.setMatrix3f(fGamutXformVar, colorSpaceXform->fSteps.src_to_dst_matrix);
        }
        if (this->applyDstTF()) {
            pdman.set1fv(fDstTFVar, kNumTransferFnCoeffs, &colorSpaceXform->fSteps.dstTFInv.g);
        }
    }

    bool isNoop() const { return (0 == fFlags.mask()); }

    bool applyUnpremul() const   { return fFlags.unpremul; }
    bool applySrcTF() const      { return fFlags.linearize; }
    bool applyGamutXform() const { return fFlags.gamut_transform; }
    bool applyDstTF() const      { return fFlags.encode; }
    bool applyPremul() const     { return fFlags.premul; }

    TFKind srcTFKind() const { return fSrcTFKind; }
    TFKind dstTFKind() const { return fDstTFKind; }

    GrGLSLProgramDataManager::UniformHandle srcTFUniform() const { return fSrcTFVar; }
    GrGLSLProgramDataManager::UniformHandle gamutXformUniform() const { return fGamutXformVar; }
    GrGLSLProgramDataManager::UniformHandle dstTFUniform() const { return fDstTFVar; }

private:
    static const int kNumTransferFnCoeffs = 7;

    GrGLSLProgramDataManager::UniformHandle fSrcTFVar;
    GrGLSLProgramDataManager::UniformHandle fGamutXformVar;
    GrGLSLProgramDataManager::UniformHandle fDstTFVar;
    SkColorSpaceXformSteps::Flags fFlags;
    TFKind fSrcTFKind;
    TFKind fDstTFKind;
};

#endif
