blob: 3b926a78c4504266adc55dd5e24b6a958546572d [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
Scroggo97c88c22011-05-11 14:05:25 +000024#include "SkXfermode.h"
25
junov@google.comf93e7172011-03-31 21:26:24 +000026class GrBinHashKeyBuilder;
27class GrGLEffect;
28struct ShaderCodeSegments;
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 {
40public:
41 class CachedData;
42
43 GrGLProgram();
44 ~GrGLProgram();
45
46 /**
47 * Streams data that can uniquely identifies the generated
48 * gpu program into a key, for cache indexing purposes.
49 *
50 * @param key The key object to receive the key data
51 */
52 void buildKey(GrBinHashKeyBuilder& key) const;
53
54 /**
55 * This is the heavy initilization routine for building a GLProgram.
56 * The result of heavy init is not stored in datamembers of GrGLProgam,
57 * but in a separate cacheable container.
58 */
bsalomon@google.com91961302011-05-09 18:39:58 +000059 bool genProgram(CachedData* programData) const;
junov@google.comf93e7172011-03-31 21:26:24 +000060
61 /**
62 * Routine that is called before rendering. Sets-up all the state and
63 * other initializations required for the Gpu Program to run.
64 */
65 bool doGLSetup(GrPrimitiveType type, CachedData* programData) const;
66
67 /**
68 * Routine that is called after rendering. Performs state restoration.
69 * May perform secondary render passes.
70 */
71 void doGLPost() const;
72
73 /**
74 * Configures the GrGLProgram based on the state of a GrDrawTarget
75 * object. This is the fast and light initialization. Retrieves all the
76 * state that is required for performing the heavy init (i.e. genProgram),
77 * or for retrieving heavy init results from cache.
78 */
79 void buildFromTarget(const GrDrawTarget* target);
80
bsalomon@google.com91961302011-05-09 18:39:58 +000081 static int PositionAttributeIdx() { return 0; }
82 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
83 static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
84 static int ViewMatrixAttributeIdx() {
85 return 2 + GrDrawTarget::kMaxTexCoords;
86 }
87 static int TextureMatrixAttributeIdx(int stage) {
88 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
89 }
90
junov@google.comf93e7172011-03-31 21:26:24 +000091private:
92
93 //Parameters that affect code generation
94 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000095 ProgramDesc() {
96 // since we use this as part of a key we can't have any unitialized
97 // padding
98 memset(this, 0, sizeof(ProgramDesc));
99 }
100
101 // stripped of bits that don't affect prog generation
junov@google.comf93e7172011-03-31 21:26:24 +0000102 GrVertexLayout fVertexLayout;
103
104 enum {
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000105 kNone_ColorType = 0,
106 kAttribute_ColorType = 1,
107 kUniform_ColorType = 2,
108 } fColorType;
109
110 bool fEmitsPointSize;
junov@google.comf93e7172011-03-31 21:26:24 +0000111
Scroggo97c88c22011-05-11 14:05:25 +0000112 GrColor fColorFilterColor;
113 SkXfermode::Mode fColorFilterXfermode;
114
junov@google.comf93e7172011-03-31 21:26:24 +0000115 struct StageDesc {
116 enum OptFlagBits {
117 kNoPerspective_OptFlagBit = 0x1,
118 kIdentityMatrix_OptFlagBit = 0x2
119 };
120
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000121 unsigned fOptFlags;
122 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000123
124 enum Modulation {
125 kColor_Modulation,
126 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000127 } fModulation;
128
129 enum FetchMode {
130 kSingle_FetchMode,
131 k2x2_FetchMode
132 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000133
134 enum CoordMapping {
135 kIdentity_CoordMapping,
136 kRadialGradient_CoordMapping,
137 kSweepGradient_CoordMapping,
138 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000139 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000140 } fStages[GrDrawTarget::kNumStages];
141 } fProgramDesc;
142
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000143 const ProgramDesc& getDesc() { return fProgramDesc; }
144
junov@google.comf93e7172011-03-31 21:26:24 +0000145public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000146 enum {
147 kUnusedUniform = -1,
148 kSetAsAttribute = 1000,
149 };
150
junov@google.comf93e7172011-03-31 21:26:24 +0000151 struct StageUniLocations {
152 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000153 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000154 GrGLint fSamplerUni;
155 GrGLint fRadial2Uni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000156 void reset() {
157 fTextureMatrixUni = kUnusedUniform;
158 fNormalizedTexelSizeUni = kUnusedUniform;
159 fSamplerUni = kUnusedUniform;
160 fRadial2Uni = kUnusedUniform;
161 }
junov@google.comf93e7172011-03-31 21:26:24 +0000162 };
163
164 struct UniLocations {
165 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000166 GrGLint fColorUni;
Scroggo97c88c22011-05-11 14:05:25 +0000167 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000168 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000169 void reset() {
170 fViewMatrixUni = kUnusedUniform;
171 fColorUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000172 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000173 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
174 fStages[s].reset();
175 }
176 }
junov@google.comf93e7172011-03-31 21:26:24 +0000177 };
178
179 class CachedData : public ::GrNoncopyable {
180 public:
181 CachedData() {
182 GR_DEBUGCODE(fEffectUniCount = 0;)
183 fEffectUniLocationsExtended = NULL;
184 }
185
186 ~CachedData() {
187 GrFree(fEffectUniLocationsExtended);
188 }
189
190 void copyAndTakeOwnership(CachedData& other) {
191 memcpy(this, &other, sizeof(this));
192 other.fEffectUniLocationsExtended = NULL; // ownership transfer
193 GR_DEBUGCODE(other.fEffectUniCount = 0;)
194 }
195
196 void setEffectUniformCount(size_t effectUniforms) {
197 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
198 GrFree(fEffectUniLocationsExtended);
199 if (effectUniforms > kUniLocationPreAllocSize) {
200 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
201 } else {
202 fEffectUniLocationsExtended = NULL;
203 }
204 }
205
206 GrGLint& effectUniLocation(size_t index) {
207 GrAssert(index < fEffectUniCount);
208 return (index < kUniLocationPreAllocSize) ?
209 fEffectUniLocations[index] :
210 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
211 }
212
213 public:
214
215 // IDs
216 GrGLuint fVShaderID;
217 GrGLuint fFShaderID;
218 GrGLuint fProgramID;
219 // shader uniform locations (-1 if shader doesn't use them)
220 UniLocations fUniLocations;
221
222 GrMatrix fViewMatrix;
223
224 // these reflect the current values of uniforms
225 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000226 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000227 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000228 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000229 // width and height used for normalized texel size
230 int fTextureWidth[GrDrawTarget::kNumStages];
231 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000232 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
233 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
234 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
235
236 private:
237 enum Constants {
238 kUniLocationPreAllocSize = 8
239 };
240
241 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
242 GrGLint* fEffectUniLocationsExtended;
243 GR_DEBUGCODE(size_t fEffectUniCount;)
244 }; // CachedData
245
246 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
247
248private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000249 enum {
250 kUseUniform = 2000
251 };
252
253 // should set all fields in locations var to kUseUniform if the
254 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000255 void genStageCode(int stageNum,
256 const ProgramDesc::StageDesc& desc,
257 const char* fsInColor, // NULL means no incoming color
258 const char* fsOutColor,
259 const char* vsInCoord,
260 ShaderCodeSegments* segments,
261 StageUniLocations* locations) const;
262
bsalomon@google.com91961302011-05-09 18:39:58 +0000263 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
264 CachedData* programData);
265
junov@google.comf93e7172011-03-31 21:26:24 +0000266 // Compiles a GL shader, returns shader ID or 0 if failed
267 // params have same meaning as glShaderSource
268 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
269 const char** strings,
270 int* stringLengths);
271
bsalomon@google.com91961302011-05-09 18:39:58 +0000272 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
273 // links the program
274 bool bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
275 CachedData* programData) const;
276
277 // Gets locations for all uniforms set to kUseUniform and initializes cache
278 // to invalid values.
279 void getUniformLocationsAndInitCache(CachedData* programData) const;
280
junov@google.comf93e7172011-03-31 21:26:24 +0000281 friend class GrGpuGLShaders;
282};
283
284#endif