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

#ifndef GrCircleBlurFragmentProcessor_DEFINED
#define GrCircleBlurFragmentProcessor_DEFINED

#include "SkTypes.h"

#if SK_SUPPORT_GPU

#include "GrFragmentProcessor.h"
#include "GrProcessorUnitTest.h"

class GrTextureProvider;

// This FP handles the special case of a blurred circle. It uses a 1D 
// profile that is just rotated about the origin of the circle.
class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
public:
    ~GrCircleBlurFragmentProcessor() override {};

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

    static const GrFragmentProcessor* Create(GrTextureProvider*textureProvider,
                                             const SkRect& circle, float sigma) {
        float offset;

        SkAutoTUnref<GrTexture> blurProfile(CreateCircleBlurProfileTexture(textureProvider,
                                                                           circle,
                                                                           sigma,
                                                                           &offset));
        if (!blurProfile) {
           return nullptr;
        }
        return new GrCircleBlurFragmentProcessor(circle, sigma, offset, blurProfile);
    }

    const SkRect& circle() const { return fCircle; }
    float sigma() const { return fSigma; }
    float offset() const { return fOffset; }
    int profileSize() const { return fBlurProfileAccess.getTexture()->width(); }

private:
    GrCircleBlurFragmentProcessor(const SkRect& circle, float sigma,
                                  float offset, GrTexture* blurProfile);

    GrGLFragmentProcessor* onCreateGLInstance() const override;

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

    bool onIsEqual(const GrFragmentProcessor& other) const override {
        const GrCircleBlurFragmentProcessor& cbfp = other.cast<GrCircleBlurFragmentProcessor>();
        // fOffset is computed from the circle width and the sigma
        return this->circle().width() == cbfp.circle().width() && fSigma == cbfp.fSigma;    
    }

    void onComputeInvariantOutput(GrInvariantOutput* inout) const override;

    static GrTexture* CreateCircleBlurProfileTexture(GrTextureProvider*,
                                                     const SkRect& circle,
                                                     float sigma, float* offset);

    SkRect              fCircle;
    float               fSigma;
    float               fOffset;
    GrTextureAccess     fBlurProfileAccess;

    GR_DECLARE_FRAGMENT_PROCESSOR_TEST;

    typedef GrFragmentProcessor INHERITED;
};

#endif
#endif
