blob: 64d7088b7269f87982fcfa4a130d1ddf4f35bfe2 [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
bsalomon@google.com91961302011-05-09 18:39:58 +000073 static int PositionAttributeIdx() { return 0; }
74 static int TexCoordAttributeIdx(int tcIdx) { return 1 + tcIdx; }
75 static int ColorAttributeIdx() { return 1 + GrDrawTarget::kMaxTexCoords; }
76 static int ViewMatrixAttributeIdx() {
77 return 2 + GrDrawTarget::kMaxTexCoords;
78 }
79 static int TextureMatrixAttributeIdx(int stage) {
80 return 5 + GrDrawTarget::kMaxTexCoords + 3 * stage;
81 }
82
junov@google.comf93e7172011-03-31 21:26:24 +000083private:
84
85 //Parameters that affect code generation
86 struct ProgramDesc {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000087 ProgramDesc() {
88 // since we use this as part of a key we can't have any unitialized
89 // padding
90 memset(this, 0, sizeof(ProgramDesc));
91 }
92
93 // stripped of bits that don't affect prog generation
junov@google.comf93e7172011-03-31 21:26:24 +000094 GrVertexLayout fVertexLayout;
95
96 enum {
bsalomon@google.com4be283f2011-04-19 21:15:09 +000097 kNone_ColorType = 0,
98 kAttribute_ColorType = 1,
99 kUniform_ColorType = 2,
100 } fColorType;
101
bsalomon@google.comf2d91552011-05-16 20:56:06 +0000102 int fFirstCoverageStage;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000103 bool fEmitsPointSize;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000104 bool fUsesEdgeAA;
junov@google.comf93e7172011-03-31 21:26:24 +0000105
Scroggo97c88c22011-05-11 14:05:25 +0000106 SkXfermode::Mode fColorFilterXfermode;
107
junov@google.comf93e7172011-03-31 21:26:24 +0000108 struct StageDesc {
109 enum OptFlagBits {
junov@google.com6acc9b32011-05-16 18:32:07 +0000110 kNoPerspective_OptFlagBit = 1 << 0,
111 kIdentityMatrix_OptFlagBit = 1 << 1,
112 kCustomTextureDomain_OptFlagBit = 1 << 2
junov@google.comf93e7172011-03-31 21:26:24 +0000113 };
114
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000115 unsigned fOptFlags;
116 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000117
118 enum Modulation {
119 kColor_Modulation,
120 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000121 } fModulation;
122
123 enum FetchMode {
124 kSingle_FetchMode,
125 k2x2_FetchMode
126 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000127
128 enum CoordMapping {
129 kIdentity_CoordMapping,
130 kRadialGradient_CoordMapping,
131 kSweepGradient_CoordMapping,
132 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000133 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000134 } fStages[GrDrawTarget::kNumStages];
135 } fProgramDesc;
136
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000137 const ProgramDesc& getDesc() { return fProgramDesc; }
138
junov@google.comf93e7172011-03-31 21:26:24 +0000139public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000140 enum {
141 kUnusedUniform = -1,
142 kSetAsAttribute = 1000,
143 };
144
junov@google.comf93e7172011-03-31 21:26:24 +0000145 struct StageUniLocations {
146 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000147 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000148 GrGLint fSamplerUni;
149 GrGLint fRadial2Uni;
junov@google.com6acc9b32011-05-16 18:32:07 +0000150 GrGLint fTexDomUni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000151 void reset() {
152 fTextureMatrixUni = kUnusedUniform;
153 fNormalizedTexelSizeUni = kUnusedUniform;
154 fSamplerUni = kUnusedUniform;
155 fRadial2Uni = kUnusedUniform;
junov@google.com6acc9b32011-05-16 18:32:07 +0000156 fTexDomUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000157 }
junov@google.comf93e7172011-03-31 21:26:24 +0000158 };
159
160 struct UniLocations {
161 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000162 GrGLint fColorUni;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000163 GrGLint fEdgesUni;
Scroggo97c88c22011-05-11 14:05:25 +0000164 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000165 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000166 void reset() {
167 fViewMatrixUni = kUnusedUniform;
168 fColorUni = kUnusedUniform;
senorblanco@chromium.org92e0f222011-05-12 15:49:15 +0000169 fEdgesUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000170 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000171 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
172 fStages[s].reset();
173 }
174 }
junov@google.comf93e7172011-03-31 21:26:24 +0000175 };
176
177 class CachedData : public ::GrNoncopyable {
178 public:
179 CachedData() {
180 GR_DEBUGCODE(fEffectUniCount = 0;)
181 fEffectUniLocationsExtended = NULL;
182 }
183
184 ~CachedData() {
185 GrFree(fEffectUniLocationsExtended);
186 }
187
188 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000189 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000190 other.fEffectUniLocationsExtended = NULL; // ownership transfer
191 GR_DEBUGCODE(other.fEffectUniCount = 0;)
192 }
193
194 void setEffectUniformCount(size_t effectUniforms) {
195 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
196 GrFree(fEffectUniLocationsExtended);
197 if (effectUniforms > kUniLocationPreAllocSize) {
198 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
199 } else {
200 fEffectUniLocationsExtended = NULL;
201 }
202 }
203
204 GrGLint& effectUniLocation(size_t index) {
205 GrAssert(index < fEffectUniCount);
206 return (index < kUniLocationPreAllocSize) ?
207 fEffectUniLocations[index] :
208 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
209 }
210
211 public:
212
213 // IDs
214 GrGLuint fVShaderID;
215 GrGLuint fFShaderID;
216 GrGLuint fProgramID;
217 // shader uniform locations (-1 if shader doesn't use them)
218 UniLocations fUniLocations;
219
220 GrMatrix fViewMatrix;
221
222 // these reflect the current values of uniforms
223 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000224 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000225 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000226 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000227 // width and height used for normalized texel size
228 int fTextureWidth[GrDrawTarget::kNumStages];
229 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000230 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
231 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
232 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
233
234 private:
235 enum Constants {
236 kUniLocationPreAllocSize = 8
237 };
238
239 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
240 GrGLint* fEffectUniLocationsExtended;
241 GR_DEBUGCODE(size_t fEffectUniCount;)
242 }; // CachedData
243
244 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
245
246private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000247 enum {
248 kUseUniform = 2000
249 };
250
251 // should set all fields in locations var to kUseUniform if the
252 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000253 void genStageCode(int stageNum,
254 const ProgramDesc::StageDesc& desc,
255 const char* fsInColor, // NULL means no incoming color
256 const char* fsOutColor,
257 const char* vsInCoord,
258 ShaderCodeSegments* segments,
259 StageUniLocations* locations) const;
260
bsalomon@google.com91961302011-05-09 18:39:58 +0000261 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
262 CachedData* programData);
263
junov@google.comf93e7172011-03-31 21:26:24 +0000264 // Compiles a GL shader, returns shader ID or 0 if failed
265 // params have same meaning as glShaderSource
266 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
267 const char** strings,
268 int* stringLengths);
269
bsalomon@google.com91961302011-05-09 18:39:58 +0000270 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
271 // links the program
272 bool bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
273 CachedData* programData) const;
274
275 // Gets locations for all uniforms set to kUseUniform and initializes cache
276 // to invalid values.
277 void getUniformLocationsAndInitCache(CachedData* programData) const;
278
junov@google.comf93e7172011-03-31 21:26:24 +0000279 friend class GrGpuGLShaders;
280};
281
282#endif