blob: 08902387e797676d3c807dac6761ecfca6481a4d [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 SkXfermode::Mode fColorFilterXfermode;
113
junov@google.comf93e7172011-03-31 21:26:24 +0000114 struct StageDesc {
115 enum OptFlagBits {
116 kNoPerspective_OptFlagBit = 0x1,
117 kIdentityMatrix_OptFlagBit = 0x2
118 };
119
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000120 unsigned fOptFlags;
121 bool fEnabled;
junov@google.comf93e7172011-03-31 21:26:24 +0000122
123 enum Modulation {
124 kColor_Modulation,
125 kAlpha_Modulation
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000126 } fModulation;
127
128 enum FetchMode {
129 kSingle_FetchMode,
130 k2x2_FetchMode
131 } fFetchMode;
junov@google.comf93e7172011-03-31 21:26:24 +0000132
133 enum CoordMapping {
134 kIdentity_CoordMapping,
135 kRadialGradient_CoordMapping,
136 kSweepGradient_CoordMapping,
137 kRadial2Gradient_CoordMapping
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000138 } fCoordMapping;
junov@google.comf93e7172011-03-31 21:26:24 +0000139 } fStages[GrDrawTarget::kNumStages];
140 } fProgramDesc;
141
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000142 const ProgramDesc& getDesc() { return fProgramDesc; }
143
junov@google.comf93e7172011-03-31 21:26:24 +0000144public:
bsalomon@google.com91961302011-05-09 18:39:58 +0000145 enum {
146 kUnusedUniform = -1,
147 kSetAsAttribute = 1000,
148 };
149
junov@google.comf93e7172011-03-31 21:26:24 +0000150 struct StageUniLocations {
151 GrGLint fTextureMatrixUni;
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000152 GrGLint fNormalizedTexelSizeUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000153 GrGLint fSamplerUni;
154 GrGLint fRadial2Uni;
bsalomon@google.com91961302011-05-09 18:39:58 +0000155 void reset() {
156 fTextureMatrixUni = kUnusedUniform;
157 fNormalizedTexelSizeUni = kUnusedUniform;
158 fSamplerUni = kUnusedUniform;
159 fRadial2Uni = kUnusedUniform;
160 }
junov@google.comf93e7172011-03-31 21:26:24 +0000161 };
162
163 struct UniLocations {
164 GrGLint fViewMatrixUni;
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000165 GrGLint fColorUni;
Scroggo97c88c22011-05-11 14:05:25 +0000166 GrGLint fColorFilterUni;
junov@google.comf93e7172011-03-31 21:26:24 +0000167 StageUniLocations fStages[GrDrawTarget::kNumStages];
bsalomon@google.com91961302011-05-09 18:39:58 +0000168 void reset() {
169 fViewMatrixUni = kUnusedUniform;
170 fColorUni = kUnusedUniform;
Scroggo97c88c22011-05-11 14:05:25 +0000171 fColorFilterUni = kUnusedUniform;
bsalomon@google.com91961302011-05-09 18:39:58 +0000172 for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
173 fStages[s].reset();
174 }
175 }
junov@google.comf93e7172011-03-31 21:26:24 +0000176 };
177
178 class CachedData : public ::GrNoncopyable {
179 public:
180 CachedData() {
181 GR_DEBUGCODE(fEffectUniCount = 0;)
182 fEffectUniLocationsExtended = NULL;
183 }
184
185 ~CachedData() {
186 GrFree(fEffectUniLocationsExtended);
187 }
188
189 void copyAndTakeOwnership(CachedData& other) {
bsalomon@google.com2d9ddf92011-05-11 16:52:59 +0000190 memcpy(this, &other, sizeof(*this));
junov@google.comf93e7172011-03-31 21:26:24 +0000191 other.fEffectUniLocationsExtended = NULL; // ownership transfer
192 GR_DEBUGCODE(other.fEffectUniCount = 0;)
193 }
194
195 void setEffectUniformCount(size_t effectUniforms) {
196 GR_DEBUGCODE(fEffectUniCount = effectUniforms;)
197 GrFree(fEffectUniLocationsExtended);
198 if (effectUniforms > kUniLocationPreAllocSize) {
199 fEffectUniLocationsExtended = (GrGLint*)GrMalloc(sizeof(GrGLint)*(effectUniforms-kUniLocationPreAllocSize));
200 } else {
201 fEffectUniLocationsExtended = NULL;
202 }
203 }
204
205 GrGLint& effectUniLocation(size_t index) {
206 GrAssert(index < fEffectUniCount);
207 return (index < kUniLocationPreAllocSize) ?
208 fEffectUniLocations[index] :
209 fEffectUniLocationsExtended[index - kUniLocationPreAllocSize];
210 }
211
212 public:
213
214 // IDs
215 GrGLuint fVShaderID;
216 GrGLuint fFShaderID;
217 GrGLuint fProgramID;
218 // shader uniform locations (-1 if shader doesn't use them)
219 UniLocations fUniLocations;
220
221 GrMatrix fViewMatrix;
222
223 // these reflect the current values of uniforms
224 // (GL uniform values travel with program)
bsalomon@google.com4be283f2011-04-19 21:15:09 +0000225 GrColor fColor;
Scroggo97c88c22011-05-11 14:05:25 +0000226 GrColor fColorFilterColor;
junov@google.comf93e7172011-03-31 21:26:24 +0000227 GrMatrix fTextureMatrices[GrDrawTarget::kNumStages];
bsalomon@google.com6aef1fb2011-05-05 12:33:22 +0000228 // width and height used for normalized texel size
229 int fTextureWidth[GrDrawTarget::kNumStages];
230 int fTextureHeight[GrDrawTarget::kNumStages];
junov@google.comf93e7172011-03-31 21:26:24 +0000231 GrScalar fRadial2CenterX1[GrDrawTarget::kNumStages];
232 GrScalar fRadial2Radius0[GrDrawTarget::kNumStages];
233 bool fRadial2PosRoot[GrDrawTarget::kNumStages];
234
235 private:
236 enum Constants {
237 kUniLocationPreAllocSize = 8
238 };
239
240 GrGLint fEffectUniLocations[kUniLocationPreAllocSize];
241 GrGLint* fEffectUniLocationsExtended;
242 GR_DEBUGCODE(size_t fEffectUniCount;)
243 }; // CachedData
244
245 GrGLEffect* fStageEffects[GrDrawTarget::kNumStages];
246
247private:
bsalomon@google.com91961302011-05-09 18:39:58 +0000248 enum {
249 kUseUniform = 2000
250 };
251
252 // should set all fields in locations var to kUseUniform if the
253 // corresponding uniform is required for the program.
junov@google.comf93e7172011-03-31 21:26:24 +0000254 void genStageCode(int stageNum,
255 const ProgramDesc::StageDesc& desc,
256 const char* fsInColor, // NULL means no incoming color
257 const char* fsOutColor,
258 const char* vsInCoord,
259 ShaderCodeSegments* segments,
260 StageUniLocations* locations) const;
261
bsalomon@google.com91961302011-05-09 18:39:58 +0000262 static bool CompileFSAndVS(const ShaderCodeSegments& segments,
263 CachedData* programData);
264
junov@google.comf93e7172011-03-31 21:26:24 +0000265 // Compiles a GL shader, returns shader ID or 0 if failed
266 // params have same meaning as glShaderSource
267 static GrGLuint CompileShader(GrGLenum type, int stringCnt,
268 const char** strings,
269 int* stringLengths);
270
bsalomon@google.com91961302011-05-09 18:39:58 +0000271 // Creates a GL program ID, binds shader attributes to GL vertex attrs, and
272 // links the program
273 bool bindAttribsAndLinkProgram(GrStringBuilder texCoordAttrNames[GrDrawTarget::kMaxTexCoords],
274 CachedData* programData) const;
275
276 // Gets locations for all uniforms set to kUseUniform and initializes cache
277 // to invalid values.
278 void getUniformLocationsAndInitCache(CachedData* programData) const;
279
junov@google.comf93e7172011-03-31 21:26:24 +0000280 friend class GrGpuGLShaders;
281};
282
283#endif