blob: 1a15953e74df3ced4dde3368011b74739c6beaa5 [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 */
61 void genProgram(CachedData* programData, const GrDrawTarget* target) const;
62
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 {
87 GrVertexLayout fVertexLayout;
88
89 enum {
90 kNotPoints_OptFlagBit = 0x1,
91 kVertexColorAllOnes_OptFlagBit = 0x2,
92 };
93 // we're assuming optflags and layout pack into 32 bits
94 // VS 2010 seems to require short rather than just unsigned
95 // for this to pack
96 unsigned short fOptFlags : 16;
97
98 struct StageDesc {
99 enum OptFlagBits {
100 kNoPerspective_OptFlagBit = 0x1,
101 kIdentityMatrix_OptFlagBit = 0x2
102 };
103
104 unsigned fOptFlags : 8;
105 unsigned fEnabled : 8;
106
107 enum Modulation {
108 kColor_Modulation,
109 kAlpha_Modulation
110 } fModulation : 8;
111
112 enum CoordMapping {
113 kIdentity_CoordMapping,
114 kRadialGradient_CoordMapping,
115 kSweepGradient_CoordMapping,
116 kRadial2Gradient_CoordMapping
117 } fCoordMapping : 8;
118 } fStages[GrDrawTarget::kNumStages];
119 } fProgramDesc;
120
121public:
122 struct StageUniLocations {
123 GrGLint fTextureMatrixUni;
124 GrGLint fSamplerUni;
125 GrGLint fRadial2Uni;
126 };
127
128 struct UniLocations {
129 GrGLint fViewMatrixUni;
130 StageUniLocations fStages[GrDrawTarget::kNumStages];
131 };
132
133 class CachedData : public ::GrNoncopyable {
134 public:
135 CachedData() {
136 GR_DEBUGCODE(fEffectUniCount = 0;)
137 fEffectUniLocationsExtended = NULL;
138 }
139
140 ~CachedData() {
141 GrFree(fEffectUniLocationsExtended);
142 }
143
144 void copyAndTakeOwnership(CachedData& other) {
145 memcpy(this, &other, sizeof(this));
146 other.fEffectUniLocationsExtended = NULL; // ownership transfer
147 GR_DEBUGCODE(other.fEffectUniCount = 0;)
148 }
149
150 void setEffectUniformCount(size_t effectUniforms) {
151 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
152 GrFree(fEffectUniLocationsExtended);
153 if (effectUniforms > kUniLocationPreAllocSize) {
154 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
155 } else {
156 fEffectUniLocationsExtended = NULL;
157 }
158 }
159
160 GrGLint& effectUniLocation(size_t index) {
161 GrAssert(index < fEffectUniCount);
162 return (index < kUniLocationPreAllocSize) ?
163 fEffectUniLocations[index] :
164 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
165 }
166
167 public:
168
169 // IDs
170 GrGLuint fVShaderID;
171 GrGLuint fFShaderID;
172 GrGLuint fProgramID;
173 // shader uniform locations (-1 if shader doesn't use them)
174 UniLocations fUniLocations;
175
176 GrMatrix fViewMatrix;
177
178 // these reflect the current values of uniforms
179 // (GL uniform values travel with program)
180 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
181 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
182 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
183 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
184
185 private:
186 enum Constants {
187 kUniLocationPreAllocSize = 8
188 };
189
190 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
191 GrGLint* fEffectUniLocationsExtended;
192 GR_DEBUGCODE(size_t fEffectUniCount;)
193 }; // CachedData
194
195 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
196
197private:
198 void genStageCode(int stageNum,
199 const ProgramDesc::StageDesc& desc,
200 const char* fsInColor, // NULL means no incoming color
201 const char* fsOutColor,
202 const char* vsInCoord,
203 ShaderCodeSegments* segments,
204 StageUniLocations* locations) const;
205
206 // Compiles a GL shader, returns shader ID or 0 if failed
207 // params have same meaning as glShaderSource
208 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
209 const char** strings,
210 int* stringLengths);
211
212 friend class GrGpuGLShaders;
213};
214
215#endif