• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright 2011 Google Inc.
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8          http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16 
17 #ifndef GrGLProgram_DEFINED
18 #define GrGLProgram_DEFINED
19 
20 #include "GrGLInterface.h"
21 #include "GrStringBuilder.h"
22 #include "GrGpu.h"
23 
24 #include "SkXfermode.h"
25 
26 class GrBinHashKeyBuilder;
27 
28 struct ShaderCodeSegments {
29     GrStringBuilder fHeader; // VS+FS, GLSL version, etc
30     GrStringBuilder fVSUnis;
31     GrStringBuilder fVSAttrs;
32     GrStringBuilder fVaryings;
33     GrStringBuilder fFSUnis;
34     GrStringBuilder fFSOutputs;
35     GrStringBuilder fVSCode;
36     GrStringBuilder fFSCode;
37 };
38 
39 /**
40  * This class manages a GPU program and records per-program information.
41  * We can specify the attribute locations so that they are constant
42  * across our shaders. But the driver determines the uniform locations
43  * at link time. We don't need to remember the sampler uniform location
44  * because we will bind a texture slot to it and never change it
45  * Uniforms are program-local so we can't rely on fHWState to hold the
46  * previous uniform state after a program change.
47  */
48 class GrGLProgram {
49 public:
50     class CachedData;
51 
52     GrGLProgram();
53     ~GrGLProgram();
54 
55     /**
56      *  Streams data that can uniquely identifies the generated
57      *  gpu program into a key, for cache indexing purposes.
58      *
59      *  @param key The key object to receive the key data
60      */
61     void buildKey(GrBinHashKeyBuilder& key) const;
62 
63     /**
64      *  This is the heavy initilization routine for building a GLProgram.
65      *  The result of heavy init is not stored in datamembers of GrGLProgam,
66      *  but in a separate cacheable container.
67      */
68     bool genProgram(CachedData* programData) const;
69 
70      /**
71       * The shader may modify the blend coeffecients. Params are in/out
72       */
73      void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const;
74 
75     /**
76      * Attribute indices
77      */
PositionAttributeIdx()78     static int PositionAttributeIdx() { return 0; }
TexCoordAttributeIdx(int tcIdx)79     static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
ColorAttributeIdx()80     static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
ViewMatrixAttributeIdx()81     static int ViewMatrixAttributeIdx() {
82         return 2 + GrDrawTarget::kMaxTexCoords;
83     }
TextureMatrixAttributeIdx(int stage)84     static int TextureMatrixAttributeIdx(int stage) {
85         return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
86     }
87 
88 private:
89 
90     // Parameters that affect code generation
91     // These structs should be kept compact; they are the input to an
92     // expensive hash key generator.
93     struct ProgramDesc {
ProgramDescProgramDesc94         ProgramDesc() {
95             // since we use this as part of a key we can't have any unitialized
96             // padding
97             memset(this, 0, sizeof(ProgramDesc));
98         }
99 
100         struct StageDesc {
101             enum OptFlagBits {
102                 kNoPerspective_OptFlagBit       = 1 << 0,
103                 kIdentityMatrix_OptFlagBit      = 1 << 1,
104                 kCustomTextureDomain_OptFlagBit = 1 << 2,
105                 kIsEnabled_OptFlagBit           = 1 << 7
106             };
107             enum Modulation {
108                 kColor_Modulation,
109                 kAlpha_Modulation
110             };
111             enum FetchMode {
112                 kSingle_FetchMode,
113                 k2x2_FetchMode
114             };
115             enum CoordMapping {
116                 kIdentity_CoordMapping,
117                 kRadialGradient_CoordMapping,
118                 kSweepGradient_CoordMapping,
119                 kRadial2Gradient_CoordMapping
120             };
121 
122             uint8_t fOptFlags;
123             uint8_t fModulation;  // casts to enum Modulation
124             uint8_t fFetchMode;  // casts to enum FetchMode
125             uint8_t fCoordMapping;  // casts to enum CoordMapping
126 
isEnabledProgramDesc::StageDesc127             inline bool isEnabled() const {
128                 return fOptFlags & kIsEnabled_OptFlagBit;
129             }
setEnabledProgramDesc::StageDesc130             inline void setEnabled(bool newValue) {
131                 if (newValue) {
132                     fOptFlags |= kIsEnabled_OptFlagBit;
133                 } else {
134                     fOptFlags &= ~kIsEnabled_OptFlagBit;
135                 }
136             }
137         };
138 
139         enum ColorType {
140             kNone_ColorType         = 0,
141             kAttribute_ColorType    = 1,
142             kUniform_ColorType      = 2,
143         };
144         // Dual-src blending makes use of a secondary output color that can be
145         // used as a per-pixel blend coeffecient. This controls whether a
146         // secondary source is output and what value it holds.
147         enum DualSrcOutput {
148             kNone_DualSrcOutput,
149             kCoverage_DualSrcOutput,
150             kCoverageISA_DualSrcOutput,
151             kCoverageISC_DualSrcOutput,
152             kDualSrcOutputCnt
153         };
154 
155         // stripped of bits that don't affect prog generation
156         GrVertexLayout fVertexLayout;
157 
158         StageDesc fStages[GrDrawTarget::kNumStages];
159 
160         uint8_t fColorType;  // casts to enum ColorType
161         uint8_t fDualSrcOutput;  // casts to enum DualSrcOutput
162         int8_t fFirstCoverageStage;
163         SkBool8 fEmitsPointSize;
164 
165         int8_t fEdgeAANumEdges;
166         uint8_t fColorFilterXfermode;  // casts to enum SkXfermode::Mode
167 
168         uint8_t fPadTo32bLengthMultiple [2];
169 
170     } fProgramDesc;
171 
getDesc()172     const ProgramDesc& getDesc() { return fProgramDesc; }
173 
174 public:
175     enum {
176         kUnusedUniform = -1,
177         kSetAsAttribute = 1000,
178     };
179 
180     struct StageUniLocations {
181         GrGLint fTextureMatrixUni;
182         GrGLint fNormalizedTexelSizeUni;
183         GrGLint fSamplerUni;
184         GrGLint fRadial2Uni;
185         GrGLint fTexDomUni;
resetStageUniLocations186         void reset() {
187             fTextureMatrixUni = kUnusedUniform;
188             fNormalizedTexelSizeUni = kUnusedUniform;
189             fSamplerUni = kUnusedUniform;
190             fRadial2Uni = kUnusedUniform;
191             fTexDomUni = kUnusedUniform;
192         }
193     };
194 
195     struct UniLocations {
196         GrGLint fViewMatrixUni;
197         GrGLint fColorUni;
198         GrGLint fEdgesUni;
199         GrGLint fColorFilterUni;
200         StageUniLocations fStages[GrDrawTarget::kNumStages];
resetUniLocations201         void reset() {
202             fViewMatrixUni = kUnusedUniform;
203             fColorUni = kUnusedUniform;
204             fEdgesUni = kUnusedUniform;
205             fColorFilterUni = kUnusedUniform;
206             for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
207                 fStages[s].reset();
208             }
209         }
210     };
211 
212     class CachedData : public ::GrNoncopyable {
213     public:
CachedData()214         CachedData() {
215         }
216 
~CachedData()217         ~CachedData() {
218         }
219 
copyAndTakeOwnership(CachedData & other)220         void copyAndTakeOwnership(CachedData& other) {
221             memcpy(this, &other, sizeof(*this));
222         }
223 
224     public:
225 
226         // IDs
227         GrGLuint    fVShaderID;
228         GrGLuint    fFShaderID;
229         GrGLuint    fProgramID;
230         // shader uniform locations (-1 if shader doesn't use them)
231         UniLocations fUniLocations;
232 
233         GrMatrix  fViewMatrix;
234 
235         // these reflect the current values of uniforms
236         // (GL uniform values travel with program)
237         GrColor                     fColor;
238         GrColor                     fColorFilterColor;
239         GrMatrix                    fTextureMatrices[GrDrawTarget::kNumStages];
240         // width and height used for normalized texel size
241         int                         fTextureWidth[GrDrawTarget::kNumStages];
242         int                         fTextureHeight[GrDrawTarget::kNumStages];
243         GrScalar                    fRadial2CenterX1[GrDrawTarget::kNumStages];
244         GrScalar                    fRadial2Radius0[GrDrawTarget::kNumStages];
245         bool                        fRadial2PosRoot[GrDrawTarget::kNumStages];
246         GrRect                      fTextureDomain[GrDrawTarget::kNumStages];
247 
248     private:
249         enum Constants {
250             kUniLocationPreAllocSize = 8
251         };
252 
253     }; // CachedData
254 
255 private:
256     enum {
257         kUseUniform = 2000
258     };
259 
260     // should set all fields in locations var to kUseUniform if the
261     // corresponding uniform is required for the program.
262     void genStageCode(int stageNum,
263                       const ProgramDesc::StageDesc& desc,
264                       const char* fsInColor, // NULL means no incoming color
265                       const char* fsOutColor,
266                       const char* vsInCoord,
267                       ShaderCodeSegments* segments,
268                       StageUniLocations* locations) const;
269 
270     static bool CompileFSAndVS(const ShaderCodeSegments& segments,
271                                CachedData* programData);
272 
273     // Compiles a GL shader, returns shader ID or 0 if failed
274     // params have same meaning as glShaderSource
275     static GrGLuint CompileShader(GrGLenum type, int stringCnt,
276                                   const char** strings,
277                                   int* stringLengths);
278 
279     // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
280     // links the program
281     bool bindOutputsAttribsAndLinkProgram(
282                 GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
283                 bool bindColorOut,
284                 bool bindDualSrcOut,
285                 CachedData* programData) const;
286 
287     // Gets locations for all uniforms set to kUseUniform and initializes cache
288     // to invalid values.
289     void getUniformLocationsAndInitCache(CachedData* programData) const;
290 
291     friend class GrGpuGLShaders;
292 };
293 
294 #endif
295