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

#ifndef GrProcOptInfo_DEFINED
#define GrProcOptInfo_DEFINED

#include "GrColor.h"
#include "GrInvariantOutput.h"

class GrDrawBatch;
class GrFragmentProcessor;
class GrPrimitiveProcessor;
class GrProcessor;

/**
 * GrProcOptInfo gathers invariant data from a set of processor stages.It is used to recognize
 * optimizations related to eliminating stages and vertex attributes that aren't necessary for a
 * draw.
 */
class GrProcOptInfo {
public:
    GrProcOptInfo()
        : fInOut(0, static_cast<GrColorComponentFlags>(0), false)
        , fFirstEffectiveProcessorIndex(0)
        , fInputColorIsUsed(true)
        , fInputColor(0)
        , fReadsFragPosition(false) {}

    void calcWithInitialValues(const GrFragmentProcessor* const *, int cnt, GrColor startColor,
                               GrColorComponentFlags, bool areCoverageStages, bool isLCD = false);

    void calcColorWithBatch(const GrDrawBatch*, const GrFragmentProcessor* const[], int cnt);
    void calcCoverageWithBatch(const GrDrawBatch*, const GrFragmentProcessor* const[], int cnt);

    bool isSolidWhite() const { return fInOut.isSolidWhite(); }
    bool isOpaque() const { return fInOut.isOpaque(); }
    bool isSingleComponent() const { return fInOut.isSingleComponent(); }
    bool allStagesMultiplyInput() const { return fInOut.allStagesMulInput(); }

    // TODO: Once texture pixel configs quaries are updated, we no longer need this function.
    // For now this function will correctly tell us if we are using LCD text or not and should only
    // be called when looking at the coverage output.
    bool isFourChannelOutput() const { return !fInOut.isSingleComponent() &&
                                               fInOut.isLCDCoverage(); }

    GrColor color() const { return fInOut.color(); }

    GrColorComponentFlags validFlags() const {
        return static_cast<GrColorComponentFlags>(fInOut.validFlags());
    }

    /**
     * Returns the index of the first effective color processor. If an intermediate processor
     * doesn't read its input or has a known output, then we can ignore all earlier processors
     * since they will not affect the final output. Thus the first effective processors index is
     * the index to the first processor that will have an effect on the final output.
     *
     * If processors before the firstEffectiveProcessorIndex() are removed, corresponding values
     * from inputColorIsUsed(), inputColorToEffectiveProcessor(), removeVertexAttribs(), and
     * readsDst() must be used when setting up the draw to ensure correct drawing.
     */
    int firstEffectiveProcessorIndex() const { return fFirstEffectiveProcessorIndex; }

    /**
     * True if the first effective processor reads its input, false otherwise.
     */
    bool inputColorIsUsed() const { return fInputColorIsUsed; }

    /**
     * If input color is used and per-vertex colors are not used, this is the input color to the
     * first effective processor.
     */
    GrColor inputColorToFirstEffectiveProccesor() const { return fInputColor; }

    /**
     * Returns true if any of the processor preserved by GrProcOptInfo read the frag position.
     */
    bool readsFragPosition() const { return fReadsFragPosition; }

private:
    void internalCalc(const GrFragmentProcessor* const[], int cnt, bool initWillReadFragPosition);

    GrInvariantOutput fInOut;
    int fFirstEffectiveProcessorIndex;
    bool fInputColorIsUsed;
    GrColor fInputColor;
    bool fReadsFragPosition;
};

#endif
