/*
 * 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 "SkTypes.h"
#include "GrFragmentProcessor.h"
#include "GrCoordTransform.h"
class GrMixerEffect : public GrFragmentProcessor {
public:
    static OptimizationFlags OptFlags(const std::unique_ptr<GrFragmentProcessor>& fp0,
                                      const std::unique_ptr<GrFragmentProcessor>& fp1) {
        auto get_flags = [](const std::unique_ptr<GrFragmentProcessor>& fp) {
            auto flags = kNone_OptimizationFlags;

            if (fp->compatibleWithCoverageAsAlpha()) {
                flags |= kCompatibleWithCoverageAsAlpha_OptimizationFlag;
            }

            if (fp->preservesOpaqueInput()) {
                flags |= kPreservesOpaqueInput_OptimizationFlag;
            }

            if (fp->hasConstantOutputForConstantInput()) {
                flags |= kConstantOutputForConstantInput_OptimizationFlag;
            }

            return flags;
        };

        const auto fp0_flags = get_flags(fp0);

        return fp1 ? (fp0_flags & get_flags(fp1)) : fp0_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->numChildProcessors();
        this->registerChildProcessor(std::move(fp0));
        if (fp1) {
            fp1_index = this->numChildProcessors();
            this->registerChildProcessor(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
