blob: 54818ec9d03d736a6206136d14cc47358e7f1c26 [file] [log] [blame]
junov@google.comf93e7172011-03-31 21:26:24 +00001/*
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"
bsalomon@google.com91961302011-05-09 18:39:58 +000021#include "GrStringBuilder.h"
junov@google.comf93e7172011-03-31 21:26:24 +000022#include "GrDrawTarget.h"
23
24class GrBinHashKeyBuilder;
25class GrGLEffect;
26struct ShaderCodeSegments;
27
28/**
29 * This class manages a GPU program and records per-program information.
30 * We can specify the attribute locations so that they are constant
31 * across our shaders. But the driver determines the uniform locations
32 * at link time. We don't need to remember the sampler uniform location
33 * because we will bind a texture slot to it and never change it
34 * Uniforms are program-local so we can't rely on fHWState to hold the
35 * previous uniform state after a program change.
36 */
37class GrGLProgram {
38public:
39 class CachedData;
40
41 GrGLProgram();
42 ~GrGLProgram();
43
44 /**
45 * Streams data that can uniquely identifies the generated
46 * gpu program into a key, for cache indexing purposes.
47 *
48 * @param key The key object to receive the key data
49 */
50 void buildKey(GrBinHashKeyBuilder& key) const;
51
52 /**
53 * This is the heavy initilization routine for building a GLProgram.
54 * The result of heavy init is not stored in datamembers of GrGLProgam,
55 * but in a separate cacheable container.
56 */
bsalomon@google.com91961302011-05-09 18:39:58 +000057 bool genProgram(CachedData* programData) const;
junov@google.comf93e7172011-03-31 21:26:24 +000058
59 /**
60 * Routine that is called before rendering. Sets-up all the state and
61 * other initializations required for the Gpu Program to run.
62 */
63 bool doGLSetup(GrPrimitiveType type, CachedData* programData) const;
64
65 /**
66 * Routine that is called after rendering. Performs state restoration.
67 * May perform secondary render passes.
68 */
69 void doGLPost() const;
70
71 /**
72 * Configures the GrGLProgram based on the state of a GrDrawTarget
73 * object. This is the fast and light initialization. Retrieves all the
74 * state that is required for performing the heavy init (i.e. genProgram),
75 * or for retrieving heavy init results from cache.
76 */
77 void buildFromTarget(const GrDrawTarget* target);
78
bsalomon@google.com91961302011-05-09 18:39:58 +000079 static int PositionAttributeIdx() { return 0; }
80 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
81 static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
82 static int ViewMatrixAttributeIdx() {
83 return 2 + GrDrawTarget::kMaxTexCoords;
84 }
85 static int TextureMatrixAttributeIdx(int stage) {
86 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
87 }
88
junov@google.comf93e7172011-03-31 21:26:24 +000089private:
90
91 //Parameters that affect code generation
92 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000093 ProgramDesc() {
94 // since we use this as part of a key we can't have any unitialized
95 // padding
96 memset(this, 0, sizeof(ProgramDesc));
97 }
98
99 // stripped of bits that don't affect prog generation
junov@google.comf93e7172011-03-31 21:26:24 +0000100 GrVertexLayout fVertexLayout;
101
102 enum {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000103 kNone_ColorType = 0,
104 kAttribute_ColorType = 1,
105 kUniform_ColorType = 2,
106 } fColorType;
107
108 bool fEmitsPointSize;
junov@google.comf93e7172011-03-31 21:26:24 +0000109
110 struct StageDesc {
111 enum OptFlagBits {
112 kNoPerspective_OptFlagBit = 0x1,
113 kIdentityMatrix_OptFlagBit = 0x2
114 };
115
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000116 unsigned fOptFlags;
117 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000118
119 enum Modulation {
120 kColor_Modulation,
121 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000122 } fModulation;
123
124 enum FetchMode {
125 kSingle_FetchMode,
126 k2x2_FetchMode
127 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000128
129 enum CoordMapping {
130 kIdentity_CoordMapping,
131 kRadialGradient_CoordMapping,
132 kSweepGradient_CoordMapping,
133 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000134 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000135 } fStages[GrDrawTarget::kNumStages];
136 } fProgramDesc;
137
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000138 const ProgramDesc& getDesc() { return fProgramDesc; }
139
junov@google.comf93e7172011-03-31 21:26:24 +0000140public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000141 enum {
142 kUnusedUniform = -1,
143 kSetAsAttribute = 1000,
144 };
145
junov@google.comf93e7172011-03-31 21:26:24 +0000146 struct StageUniLocations {
147 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000148 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000149 GrGLint fSamplerUni;
150 GrGLint fRadial2Uni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000151 void reset() {
152 fTextureMatrixUni = kUnusedUniform;
153 fNormalizedTexelSizeUni = kUnusedUniform;
154 fSamplerUni = kUnusedUniform;
155 fRadial2Uni = kUnusedUniform;
156 }
junov@google.comf93e7172011-03-31 21:26:24 +0000157 };
158
159 struct UniLocations {
160 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000161 GrGLint fColorUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000162 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000163 void reset() {
164 fViewMatrixUni = kUnusedUniform;
165 fColorUni = kUnusedUniform;
166 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
167 fStages[s].reset();
168 }
169 }
junov@google.comf93e7172011-03-31 21:26:24 +0000170 };
171
172 class CachedData : public ::GrNoncopyable {
173 public:
174 CachedData() {
175 GR_DEBUGCODE(fEffectUniCount = 0;)
176 fEffectUniLocationsExtended = NULL;
177 }
178
179 ~CachedData() {
180 GrFree(fEffectUniLocationsExtended);
181 }
182
183 void copyAndTakeOwnership(CachedData& other) {
184 memcpy(this, &other, sizeof(this));
185 other.fEffectUniLocationsExtended = NULL; // ownership transfer
186 GR_DEBUGCODE(other.fEffectUniCount = 0;)
187 }
188
189 void setEffectUniformCount(size_t effectUniforms) {
190 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
191 GrFree(fEffectUniLocationsExtended);
192 if (effectUniforms > kUniLocationPreAllocSize) {
193 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
194 } else {
195 fEffectUniLocationsExtended = NULL;
196 }
197 }
198
199 GrGLint& effectUniLocation(size_t index) {
200 GrAssert(index < fEffectUniCount);
201 return (index < kUniLocationPreAllocSize) ?
202 fEffectUniLocations[index] :
203 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
204 }
205
206 public:
207
208 // IDs
209 GrGLuint fVShaderID;
210 GrGLuint fFShaderID;
211 GrGLuint fProgramID;
212 // shader uniform locations (-1 if shader doesn't use them)
213 UniLocations fUniLocations;
214
215 GrMatrix fViewMatrix;
216
217 // these reflect the current values of uniforms
218 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000219 GrColor fColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000220 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000221 // width and height used for normalized texel size
222 int fTextureWidth[GrDrawTarget::kNumStages];
223 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000224 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
225 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
226 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
227
228 private:
229 enum Constants {
230 kUniLocationPreAllocSize = 8
231 };
232
233 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
234 GrGLint* fEffectUniLocationsExtended;
235 GR_DEBUGCODE(size_t fEffectUniCount;)
236 }; // CachedData
237
238 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
239
240private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000241 enum {
242 kUseUniform = 2000
243 };
244
245 // should set all fields in locations var to kUseUniform if the
246 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000247 void genStageCode(int stageNum,
248 const ProgramDesc::StageDesc& desc,
249 const char* fsInColor, // NULL means no incoming color
250 const char* fsOutColor,
251 const char* vsInCoord,
252 ShaderCodeSegments* segments,
253 StageUniLocations* locations) const;
254
bsalomon@google.com91961302011-05-09 18:39:58 +0000255 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
256 CachedData* programData);
257
junov@google.comf93e7172011-03-31 21:26:24 +0000258 // Compiles a GL shader, returns shader ID or 0 if failed
259 // params have same meaning as glShaderSource
260 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
261 const char** strings,
262 int* stringLengths);
263
bsalomon@google.com91961302011-05-09 18:39:58 +0000264 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
265 // links the program
266 bool bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
267 CachedData* programData) const;
268
269 // Gets locations for all uniforms set to kUseUniform and initializes cache
270 // to invalid values.
271 void getUniformLocationsAndInitCache(CachedData* programData) const;
272
junov@google.comf93e7172011-03-31 21:26:24 +0000273 friend class GrGpuGLShaders;
274};
275
276#endif