blob: 4fc1d430cbc1a2d12b3cfd7069241d341253b707 [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"
21
22#define POS_ATTR_LOCATION 0
23#define TEX_ATTR_LOCATION(X) (1 + (X))
24#define COL_ATTR_LOCATION (2 + GrDrawTarget::kMaxTexCoords)
25
26#include "GrDrawTarget.h"
27
28class GrBinHashKeyBuilder;
29class GrGLEffect;
30struct ShaderCodeSegments;
31
32/**
33 * This class manages a GPU program and records per-program information.
34 * We can specify the attribute locations so that they are constant
35 * across our shaders. But the driver determines the uniform locations
36 * at link time. We don't need to remember the sampler uniform location
37 * because we will bind a texture slot to it and never change it
38 * Uniforms are program-local so we can't rely on fHWState to hold the
39 * previous uniform state after a program change.
40 */
41class GrGLProgram {
42public:
43 class CachedData;
44
45 GrGLProgram();
46 ~GrGLProgram();
47
48 /**
49 * Streams data that can uniquely identifies the generated
50 * gpu program into a key, for cache indexing purposes.
51 *
52 * @param key The key object to receive the key data
53 */
54 void buildKey(GrBinHashKeyBuilder& key) const;
55
56 /**
57 * This is the heavy initilization routine for building a GLProgram.
58 * The result of heavy init is not stored in datamembers of GrGLProgam,
59 * but in a separate cacheable container.
60 */
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +000061 void genProgram(CachedData* programData) const;
junov@google.comf93e7172011-03-31 21:26:24 +000062
63 /**
64 * Routine that is called before rendering. Sets-up all the state and
65 * other initializations required for the Gpu Program to run.
66 */
67 bool doGLSetup(GrPrimitiveType type, CachedData* programData) const;
68
69 /**
70 * Routine that is called after rendering. Performs state restoration.
71 * May perform secondary render passes.
72 */
73 void doGLPost() const;
74
75 /**
76 * Configures the GrGLProgram based on the state of a GrDrawTarget
77 * object. This is the fast and light initialization. Retrieves all the
78 * state that is required for performing the heavy init (i.e. genProgram),
79 * or for retrieving heavy init results from cache.
80 */
81 void buildFromTarget(const GrDrawTarget* target);
82
83private:
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
102 bool fEmitsPointSize;
junov@google.comf93e7172011-03-31 21:26:24 +0000103
104 struct StageDesc {
105 enum OptFlagBits {
106 kNoPerspective_OptFlagBit = 0x1,
107 kIdentityMatrix_OptFlagBit = 0x2
108 };
109
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000110 unsigned fOptFlags;
111 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000112
113 enum Modulation {
114 kColor_Modulation,
115 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000116 } fModulation;
117
118 enum FetchMode {
119 kSingle_FetchMode,
120 k2x2_FetchMode
121 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000122
123 enum CoordMapping {
124 kIdentity_CoordMapping,
125 kRadialGradient_CoordMapping,
126 kSweepGradient_CoordMapping,
127 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000128 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000129 } fStages[GrDrawTarget::kNumStages];
130 } fProgramDesc;
131
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000132 const ProgramDesc& getDesc() { return fProgramDesc; }
133
junov@google.comf93e7172011-03-31 21:26:24 +0000134public:
135 struct StageUniLocations {
136 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000137 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000138 GrGLint fSamplerUni;
139 GrGLint fRadial2Uni;
140 };
141
142 struct UniLocations {
143 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000144 GrGLint fColorUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000145 StageUniLocations fStages[GrDrawTarget::kNumStages];
146 };
147
148 class CachedData : public ::GrNoncopyable {
149 public:
150 CachedData() {
151 GR_DEBUGCODE(fEffectUniCount = 0;)
152 fEffectUniLocationsExtended = NULL;
153 }
154
155 ~CachedData() {
156 GrFree(fEffectUniLocationsExtended);
157 }
158
159 void copyAndTakeOwnership(CachedData& other) {
160 memcpy(this, &other, sizeof(this));
161 other.fEffectUniLocationsExtended = NULL; // ownership transfer
162 GR_DEBUGCODE(other.fEffectUniCount = 0;)
163 }
164
165 void setEffectUniformCount(size_t effectUniforms) {
166 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
167 GrFree(fEffectUniLocationsExtended);
168 if (effectUniforms > kUniLocationPreAllocSize) {
169 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
170 } else {
171 fEffectUniLocationsExtended = NULL;
172 }
173 }
174
175 GrGLint& effectUniLocation(size_t index) {
176 GrAssert(index < fEffectUniCount);
177 return (index < kUniLocationPreAllocSize) ?
178 fEffectUniLocations[index] :
179 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
180 }
181
182 public:
183
184 // IDs
185 GrGLuint fVShaderID;
186 GrGLuint fFShaderID;
187 GrGLuint fProgramID;
188 // shader uniform locations (-1 if shader doesn't use them)
189 UniLocations fUniLocations;
190
191 GrMatrix fViewMatrix;
192
193 // these reflect the current values of uniforms
194 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000195 GrColor fColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000196 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000197 // width and height used for normalized texel size
198 int fTextureWidth[GrDrawTarget::kNumStages];
199 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000200 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
201 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
202 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
203
204 private:
205 enum Constants {
206 kUniLocationPreAllocSize = 8
207 };
208
209 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
210 GrGLint* fEffectUniLocationsExtended;
211 GR_DEBUGCODE(size_t fEffectUniCount;)
212 }; // CachedData
213
214 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
215
216private:
217 void genStageCode(int stageNum,
218 const ProgramDesc::StageDesc& desc,
219 const char* fsInColor, // NULL means no incoming color
220 const char* fsOutColor,
221 const char* vsInCoord,
222 ShaderCodeSegments* segments,
223 StageUniLocations* locations) const;
224
225 // Compiles a GL shader, returns shader ID or 0 if failed
226 // params have same meaning as glShaderSource
227 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
228 const char** strings,
229 int* stringLengths);
230
231 friend class GrGpuGLShaders;
232};
233
234#endif