/*
 * 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 "GrYUVtoRGBEffect.h"

#include "GrCoordTransform.h"
#include "GrEffect.h"
#include "gl/GrGLEffect.h"
#include "GrTBackendEffectFactory.h"

namespace {

class YUVtoRGBEffect : public GrEffect {
public:
    static GrEffect* Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) {
        return SkNEW_ARGS(YUVtoRGBEffect, (yTexture, uTexture, vTexture));
    }

    static const char* Name() { return "YUV to RGB"; }

    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
        return GrTBackendEffectFactory<YUVtoRGBEffect>::getInstance();
    }

    virtual void getConstantColorComponents(GrColor* color,
                                            uint32_t* validFlags) const SK_OVERRIDE {
        // YUV is opaque
        *color = 0xFF;
        *validFlags = kA_GrColorComponentFlag;
    }

    class GLEffect : public GrGLEffect {
    public:
        // this class always generates the same code.
        static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; }

        GLEffect(const GrBackendEffectFactory& factory,
                 const GrDrawEffect&)
        : INHERITED(factory) {
        }

        virtual void emitCode(GrGLShaderBuilder* builder,
                              const GrDrawEffect&,
                              EffectKey,
                              const char* outputColor,
                              const char* inputColor,
                              const TransformedCoordsArray& coords,
                              const TextureSamplerArray& samplers) SK_OVERRIDE {
            const char* yuvMatrix   = "yuvMatrix";
            builder->fsCodeAppendf("\tconst mat4 %s = mat4(1.0,  0.0,    1.402, -0.701,\n\t\t\t"
                                                          "1.0, -0.344, -0.714,  0.529,\n\t\t\t"
                                                          "1.0,  1.772,  0.0,   -0.886,\n\t\t\t"
                                                          "0.0,  0.0,    0.0,    1.0);\n",
                                   yuvMatrix);
            builder->fsCodeAppendf("\t%s = vec4(\n\t\t", outputColor);
            builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
            builder->fsCodeAppend(".r,\n\t\t");
            builder->fsAppendTextureLookup(samplers[1], coords[0].c_str(), coords[0].type());
            builder->fsCodeAppend(".r,\n\t\t");
            builder->fsAppendTextureLookup(samplers[2], coords[0].c_str(), coords[0].type());
            builder->fsCodeAppendf(".r,\n\t\t1.0) * %s;\n", yuvMatrix);
        }

        typedef GrGLEffect INHERITED;
    };

private:
    YUVtoRGBEffect(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture)
    : fCoordTransform(kLocal_GrCoordSet, MakeDivByTextureWHMatrix(yTexture), yTexture)
    , fYAccess(yTexture)
    , fUAccess(uTexture)
    , fVAccess(vTexture) {
        this->addCoordTransform(&fCoordTransform);
        this->addTextureAccess(&fYAccess);
        this->addTextureAccess(&fUAccess);
        this->addTextureAccess(&fVAccess);
        this->setWillNotUseInputColor();
    }

    virtual bool onIsEqual(const GrEffect& sBase) const {
        const YUVtoRGBEffect& s = CastEffect<YUVtoRGBEffect>(sBase);
        return fYAccess.getTexture() == s.fYAccess.getTexture() &&
               fUAccess.getTexture() == s.fUAccess.getTexture() &&
               fVAccess.getTexture() == s.fVAccess.getTexture();
    }

    GrCoordTransform fCoordTransform;
    GrTextureAccess fYAccess;
    GrTextureAccess fUAccess;
    GrTextureAccess fVAccess;

    typedef GrEffect INHERITED;
};

}

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

GrEffect* GrYUVtoRGBEffect::Create(GrTexture* yTexture, GrTexture* uTexture, GrTexture* vTexture) {
    return YUVtoRGBEffect::Create(yTexture, uTexture, vTexture);
}
