GrGLProgram.h revision ed8659b51d9f2bad3f004df6033d72cc32d71c0d
1/*
2 * Copyright 2011 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
9#ifndef GrGLProgram_DEFINED
10#define GrGLProgram_DEFINED
11
12#include "GrDrawState.h"
13#include "GrGLEffect.h"
14#include "GrGLContextInfo.h"
15#include "GrGLSL.h"
16#include "GrGLTexture.h"
17#include "GrGLUniformManager.h"
18
19#include "SkString.h"
20#include "SkXfermode.h"
21
22class GrBinHashKeyBuilder;
23class GrGLEffect;
24class GrGLShaderBuilder;
25
26// optionally compile the experimental GS code. Set to GR_DEBUG
27// so that debug build bots will execute the code.
28#define GR_GL_EXPERIMENTAL_GS GR_DEBUG
29
30/**
31 * This class manages a GPU program and records per-program information.
32 * We can specify the attribute locations so that they are constant
33 * across our shaders. But the driver determines the uniform locations
34 * at link time. We don't need to remember the sampler uniform location
35 * because we will bind a texture slot to it and never change it
36 * Uniforms are program-local so we can't rely on fHWState to hold the
37 * previous uniform state after a program change.
38 */
39class GrGLProgram : public GrRefCnt {
40public:
41    SK_DECLARE_INST_COUNT(GrGLProgram)
42
43    struct Desc;
44
45    static GrGLProgram* Create(const GrGLContextInfo& gl,
46                               const Desc& desc,
47                               const GrEffectStage* stages[]);
48
49    virtual ~GrGLProgram();
50
51    /**
52     * Call to abandon GL objects owned by this program.
53     */
54    void abandon();
55
56    /**
57     * The shader may modify the blend coefficients. Params are in/out
58     */
59    void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
60
61    const Desc& getDesc() { return fDesc; }
62
63    /**
64     * Attribute indices. These should not overlap.
65     */
66    static int PositionAttributeIdx() { return 0; }
67    static int ColorAttributeIdx() { return 1; }
68    static int CoverageAttributeIdx() { return 2; }
69    static int EdgeAttributeIdx() { return 3; }
70    static int TexCoordAttributeIdx(int tcIdx) { return 4 + tcIdx; }
71
72    /**
73     * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a
74     * draw occurs using the program after the program has already been bound. It also uses the
75     * GrGpuGL object to bind the textures required by the GrGLEffects.
76     */
77    void setData(GrGpuGL*);
78
79    // Parameters that affect code generation
80    // This structs should be kept compact; it is input to an expensive hash key generator.
81    struct Desc {
82        Desc() {
83            // since we use this as part of a key we can't have any uninitialized
84            // padding
85            memset(this, 0, sizeof(Desc));
86        }
87
88        // returns this as a uint32_t array to be used as a key in the program cache
89        const uint32_t* asKey() const {
90            return reinterpret_cast<const uint32_t*>(this);
91        }
92
93        // Specifies where the initial color comes from before the stages are applied.
94        enum ColorInput {
95            kSolidWhite_ColorInput,
96            kTransBlack_ColorInput,
97            kAttribute_ColorInput,
98            kUniform_ColorInput,
99
100            kColorInputCnt
101        };
102        // Dual-src blending makes use of a secondary output color that can be
103        // used as a per-pixel blend coefficient. This controls whether a
104        // secondary source is output and what value it holds.
105        enum DualSrcOutput {
106            kNone_DualSrcOutput,
107            kCoverage_DualSrcOutput,
108            kCoverageISA_DualSrcOutput,
109            kCoverageISC_DualSrcOutput,
110
111            kDualSrcOutputCnt
112        };
113
114        // TODO: remove these two members when edge-aa can be rewritten as a GrEffect.
115        GrDrawState::VertexEdgeType fVertexEdgeType;
116        // should the FS discard if the edge-aa coverage is zero (to avoid stencil manipulation)
117        bool                        fDiscardIfOutsideEdge;
118
119        // stripped of bits that don't affect program generation
120        GrVertexLayout              fVertexLayout;
121
122        /** Non-zero if this stage has an effect */
123        GrGLEffect::EffectKey       fEffectKeys[GrDrawState::kNumStages];
124
125        // To enable experimental geometry shader code (not for use in
126        // production)
127#if GR_GL_EXPERIMENTAL_GS
128        bool                        fExperimentalGS;
129#endif
130        uint8_t                     fColorInput;            // casts to enum ColorInput
131        uint8_t                     fCoverageInput;         // casts to enum ColorInput
132        uint8_t                     fDualSrcOutput;         // casts to enum DualSrcOutput
133        int8_t                      fFirstCoverageStage;
134        SkBool8                     fEmitsPointSize;
135        uint8_t                     fColorFilterXfermode;   // casts to enum SkXfermode::Mode
136    };
137private:
138    GrGLProgram(const GrGLContextInfo& gl,
139                const Desc& desc,
140                const GrEffectStage* stages[]);
141
142    bool succeeded() const { return 0 != fProgramID; }
143
144    /**
145     *  This is the heavy initialization routine for building a GLProgram.
146     */
147    bool genProgram(const GrEffectStage* stages[]);
148
149    void genInputColor(GrGLShaderBuilder* builder, SkString* inColor);
150
151    void genGeometryShader(GrGLShaderBuilder* segments) const;
152
153    typedef GrGLUniformManager::UniformHandle UniformHandle;
154
155    void genUniformCoverage(GrGLShaderBuilder* segments, SkString* inOutCoverage);
156
157    // generates code to compute coverage based on edge AA. Returns true if edge coverage was
158    // inserted in which case coverageVar will be updated to refer to a scalar. Otherwise,
159    // coverageVar is set to an empty string.
160    bool genEdgeCoverage(SkString* coverageVar, GrGLShaderBuilder* builder) const;
161
162    // Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program
163    bool bindOutputsAttribsAndLinkProgram(const GrGLShaderBuilder& builder,
164                                          SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
165                                          bool bindColorOut,
166                                          bool bindDualSrcOut);
167
168    // Sets the texture units for samplers
169    void initSamplerUniforms();
170
171    bool compileShaders(const GrGLShaderBuilder& builder);
172
173    const char* adjustInColor(const SkString& inColor) const;
174
175    typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray;
176
177    struct UniformHandles {
178        UniformHandle       fViewMatrixUni;
179        UniformHandle       fColorUni;
180        UniformHandle       fCoverageUni;
181        UniformHandle       fColorFilterUni;
182        // We use the render target height to provide a y-down frag coord when specifying
183        // origin_upper_left is not supported.
184        UniformHandle       fRTHeightUni;
185        // An array of sampler uniform handles for each effect.
186        SamplerUniSArray    fSamplerUnis[GrDrawState::kNumStages];
187
188        UniformHandles() {
189            fViewMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
190            fColorUni = GrGLUniformManager::kInvalidUniformHandle;
191            fCoverageUni = GrGLUniformManager::kInvalidUniformHandle;
192            fColorFilterUni = GrGLUniformManager::kInvalidUniformHandle;
193            fRTHeightUni = GrGLUniformManager::kInvalidUniformHandle;
194        }
195    };
196
197    // GL IDs
198    GrGLuint                    fVShaderID;
199    GrGLuint                    fGShaderID;
200    GrGLuint                    fFShaderID;
201    GrGLuint                    fProgramID;
202    // The matrix sent to GL is determined by the client's matrix,
203    // the size of the viewport, and the origin of the render target.
204    SkMatrix                    fViewMatrix;
205    SkISize                     fViewportSize;
206    GrSurfaceOrigin             fOrigin;
207
208    // these reflect the current values of uniforms (GL uniform values travel with program)
209    GrColor                     fColor;
210    GrColor                     fCoverage;
211    GrColor                     fColorFilterColor;
212    int                         fRTHeight;
213
214    GrGLEffect*                 fEffects[GrDrawState::kNumStages];
215
216    Desc                        fDesc;
217    const GrGLContextInfo&      fContextInfo;
218
219    GrGLUniformManager          fUniformManager;
220    UniformHandles              fUniformHandles;
221
222    friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality.
223
224    typedef GrRefCnt INHERITED;
225};
226
227#endif
228