blob: bc740384df08375203ab5b420a88c910552d4ae1 [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 {
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
110 unsigned fOptFlags : 8;
111 unsigned fEnabled : 8;
112
113 enum Modulation {
114 kColor_Modulation,
115 kAlpha_Modulation
116 } fModulation : 8;
117
118 enum CoordMapping {
119 kIdentity_CoordMapping,
120 kRadialGradient_CoordMapping,
121 kSweepGradient_CoordMapping,
122 kRadial2Gradient_CoordMapping
123 } fCoordMapping : 8;
124 } fStages[GrDrawTarget::kNumStages];
125 } fProgramDesc;
126
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000127 const ProgramDesc& getDesc() { return fProgramDesc; }
128
junov@google.comf93e7172011-03-31 21:26:24 +0000129public:
130 struct StageUniLocations {
131 GrGLint fTextureMatrixUni;
132 GrGLint fSamplerUni;
133 GrGLint fRadial2Uni;
134 };
135
136 struct UniLocations {
137 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000138 GrGLint fColorUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000139 StageUniLocations fStages[GrDrawTarget::kNumStages];
140 };
141
142 class CachedData : public ::GrNoncopyable {
143 public:
144 CachedData() {
145 GR_DEBUGCODE(fEffectUniCount = 0;)
146 fEffectUniLocationsExtended = NULL;
147 }
148
149 ~CachedData() {
150 GrFree(fEffectUniLocationsExtended);
151 }
152
153 void copyAndTakeOwnership(CachedData& other) {
154 memcpy(this, &other, sizeof(this));
155 other.fEffectUniLocationsExtended = NULL; // ownership transfer
156 GR_DEBUGCODE(other.fEffectUniCount = 0;)
157 }
158
159 void setEffectUniformCount(size_t effectUniforms) {
160 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
161 GrFree(fEffectUniLocationsExtended);
162 if (effectUniforms > kUniLocationPreAllocSize) {
163 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
164 } else {
165 fEffectUniLocationsExtended = NULL;
166 }
167 }
168
169 GrGLint& effectUniLocation(size_t index) {
170 GrAssert(index < fEffectUniCount);
171 return (index < kUniLocationPreAllocSize) ?
172 fEffectUniLocations[index] :
173 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
174 }
175
176 public:
177
178 // IDs
179 GrGLuint fVShaderID;
180 GrGLuint fFShaderID;
181 GrGLuint fProgramID;
182 // shader uniform locations (-1 if shader doesn't use them)
183 UniLocations fUniLocations;
184
185 GrMatrix fViewMatrix;
186
187 // these reflect the current values of uniforms
188 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000189 GrColor fColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000190 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
191 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
192 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
193 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
194
195 private:
196 enum Constants {
197 kUniLocationPreAllocSize = 8
198 };
199
200 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
201 GrGLint* fEffectUniLocationsExtended;
202 GR_DEBUGCODE(size_t fEffectUniCount;)
203 }; // CachedData
204
205 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
206
207private:
208 void genStageCode(int stageNum,
209 const ProgramDesc::StageDesc& desc,
210 const char* fsInColor, // NULL means no incoming color
211 const char* fsOutColor,
212 const char* vsInCoord,
213 ShaderCodeSegments* segments,
214 StageUniLocations* locations) const;
215
216 // Compiles a GL shader, returns shader ID or 0 if failed
217 // params have same meaning as glShaderSource
218 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
219 const char** strings,
220 int* stringLengths);
221
222 friend class GrGpuGLShaders;
223};
224
225#endif