1/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrOptDrawState_DEFINED
9#define GrOptDrawState_DEFINED
10
11#include "GrDrawState.h"
12#include "GrRODrawState.h"
13
14/**
15 * Subclass of GrRODrawState that holds an optimized version of a GrDrawState. Like it's parent
16 * it is meant to be an immutable class, and simply adds a few helpful data members not in the
17 * base class.
18 */
19class GrOptDrawState : public GrRODrawState {
20public:
21    bool operator== (const GrOptDrawState& that) const;
22
23    bool inputColorIsUsed() const { return fInputColorIsUsed; }
24    bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; }
25
26    bool readsDst() const { return fReadsDst; }
27    bool readsFragPosition() const { return fReadsFragPosition; }
28    bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; }
29
30    ///////////////////////////////////////////////////////////////////////////
31    /// @name Stage Output Types
32    ////
33
34    enum PrimaryOutputType {
35        // Modulate color and coverage, write result as the color output.
36        kModulate_PrimaryOutputType,
37        // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
38        // can only be set if fDstReadKey is non-zero.
39        kCombineWithDst_PrimaryOutputType,
40
41        kPrimaryOutputTypeCnt,
42    };
43
44    enum SecondaryOutputType {
45        // There is no secondary output
46        kNone_SecondaryOutputType,
47        // Writes coverage as the secondary output. Only set if dual source blending is supported
48        // and primary output is kModulate.
49        kCoverage_SecondaryOutputType,
50        // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
51        // is supported and primary output is kModulate.
52        kCoverageISA_SecondaryOutputType,
53        // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
54        // blending is supported and primary output is kModulate.
55        kCoverageISC_SecondaryOutputType,
56
57        kSecondaryOutputTypeCnt,
58    };
59
60    PrimaryOutputType getPrimaryOutputType() const { return fPrimaryOutputType; }
61    SecondaryOutputType getSecondaryOutputType() const { return fSecondaryOutputType; }
62
63    /// @}
64
65private:
66    /**
67     * Constructs and optimized drawState out of a GrRODrawState.
68     */
69    GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
70                   GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
71                   const GrDrawTargetCaps& caps);
72
73    /**
74     * Loops through all the color stage effects to check if the stage will ignore color input or
75     * always output a constant color. In the ignore color input case we can ignore all previous
76     * stages. In the constant color case, we can ignore all previous stages and
77     * the current one and set the state color to the constant color. Once we determine the so
78     * called first effective stage, we copy all the effective stages into our optimized
79     * state.
80     */
81    void copyEffectiveColorStages(const GrDrawState& ds);
82
83    /**
84     * Loops through all the coverage stage effects to check if the stage will ignore color input.
85     * If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
86     * loop to determine the first effective coverage stage, and then copy all of our effective
87     * coverage stages into our optimized state.
88     */
89    void copyEffectiveCoverageStages(const GrDrawState& ds);
90
91    /**
92     * This function takes in a flag and removes the corresponding fixed function vertex attributes.
93     * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
94     * set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
95     */
96    void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags);
97
98    /**
99     * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
100     * BlendOptFlags.
101     */
102    void adjustFromBlendOpts();
103
104    /**
105     * Loop over the effect stages to determine various info like what data they will read and what
106     * shaders they require.
107     */
108    void getStageStats();
109
110    /**
111     * Calculates the primary and secondary output types of the shader. For certain output types
112     * the function may adjust the blend coefficients. After this function is called the src and dst
113     * blend coeffs will represent those used by backend API.
114     */
115    void setOutputStateInfo(const GrDrawTargetCaps&);
116
117    // These flags are needed to protect the code from creating an unused uniform color/coverage
118    // which will cause shader compiler errors.
119    bool            fInputColorIsUsed;
120    bool            fInputCoverageIsUsed;
121
122    // These flags give aggregated info on the effect stages that are used when building programs.
123    bool            fReadsDst;
124    bool            fReadsFragPosition;
125    bool            fRequiresLocalCoordAttrib;
126
127    SkAutoSTArray<4, GrVertexAttrib> fOptVA;
128
129    BlendOptFlags   fBlendOptFlags;
130
131    // Fragment shader color outputs
132    PrimaryOutputType  fPrimaryOutputType : 8;
133    SecondaryOutputType  fSecondaryOutputType : 8;
134
135    friend GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps&) const;
136    typedef GrRODrawState INHERITED;
137};
138
139#endif
140