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

/**************************************************************************************************
 *** This file was autogenerated from GrMixerEffect.fp; do not modify.
 **************************************************************************************************/
#ifndef GrMixerEffect_DEFINED
#define GrMixerEffect_DEFINED

#include "include/core/SkM44.h"
#include "include/core/SkTypes.h"

#include "src/gpu/GrCoordTransform.h"
#include "src/gpu/GrFragmentProcessor.h"

class GrMixerEffect : public GrFragmentProcessor {
public:
    static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
                                      const std::unique_ptr<GrFragmentProcessor>& fp1) {
        auto flags = ProcessorOptimizationFlags(fp0.get());
        if (fp1) {
            flags &= ProcessorOptimizationFlags(fp1.get());
        }
        return flags;
    }

    SkPMColor4f constantOutputForConstantInput(const SkPMColor4f& input) const override {
        const auto c0 = ConstantOutputForConstantInput(this->childProcessor(0), input),
                   c1 = (this->numChildProcessors() > 1)
                                ? ConstantOutputForConstantInput(this->childProcessor(1), input)
                                : input;
        return {c0.fR + (c1.fR - c0.fR) * weight, c0.fG + (c1.fG - c0.fG) * weight,
                c0.fB + (c1.fB - c0.fB) * weight, c0.fA + (c1.fA - c0.fA) * weight};
    }
    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> fp0,
                                                     std::unique_ptr<GrFragmentProcessor> fp1,
                                                     float weight) {
        return std::unique_ptr<GrFragmentProcessor>(
                new GrMixerEffect(std::move(fp0), std::move(fp1), weight));
    }
    GrMixerEffect(const GrMixerEffect& src);
    std::unique_ptr<GrFragmentProcessor> clone() const override;
    const char* name() const override { return "MixerEffect"; }
    int fp0_index = -1;
    int fp1_index = -1;
    float weight;

private:
    GrMixerEffect(std::unique_ptr<GrFragmentProcessor> fp0,
                  std::unique_ptr<GrFragmentProcessor> fp1,
                  float weight)
            : INHERITED(kGrMixerEffect_ClassID, (OptimizationFlags)OptFlags(fp0, fp1))
            , weight(weight) {
        SkASSERT(fp0);
        fp0_index = this->registerChild(std::move(fp0));
        if (fp1) {
            fp1_index = this->registerChild(std::move(fp1));
        }
    }
    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
    bool onIsEqual(const GrFragmentProcessor&) const override;
    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
    typedef GrFragmentProcessor INHERITED;
};
#endif
