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

#ifndef GrSimpleTextureEffect_DEFINED
#define GrSimpleTextureEffect_DEFINED

#include "GrSingleTextureEffect.h"

class GrGLSimpleTextureEffect;
class GrInvariantOutput;

/**
 * The output color of this effect is a modulation of the input color and a sample from a texture.
 * It allows explicit specification of the filtering and wrap modes (GrTextureParams). It can use
 * local coords, positions, or a custom vertex attribute as input texture coords. The input coords
 * can have a matrix applied in the VS in both the local and position cases but not with a custom
 * attribute coords at this time. It will add a varying to input interpolate texture coords to the
 * FS.
 */
class GrSimpleTextureEffect : public GrSingleTextureEffect {
public:
    /* unfiltered, clamp mode */
    static GrFragmentProcessor* Create(GrTexture* tex,
                                       const SkMatrix& matrix,
                                       GrCoordSet coordSet = kLocal_GrCoordSet) {
        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, GrTextureParams::kNone_FilterMode,
                                                  coordSet));
    }

    /* clamp mode */
    static GrFragmentProcessor* Create(GrTexture* tex,
                                       const SkMatrix& matrix,
                                       GrTextureParams::FilterMode filterMode,
                                       GrCoordSet coordSet = kLocal_GrCoordSet) {
        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, filterMode, coordSet));
    }

    static GrFragmentProcessor* Create(GrTexture* tex,
                                       const SkMatrix& matrix,
                                       const GrTextureParams& p,
                                       GrCoordSet coordSet = kLocal_GrCoordSet) {
        return SkNEW_ARGS(GrSimpleTextureEffect, (tex, matrix, p, coordSet));
    }

    virtual ~GrSimpleTextureEffect() {}

    static const char* Name() { return "Texture"; }

    typedef GrGLSimpleTextureEffect GLProcessor;

    virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE;

private:
    GrSimpleTextureEffect(GrTexture* texture,
                          const SkMatrix& matrix,
                          GrTextureParams::FilterMode filterMode,
                          GrCoordSet coordSet)
        : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) {
    }

    GrSimpleTextureEffect(GrTexture* texture,
                          const SkMatrix& matrix,
                          const GrTextureParams& params,
                          GrCoordSet coordSet)
        : GrSingleTextureEffect(texture, matrix, params, coordSet) {
    }

    virtual bool onIsEqual(const GrFragmentProcessor& other) const SK_OVERRIDE { return true; }

    virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE;

    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;

    typedef GrSingleTextureEffect INHERITED;
};

#endif
