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

#ifndef GrConvolutionEffect_DEFINED
#define GrConvolutionEffect_DEFINED

#include "Gr1DKernelEffect.h"
#include "GrInvariantOutput.h"

/**
 * A convolution effect. The kernel is specified as an array of 2 * half-width
 * + 1 weights. Each texel is multiplied by it's weight and summed to determine
 * the output color. The output color is modulated by the input color.
 */
class GrConvolutionEffect : public Gr1DKernelEffect {

public:

    /// Convolve with an arbitrary user-specified kernel
    static GrFragmentProcessor* Create(GrProcessorDataManager* procDataManager,
                                       GrTexture* tex,
                                       Direction dir,
                                       int halfWidth,
                                       const float* kernel,
                                       bool useBounds,
                                       float bounds[2]) {
        return SkNEW_ARGS(GrConvolutionEffect, (procDataManager,
                                                tex,
                                                dir,
                                                halfWidth,
                                                kernel,
                                                useBounds,
                                                bounds));
    }

    /// Convolve with a Gaussian kernel
    static GrFragmentProcessor* CreateGaussian(GrProcessorDataManager* procDataManager,
                                               GrTexture* tex,
                                               Direction dir,
                                               int halfWidth,
                                               float gaussianSigma,
                                               bool useBounds,
                                               float bounds[2]) {
        return SkNEW_ARGS(GrConvolutionEffect, (procDataManager,
                                                tex,
                                                dir,
                                                halfWidth,
                                                gaussianSigma,
                                                useBounds,
                                                bounds));
    }

    virtual ~GrConvolutionEffect();

    const float* kernel() const { return fKernel; }

    const float* bounds() const { return fBounds; }
    bool useBounds() const { return fUseBounds; }

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

    enum {
        // This was decided based on the min allowed value for the max texture
        // samples per fragment program run in DX9SM2 (32). A sigma param of 4.0
        // on a blur filter gives a kernel width of 25 while a sigma of 5.0
        // would exceed a 32 wide kernel.
        kMaxKernelRadius = 12,
        // With a C++11 we could have a constexpr version of WidthFromRadius()
        // and not have to duplicate this calculation.
        kMaxKernelWidth = 2 * kMaxKernelRadius + 1,
    };

protected:

    float fKernel[kMaxKernelWidth];
    bool fUseBounds;
    float fBounds[2];

private:
    GrConvolutionEffect(GrProcessorDataManager*,
                        GrTexture*, Direction,
                        int halfWidth,
                        const float* kernel,
                        bool useBounds,
                        float bounds[2]);

    /// Convolve with a Gaussian kernel
    GrConvolutionEffect(GrProcessorDataManager*,
                        GrTexture*, Direction,
                        int halfWidth,
                        float gaussianSigma,
                        bool useBounds,
                        float bounds[2]);

    GrGLFragmentProcessor* onCreateGLInstance() const override;

    void onGetGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;

    bool onIsEqual(const GrFragmentProcessor&) const override;

    void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
        // If the texture was opaque we could know that the output color if we knew the sum of the
        // kernel values.
        inout->mulByUnknownFourComponents();
    }

    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;

    typedef Gr1DKernelEffect INHERITED;
};

#endif
