• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 class GrBinHashKeyBuilder;
23 class GrGLEffect;
24 class 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  */
39 class GrGLProgram : public GrRefCnt {
40 public:
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 
getDesc()61     const Desc& getDesc() { return fDesc; }
62 
63     /**
64      * Attribute indices. These should not overlap.
65      */
PositionAttributeIdx()66     static int PositionAttributeIdx() { return 0; }
ColorAttributeIdx()67     static int ColorAttributeIdx() { return 1; }
CoverageAttributeIdx()68     static int CoverageAttributeIdx() { return 2; }
EdgeAttributeIdx()69     static int EdgeAttributeIdx() { return 3; }
TexCoordAttributeIdx(int tcIdx)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 {
DescDesc82         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
asKeyDesc89         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     };
137 private:
138     GrGLProgram(const GrGLContextInfo& gl,
139                 const Desc& desc,
140                 const GrEffectStage* stages[]);
141 
succeeded()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 
UniformHandlesUniformHandles188         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 both the client's matrix and
203     // the size of the viewport.
204     SkMatrix                    fViewMatrix;
205     SkISize                     fViewportSize;
206 
207     // these reflect the current values of uniforms (GL uniform values travel with program)
208     GrColor                     fColor;
209     GrColor                     fCoverage;
210     GrColor                     fColorFilterColor;
211     int                         fRTHeight;
212 
213     GrGLEffect*                 fEffects[GrDrawState::kNumStages];
214 
215     Desc                        fDesc;
216     const GrGLContextInfo&      fContextInfo;
217 
218     GrGLUniformManager          fUniformManager;
219     UniformHandles              fUniformHandles;
220 
221     friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality.
222 
223     typedef GrRefCnt INHERITED;
224 };
225 
226 #endif
227